Як я можу перевірити, чи PHP було складено з версією UNICODE API Win32?


10

Це пов’язано з цією публікацією переповнення стека:

glob () не може знайти імена файлів з багатобайтовими символами в Windows?

У мене проблеми з PHP та файлами, які мають багатобайтові символи в Windows. Ось мій тестовий випадок:

print_r(scandir('./uploads/')); 
print_r(glob('./uploads/*'));

Правильний вихід на віддалений сервер UNIX:

Array
(
    [0] => .
    [1] => ..
    [2] => filename-äöü.jpg
    [3] => filename.jpg
    [4] => test이test.jpg
    [5] => имя файла.jpg
    [6] => פילענאַמע.jpg
    [7] => 文件名.jpg
)
Array
(
    [0] => ./uploads/filename-äöü.jpg
    [1] => ./uploads/filename.jpg
    [2] => ./uploads/test이test.jpg
    [3] => ./uploads/имя файла.jpg
    [4] => ./uploads/פילענאַמע.jpg
    [5] => ./uploads/文件名.jpg
)

Неправильний вихід локально в Windows:

Array
(
    [0] => .
    [1] => ..
    [2] => ??? ?????.jpg
    [3] => ???.jpg
    [4] => ?????????.jpg
    [5] => filename-äöü.jpg
    [6] => filename.jpg
    [7] => test?test.jpg
)
Array
(
    [0] => ./uploads/filename-äöü.jpg
    [1] => ./uploads/filename.jpg
)

Ось відповідний уривок з відповіді, яку я вирішив прийняти (що насправді є цитатою зі статті, яка була розміщена в Інтернеті понад 2 роки тому):

З коментарів до цієї статті: http://www.rooftopsolutions.nl/blog/filesystem-encoding-and-php

Вихід з інсталяції PHP в Windows легко пояснити: ви встановили неправильну версію PHP і використовували версію, не скомпільовану для використання версії Unicode API Win32. З цієї причини виклики файлової системи, використовувані PHP, використовуватимуть застарілий API "ANSI", і тому бібліотеки C / C ++, пов'язані з цією версією PHP, спершу спробують перетворити юту PHP-кодовану PHP-рядок у локальну "ANSI" кодова сторінка, вибрана в середовищі запуску (див. команду CHCP перед запуском PHP у вікні командного рядка)

Ваша версія Windows НАЙБІЛЬШЕ ВІДПОВІДНО НЕ відповідає за цю дивну річ. Насправді, це ВАША версія PHP, яка не скомпільована належним чином і яка використовує застарілу версію ANSI API Win32 (для сумісності із застарілими 16-бітовими версіями Windows 95/98, підтримка яких у ядрі фактично не мала прямої версії) підтримка Unicode, але використовувався внутрішній шар перетворення для перетворення Unicode на локальну кодову сторінку ANSI перед тим, як використовувати фактичну версію API ANSI).

Перекомпілюйте PHP, використовуючи параметр компілятора, щоб використовувати версію UNICODE API Win32 (яка повинна бути за замовчуванням сьогодні, і все одно завжди типовою для PHP, встановленої на сервері, який НІКОЛИ не буде Windows 95 або Windows 98 ...)

Я не можу підтвердити, це моя проблема чи ні. Я використовував phpinfo()і нічого цікавого не знаходив, але не знав, що шукати. Я використовував XAMPP для легких установок, тому я дійсно не впевнений, як саме він був встановлений.

Я використовую Windows 7, 64 біт - тож пробачте моє незнання, але я навіть не впевнений, чи доречний тут "Win32". Як я можу перевірити, чи була складена моя поточна версія PHP із згаданою вище конфігурацією?

  • Версія PHP : 5.3.8
  • Система : Windows NT WES-PC 6.1 build 7601 (Windows 7 Home Premium Edition Service Pack 1) i586
  • Дата складання: 23 серпня 2011 11:47:20
  • Укладач : MSVC9 (Visual C ++ 2008)
  • Архітектура : x86
  • Налаштування команди : cscript /nologo configure.js "--enable-snapshot-build" "--disable-isapi" "--enable-debug-pack" "--disable-isapi" "--without-mssql" "--without-pdo-mssql" "--without-pi3web" "--with-pdo-oci=D:\php-sdk\oracle\instantclient10\sdk,shared" "--with-oci8=D:\php-sdk\oracle\instantclient10\sdk,shared" "--with-oci8-11g=D:\php-sdk\oracle\instantclient11\sdk,shared" "--enable-object-out-dir=../obj/" "--enable-com-dotnet" "--with-mcrypt=static" "--disable-static-analyze"

Якщо це доречно або виявляє корисну інформацію, ось знімок екрана мого phpinfo()(mbstring section):

phpinfo знімок екрана

Як я можу дізнатися, чи була моя інсталяція PHP "зібрана з версією UNICODE API Win32"? (і чи це насправді має сенс?)


5
Захищений тому, що Весліс повинен стежити за іншим.
Веслі

Ви зробили щось у своєму сценарії щодо кодування? З моєю установкою win7-64 у мене була протилежність цієї проблеми! Php прочитав би умлатів та всього того, що та насріла програма, з якої я спілкувався з перервами, коли це отримує.
Кріс К

Вибачте, що я порушив це питання, я просто не отримав швидкої та брудної робочої відповіді, на яку я сподівався, і врешті-решт припинив розробку цього проекту в Windows. Я незабаром встановлю PHP 5.4 локально (на windows), тому питання може більше не бути для мене цінним, якщо хтось хоче запропонувати прийняту відповідь, я всі вуха. Тим часом, заявки та подяки всім навколо.
Веслі Мерч

Відповіді:


3

Я думаю, вам слід завантажити офіційний бінарний файл із сховища PHP Windows і встановити його (врахуйте шлях встановлення).

Після цього вам потрібно буде налаштувати apache для використання нового бінарного файла замість того, який він переносить за замовчуванням. Це просто:

  • Знайдіть свій httpd.confфайл у папці WAMP (щось на зразок C: \ wamp \ bin \ apache \ ApacheXXX \ conf \ httpd.conf) - можливо, також можна пройти через trayicon.

  • Ок, тепер, коли ви виявили, знайдіть відповідність рядків LoadModule php5_module

  • Добре, просто замініть цей рядок новим, php5_moduleякий заборонено на c: /php/php5apache2_2.dll (ви зберегли шлях встановлення!). У результаті чогось подібногоLoadModule php5_module "c:/php/php5apache2_2.dll"

Вуаля. Скиньте сервер wamp і протестуйте свою програму за допомогою останньої версії побудови php спеціально для Windows.

Я не впевнений, що це вирішить вашу проблему, але, безумовно, це справжній шлях. Якщо у вас є проблеми з налаштуванням php, прочитайте цю статтю .

Удачі!


2

Схоже, що це питання вже деякий час існує, і не було, чи php було зібрано з прапорцями unicode, не впливає на його підтримку unicode, але якщо вам потрібно визначити, чи певне зображення ПЕ, ймовірно, було складено проти версії Unicode API API, який ви можете використовувати dumpbinдля вивчення імпорту kernel32.dll, який використовується. Це не зовсім те, що я б робив прагматично, але, в міру, міг би працювати для діагностики.

Наприклад, виконуваний файл Unicode може перелічити:

               4C CreateFileMappingW
               45 CreateDirectoryW
               33 CompareStringW
              12E GetCurrentDirectoryW
               AF ExpandEnvironmentStringsW
              2F0 SetFileAttributesW

відзначивши кількість функцій, що закінчуються на W, він же Широкий для символів unicode.

Для виконуваного файлу ANSI або DLL ви можете побачити щось ближче до:

              30A SetCurrentDirectoryA
              15E GetFileAttributesA
              171 GetLastError
               4B CreateDirectoryA
              319 SetFileAttributesA

з більшістю функцій, що закінчуються на A, ми можемо бачити, що виконуваний файл, швидше за все, був складений прапорами ANSI.


2

Ось код, над яким я працював, щоб вирішити mbstringпроблему, з якою я стикався. Я закінчував ітерацію через кожну комбінацію кодувань та параметрів, поки одна з них не представила потрібний мені вихід. У мене є відчуття, що ця процедура може допомогти вам знайти відповідь, яку ви шукаєте.

Не покладайтеся на документацію , так як у моєму випадку результати були не такими, як я вважав, що будуть робити варіанти та кодування. Я пригадую, що під час тестування я отримав би прямокутники,? S та такі речі, як A ~. Моє тестування було точно таким, як ваше, print_rінформація. У моєму випадку мій сценарій імпортує інформацію про клієнтів та продажі у Quickbooks, які не можуть працювати з UTF-8. (Або сам QB не може, або драйвер QODBC не може) Тильди, могили та мулати не підлягають сумніву.

setlocale(LC_CTYPE, 'en_US.UTF-8');
$xmlstr=file_get_contents($file);           
// convert character encoding to get rid of accents, etc
// see http://www.php.net/manual/en/function.mb-detect-encoding.php#89915
// note that unlike ASCII//TRANSLIT and ASCII//TRANSLIT//IGNORE do not work
// in windows 7.
$xmlstr=iconv('UTF-8', 'ASCII//IGNORE', $xmlstr);   

Це посилання вище http://www.php.net/manual/en/function.mb-detect-encoding.php#89915, і якщо Google знайде вас тут, обов'язково прочитайте це.


1

Я вважаю, що ви захочете перевірити, чи PHP був складений з mbstring (чи встановлений і включений модуль mbstring, якщо ви використовуєте модулі). Увімкнення цього розширення повинно вирішити ваші проблеми. На цій сторінці ви повинні розповісти все, що потрібно знати, щоб працювати.


Дякую за пропозицію, але я вважаю, що mbstring встановлений правильно. До кінця свого допису я додав трохи інформації щодо цього. Мені більше цікаво дізнатися про коментарі, які я цитував із статті "ВАША версія PHP, яка не скомпільована належним чином і в якій використовується застаріла версія ANSI API Win32" , як дізнатися, чи це так, і має значення це чи ні.
Веслі Мерч

Я не думаю, що підтримка Unicode в PHP має багато спільного з підтримкою Unicode в API, яку PHP використовує для своєї справи. Я підозрюю, що останнє - це питання, а не перше. (Вибачте, що у мене немає відповіді на проблему; мені огидно, наскільки жахливо PHP після спроб здорових мов, тому я не маю стільки досвіду з цим).
геп
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.