这与这个堆栈溢出post有关:
glob()在Windows上无法find具有多字节字符的文件名?
我遇到了PHP和Windows上有多字节字符的文件的问题。 这是我的testing用例:
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 )
以下是我select接受的答案的相关摘录(实际上是2年前在线发表的一篇文章的引用):
从这篇文章的评论: http : //www.rooftopsolutions.nl/blog/filesystem-encoding-and-php
在Windows上安装PHP的输出很容易解释:您安装了错误的PHP版本,并且使用了未编译的版本来使用Unicode版本的Win32 API。 由于这个原因,PHP使用的文件系统调用将使用传统的“ANSI”API,因此与此版本的PHP链接的C / C ++库将首先尝试将UTF-8编码的PHPstring转换为本地的“ANSI”在运行环境中select代码页(在从命令行窗口启动PHP之前,请参阅CHCP命令)
您的Windows版本最可能不负责这个奇怪的事情。 实际上,这是您的PHP版本,编译不正确,并且使用传统的ANSI版本的Win32 API(为了与Windows 95/98的旧版本的16位版本兼容,而这些版本在内核中的文件系统实际上没有直接的支持Unicode,但在使用实际的ANSI版本的API之前,使用内部转换层将Unicode转换为本地ANSI代码页)。
使用编译器选项重新编译PHP以使用UNICODE版本的Win32 API(这应该是现在的默认值,并且始终是安装在永远不会是Windows 95或Windows 98的服务器上的默认PHP …)
我无法确认这是否是我的问题。 我用phpinfo()并没有发现任何有趣的东西,但我不知道该找什么。 我一直在使用XAMPP进行简单的安装,所以我真的不确定它是如何安装的。
我正在使用Windows 7,64位 – 所以原谅我的无知,但我甚至不确定是否“Win32”在这里是相关的。 我如何检查我的PHP当前版本是否使用上述configuration进行编译?
- PHP版本 :5.3.8
- 系统 :Windows NT WES-PC 6.1内置7601(Windows 7家庭高级版服务包1)i586
- build立date :2011年8月23日11:47:20
- 编译器 :MSVC9(Visual C ++ 2008)
- 架构 :x86
- configuration命令 :
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部分)的屏幕截图:
我怎样才能知道我的PHP安装是否是“用UNICODE版本的Win32 API编译的”? (这实际上是有道理的吗?)
我想你应该从PHP Windows资源库下载一个官方二进制文件并安装它(注意安装path)。
之后,你需要configurationapache来使用新的二进制文件,而不是默认携带的文件。 很简单:
在WAMP文件夹中find你的httpd.conf文件(类似于C:\ wamp \ bin \ apache \ ApacheXXX \ conf \ httpd.conf) – 也可以通过trayicon。
好吧,现在你发现它find一个匹配LoadModule php5_module的string
好的,只需用你的新的php5_modulereplace这个行就可以在c:/php/php5apache2_2.dll(你保存了安装path!)。 导致类似于LoadModule php5_module "c:/php/php5apache2_2.dll"
瞧。 重置瓦特服务器和testing您的应用程序与最新版本的PHP专门为Windows生成。
我不确定这会解决你的问题,但肯定是一个真正的路要走。 如果你在php设置上有问题,请阅读这篇文章 。
祝你好运!
似乎这个问题已经出现了一段时间,是否用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的字符。
对于ANSI可执行文件或DLL,可能会看到更接近的内容:
30A SetCurrentDirectoryA 15E GetFileAttributesA 171 GetLastError 4B CreateDirectoryA 319 SetFileAttributesA
大多数函数以A结尾,我们可以看到可执行文件很可能是用ANSI标志编译的。
这里是我处理我遇到的一个mbstring问题的一些代码。 我最终通过编码和选项的每个组合迭代,直到其中一个呈现我所需要的输出。 我有这种程序的感觉可能会帮助你find你正在寻找的答案。
不要依赖文档 ,就像我的情况一样,结果不是我认为的选项和编码会做的。 我记得在我的测试中,我会得到矩形,?和像A〜的东西。 我的testing和你的一样, print_r的信息。 在我的情况下,我的脚本是导入客户和销售信息到Quickbooks,无法处理UTF-8。 (QB本身不能或QODBC驱动程序不能)Tildes,坟墓和umlats是不可能的。
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 ,如果谷歌在这里find你,一定要去阅读。
我相信你会想检查一下PHP是否使用mbstring编译(或者如果你使用的是模块,可以安装和启用mbstring模块)。 启用该扩展应解决您的问题。 这个页面应该告诉你一切你需要知道的工作。