如何检查 PHP 是否使用 Win32 API 的 UNICODE 版本进行编译?

如何检查 PHP 是否使用 Win32 API 的 UNICODE 版本进行编译?

这与 Stack Overflow 上的这个帖子相关:

glob() 在 Windows 上无法找到包含多字节字符的文件名?

我在 Windows 上使用 PHP 和包含多字节字符的文件时遇到了问题。这是我的测试用例:

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
)

这是我选择接受的答案的相关摘录(实际上是引用两年前在线发布的一篇文章):

来自这篇文章的评论:http://www.rooftopsolutions.nl/blog/filesystem-encoding-and-php

在 Windows 上安装 PHP 时的输出很容易解释:您安装了错误版本的 PHP,并且使用了未编译为使用 Win32 API 的 Unicode 版本的版本。因此,PHP 使用的文件系统调用将使用旧版“ANSI”API,因此与此版本 PHP 链接的 C/C++ 库将首先尝试将 UTF-8 编码的 PHP 字符串转换为运行环境中选择的本地“ANSI”代码页(在从命令行窗口启动 PHP 之前,请参阅 CHCP 命令)

您的 Windows 版本很可能不对这个奇怪的事情负责。实际上,这是您的 PHP 版本未正确编译,并且使用了旧版 ANSI 版本的 Win32 API(为了与旧版 16 位版本的 Windows 95/98 兼容,其内核中的文件系统支持实际上不直接支持 Unicode,而是使用内部转换层将 Unicode 转换为本地 ANSI 代码页,然后再使用实际的 ANSI 版本的 API)。

使用编译器选项重新编译 PHP 以使用 Win32 API 的 UNICODE 版本(这应该是今天的默认设置,并且无论如何始终是安装在永远不会是 Windows 95 或 Windows 98 的服务器上的 PHP 的默认设置...)

我无法确认这是否是我的问题。我用过phpinfo(),没有发现任何有趣的东西,但我不确定要寻找什么。我一直在使用微软XAMPP为了方便安装,所以我真的不确定它是如何安装的。

我使用的是 Windows 7,64 位 - 请原谅我的无知,但我甚至不确定“Win32”是否与此相关。如何检查我当前的 PHP 版本是否使用上述配置进行编译?

  • PHP 版本:5.3.8
  • 系统:Windows NT WES-PC 6.1 build 7601(Windows 7 家庭高级版 Service Pack 1)i586
  • 建造日期:2011年8月23日 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 部分)的屏幕截图:

phpinfo 屏幕截图

如何才能知道我的 PHP 安装是否“使用 Win32 API 的 UNICODE 版本进行编译”?(这真的有意义吗?)

答案1

我认为你应该从下载官方二进制文件PHP Windows 存储库并安装它(记下安装路径)。

之后,您将需要配置 apache 以使用新的二进制文件而不是其默认携带的二进制文件。很简单:

  • 在 WAMP 文件夹中找到您的httpd.conf文件(例如 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 服务器并使用专为 Windows 构建的最新版本的 php 测试您的应用程序。

我不确定这是否能解决你的问题,但确实是一个可行的方法。如果你在 php 设置方面遇到问题,请阅读此文章

祝你好运!

答案2

这个问题似乎已经存在了一段时间,php 是否使用 unicode 标志进行编译并不影响其对 unicode 的支持,但如果您需要确定给定的 PE 映像是否可能针对 Windows API 的 Unicode 版本进行编译,您可以使用它来dumpbin检查所使用的 kernel32.dll 导入。这不是我务实的做法,但在紧急情况下,可以用于诊断。

例如,Unicode 可执行文件可以列出:

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

注意以 W 结尾的函数数量,又称为 Unicode 字符的 Wide。

对于 ANSI 可执行文件或 DLL,您可能会看到更接近以下内容:

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

由于大多数函数以 A 结尾,我们可以看出可执行文件很可能是使用 ANSI 标志进行编译的。

答案3

这是我为解决mbstring遇到的问题而编写的一些代码。我最终遍历了所有编码和选项的组合,直到其中一个组合提供了我需要的输出。我觉得这种程序可能会帮助你找到你想要的答案。

不要依赖文档,就我的情况而言,结果并不是我所认为的选项和编码。我记得在我的测​​试中,我会得到矩形、?和 A~ 之类的东西。我的测试和你的完全一样,print_r信息。就我的情况而言,我的脚本正在将客户和销售信息导入 Quickbooks,而 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 在这里找到你,一定要去阅读。

答案4

我相信你会想检查一下 PHP 是否是用字符串(或者,如果您使用模块,请安装并启用 mbstring 模块)。启用该扩展应该可以解决您的问题。这一页应该告诉您使其工作所需的一切信息。

相关内容