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


10

这与此堆栈溢出帖子有关:

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
)

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

从对本文的评论中: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版本,未正确编译,并且使用的是Win32 API的旧版ANSI版本(与Windows 95/98的旧版16位版本兼容,而Windows 95/98的内核中的文件系统支持实际上没有直接的支持。支持Unicode,但在使用API​​的实际ANSI版本之前,使用了内部转换层将Unicode转换为本地ANSI代码页。

使用编译器选项重新编译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内部版本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版本一起编译”?(这实际上有意义吗?)


5
由于韦斯利夫妇必须彼此提防,因此表示支持。
韦斯利

您是否在脚本中完成了编码方面的任何工作?我的win7-64安装与这个问题相反!Php会读取umlats以及所有与我交流的废话遗留程序,直到它们得到休息。
克里斯K

对这个问题感到抱歉,我只是没有得到我所希望的快速而肮脏的工作答案,并最终停止在Windows上开发该项目。我将很快在本地(在Windows上)安装PHP 5.4,因此,如果有人想提出一个可以接受的答案,那么这个问题对我来说可能不再有价值。在此期间,大家都表示赞赏和感谢。
Wesley Murch

Answers:


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服务器,并使用专门用于Windows的最新版本的php构建测试您的应用程序。

我不确定这是否可以解决您的问题,但确实是一种切实可行的方法。如果您对php设置有疑问,请阅读此文章

祝好运!


2

似乎这个问题已经存在了一段时间,并且是否用unicode标志编译了php并不影响它对unicode的支持,但是如果您需要确定给定的PE映像是否可能是针对Unicode版本的, Windows API,可以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标志进行编译的。


2

这是mbstring我正在处理的一些代码,用于解决遇到的问题。我最终遍历了编码和选项的每种组合,直到其中之一提供了我所需的输出。我感觉这种程序可以帮助您找到所需的答案。

不要依赖文档,就我而言,结果不是我认为的选项和编码所能实现的。我记得在测试中,我会得到矩形,?s和诸如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在这里找到您,请务必阅读。


1

我相信您会希望检查PHP是否使用mbstring编译(或者如果使用模块,则已安装并启用了mbstring模块)。启用该扩展程序应该可以解决您的问题。该页面应告诉您一切正常运行所需的知识。


感谢您的建议,但我相信mbstring安装正确。我在文章末尾添加了一些与此有关的信息。我对从文章“您的PHP版本未正确编译,并且使用Win32 API的旧版ANSI版本”中引用的注释更感兴趣,如何查找是否是这种情况,以及是否相关。
韦斯利·默奇

我认为PHP中的unicode支持与PHP用于开展业务的API中的unicode支持无关。我怀疑后者是问题,而不是前者。(很抱歉,我没有解决这个问题的方法;尝试使用理智的语言后,PHP多么糟糕,令我感到恶心,我对此没有太多经验)。
gparent,2012年
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.