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 o PHP e arquivos com caracteres multibyte 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
)

Saída incorreta 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 publicado on-line há mais de 2 anos):

Dos comentários neste artigo: http://www.rooftopsolutions.nl/blog/filesystem-encoding-and-php

A saída da instalação do PHP no Windows é fácil de explicar: você instalou a versão errada do PHP e usou uma versão não compilada para usar a versão Unicode da API do Win32. Por esse motivo, as chamadas do sistema de arquivos usadas pelo PHP usarão a API "ANSI" herdada e, portanto, as bibliotecas C / C ++ vinculadas a esta versão do PHP tentarão primeiro converter sua string PHP codificada em UTF-8 na "ANSI" local. página de código selecionada no ambiente em execução (consulte o comando CHCP antes de iniciar o PHP a partir de uma janela da linha de comandos)

A sua versão do Windows NÃO É MAIS PROVÁVEL responsável por essa coisa estranha. Na verdade, esta é a sua versão do PHP que não foi compilada corretamente e que usa a versão ANSI herdada da API do Win32 (para compatibilidade com as versões herdadas de 16 bits do Windows 95/98 cujo suporte ao sistema de arquivos no kernel na verdade não tinha nenhuma conexão direta). suporte para Unicode, mas usou uma camada de conversão interna para converter Unicode para a página de código ANSI local antes de usar a versão ANSI real da API).

Recompile o PHP usando a opção de compilador para usar a versão UNICODE da API do Win32 (que deve ser o padrão hoje e sempre o padrão do PHP instalado em um servidor que NUNCA será o Windows 95 ou Windows 98 ...)

Não posso confirmar se esse é o meu problema ou não. Usei phpinfo()e não achei nada interessante, mas não sabia ao certo o que procurar. Eu tenho usado o XAMPP para instalações fáceis, por isso não tenho certeza exatamente como ele foi instalado.

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

  • Versão do PHP : 5.3.8
  • Sistema : Windows NT WES-PC 6.1 build 7601 (Windows 7 Home Premium Edition Service Pack 1) i586
  • Data da construção : 23 de agosto de 2011 11:47:20
  • Compilador : MSVC9 (Visual C ++ 2008)
  • Arquitetura : x86
  • Comando Configure : 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 qualquer informação útil, aqui está uma captura de tela do meu phpinfo()(seção mbstring):

captura de tela do phpinfo

Como posso descobrir se minha instalação do PHP foi "compilada com a versão UNICODE da API do Win32"? (e isso realmente faz algum sentido?)

Wesley Murch
fonte
5
Votado porque Wesleys tem que tomar cuidado um com o outro.
31412 Wesley
Você já fez alguma coisa no seu script em relação à codificação? Eu tive o oposto desse problema com minha instalação do win7-64! O Php leria os umlats, tudo isso e o programa de merda que eu estava comunicando com intervalos quando os recebia.
Chris K
Desculpe por me livrar dessa questão, mas não recebi a resposta rápida e suja de trabalho que esperava, e finalmente parei de desenvolver esse projeto no Windows. Em breve instalarei o PHP 5.4 localmente (no Windows), para que a pergunta não seja mais valiosa para mim, se alguém quiser sugerir uma resposta aceita, sou todo ouvidos. Enquanto isso, votos positivos e agradecimentos ao redor.
Wesley Murch

Respostas:

3

Eu acho que você deve baixar um binário oficial do repositório PHP Windows e instalá-lo (observe o caminho da instalação).

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

  • Encontre seu httpd.confarquivo na pasta WAMP (algo como C: \ wamp \ bin \ apache \ ApacheXXX \ conf \ httpd.conf) - também pode ser possível acessar o trayicon.

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

  • Bom, basta substituir esta linha pela nova, php5_moduleprovavelmente em c: /php/php5apache2_2.dll (você salvou o caminho da instalação!). Resultando em algo comoLoadModule php5_module "c:/php/php5apache2_2.dll"

Voila. Redefina o servidor wamp e teste seu aplicativo com a versão mais recente do php build, especialmente para Windows.

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

Boa sorte!

Thiago Macedo
fonte
2

Parece que essa pergunta existe há algum tempo e se o php foi compilado ou não com sinalizadores unicode não afeta seu suporte a unicode, mas se você precisar determinar se uma determinada imagem do PE provavelmente foi compilada na versão Unicode do API do Windows, você pode usar dumpbinpara examinar as importações do kernel32.dll usadas. Isso não é exatamente algo que eu faria de forma pragmática, mas em uma pitada, poderia funcionar para diagnósticos.

Por exemplo, um executável Unicode pode listar:

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

observando o número de funções que terminam em W, também conhecido 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 terminadas em A, podemos ver que o executável provavelmente foi compilado com sinalizadores ANSI.

Mitch
fonte
2

Aqui está um código no qual trabalhei para lidar com um mbstringproblema que estava ocorrendo. Acabei iterando por todas as combinações de codificações e opções até que uma delas apresentasse a saída que eu precisava. Acho que esse tipo de procedimento pode ajudá-lo a encontrar a resposta que está procurando.

Não confie na documentação , pois no meu caso, os resultados não eram o que eu pensava que as opções e codificações fariam. Lembro-me que em meus testes, eu pegava retângulos,? S, e coisas como A ~. Meu teste foi exatamente como o seu, print_ra informação. No meu caso, meu script está importando informações de clientes e vendas para o Quickbooks, que não pode manipular UTF-8. (O QB em si 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 é http://www.php.net/manual/en/function.mb-detect-encoding.php#89915 e, se o Google encontrar você aqui, definitivamente leia isso.

Chris K
fonte
1

Acredito que você deseje verificar se o PHP foi compilado com o mbstring (ou se o módulo mbstring está instalado e ativado se você estiver usando módulos). A ativação dessa extensão deve resolver seus problemas. Esta página deve informar tudo o que você precisa saber para fazê-lo funcionar.

Aaron
fonte
Obrigado pela sugestão, mas acredito que o mbstring está instalado corretamente. Adicionei algumas informações sobre isso ao final do meu post. Estou mais interessado em aprender sobre os comentários que citei no artigo "SUA versão do PHP, que não foi compilada corretamente e que usa a versão ANSI herdada da API do Win32" , como descobrir se esse é o caso e se isso é relevante ou não.
Wesley Murch
Eu não acho que o suporte a Unicode no PHP tenha muito a ver com o suporte a Unicode na API que o PHP usa para fazer seus negócios. Eu suspeito que o último é a questão e não o primeiro. (Desculpe, porém, não tenho uma resposta para o problema; estou enojado com o quão terrível é o PHP depois de experimentar linguagens sãs, de modo que não tenho tanta experiência com ele).
Gparent