Como posso verificar se o PHP foi compilado com a versão UNICODE da API do Win32?

10

Isso está relacionado a esta postagem do Stack Overflow:

glob () não consegue encontrar nomes de arquivos com caracteres multibyte no Windows?

Estou tendo problemas com PHP e arquivos que possuem caracteres de vários bytes no Windows. Aqui está o meu caso de teste:

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

Saída correta no servidor UNIX remoto:

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
)

Incorreto Saída localmente no 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
)

Aqui está um trecho relevante da resposta que escolhi aceitar (que na verdade é uma citação de um artigo que foi postado on-line há mais de dois anos):

Dos comentários sobre este artigo: link

The output from your PHP installation on Windows is easy to explain : you installed the wrong version of PHP, and used a version not compiled to use the Unicode version of the Win32 API. For this reason, the filesystem calls used by PHP will use the legacy "ANSI" API and so the C/C++ libraries linked with this version of PHP will first try to convert yout UTF-8-encoded PHP string into the local "ANSI" codepage selected in the running environment (see the CHCP command before starting PHP from a command line window)

Your version of Windows is MOST PROBABLY NOT responsible of this weird thing. Actually, this is YOUR version of PHP which is not compiled correctly, and that uses the legacy ANSI version of the Win32 API (for compatibility with the legacy 16-bit versions of Windows 95/98 whose filesystem support in the kernel actually had no direct support for Unicode, but used an internal conversion layer to convert Unicode to the local ANSI codepage before using the actual ANSI version of the API).

Recompile PHP using the compiler option to use the UNICODE version of the Win32 API (which should be the default today, and anyway always the default for PHP installed on a server that will NEVER be Windows 95 or Windows 98...)

Não posso confirmar se isso é problema meu ou não. Eu usei phpinfo() e não achei nada interessante, mas não sabia ao certo o que procurar. Eu tenho usado o XAMPP para facilitar as instalações, então não sei exatamente como ele foi instalado.

Estou usando o Windows 7, de 64 bits - por isso, perdoe minha ignorância, mas não tenho certeza se "Win32" é relevante aqui. Como posso verificar se a minha versão atual do PHP foi compilada com a configuração mencionada acima?

  • PHP Version: 5.3.8
  • System: Windows NT WES-PC 6.1 build 7601 (Windows 7 Home Premium Edition Service Pack 1) i586
  • Build Date: Aug 23 2011 11:47:20
  • Compiler: MSVC9 (Visual C++ 2008)
  • Architecture: x86
  • Configure Command: 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"

Caso seja relevante ou revele alguma informação útil, aqui está uma captura de tela da minha phpinfo() (seção mbstring):

ComopossodescobrirseaminhainstalaçãodoPHPfoi"compilada com a versão UNICODE da API do Win32"? (e isso realmente faz algum sentido?)

    
por Wesley Murch 30.03.2012 / 22:23

4 respostas

3

Eu acho que você deve baixar um binário oficial do repositório do PHP e instalar (anote o caminho da instalação).

Depois disso, você precisará configurar o apache para usar o novo binário em vez daquele que ele carrega por padrão. É simples:

  • Encontre o arquivo httpd.conf na pasta WAMP (algo como C: \ wamp \ bin \ apache \ ApacheXXX \ conf \ httpd.conf) - também é possível passar pelo trayicon.

  • Ok, agora que você encontrou uma string correspondente a LoadModule php5_module

  • Bom, apenas substitua esta linha pelo seu novo php5_module , que provavelmente está em c: /php/php5apache2_2.dll (você salvou o caminho da instalação!). Resultando em algo como LoadModule php5_module "c:/php/php5apache2_2.dll"

Voila. Reinicie o servidor wamp e teste sua aplicação com a última versão do php build especialmente para windows.

Não sei se isso resolverá seu problema, mas certamente é um caminho real a ser seguido. Se você tiver problemas na configuração do php, leia este artigo .

Boa sorte!

    
por 20.07.2012 / 08:49
2

Parece que esta questão já existe há algum tempo e se o php foi ou não compilado com unicode flags não afeta seu suporte a unicode, mas se você precisa determinar se uma dada imagem de PE provavelmente foi compilada contra o Unicode versão da API do Windows, você pode usar dumpbin para examinar as importações kernel32.dll usadas. Isso não é exatamente algo que eu faria de forma pragmática, mas em um piscar de olhos, poderia funcionar para diagnósticos.

Por exemplo, um executável Unicode poderia listar:

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

anotando o número de funções terminadas em W, também conhecidas como Wide, para caracteres unicode.

Para um executável ANSI ou DLL, você pode ver algo mais próximo de:

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

com a maioria das funções terminando em A, podemos ver que o executável provavelmente foi compilado com sinalizadores ANSI.

    
por 08.08.2012 / 06:24
2

Aqui estão alguns códigos em que trabalhei para lidar com um problema mbstring em que eu estava correndo. Acabei fazendo iterações em todas as combinações de codificações e opções até que uma delas apresentava a saída de que eu precisava. Tenho a sensação de que esse tipo de procedimento pode ajudá-lo a encontrar a resposta que você está procurando.

Não confie na documentação , como no meu caso, os resultados não foram o que eu pensei que as opções e codificações fariam. Eu me lembro em meus testes, eu pegava os retângulos, e coisas como A ~. Meu teste foi exatamente como o seu, print_r da informação. No meu caso, meu script está importando informações de clientes e vendas para o Quickbooks, que não pode manipular o UTF-8. (O próprio QB não pode ou o driver QODBC não pode) Tildes, sepulturas e umlats estão fora de questão.

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);   

Esse link acima é link e se o Google encontrá-lo aqui , definitivamente leia isso.

    
por 14.06.2012 / 01:59
1

Eu acredito que você queira verificar se o PHP foi compilado com mbstring (ou o módulo mbstring instalado e ativado se você estiver usando módulos). Ter essa extensão ativada deve resolver seus problemas. Esta página deve dizer tudo o que você precisa saber para que funcione.

    
por 01.05.2012 / 18:06