Working with Japanese filenames in PHP 5.3 and Windows Vista?
I'm currently trying to write a simple script that looks 开发者_运维百科in a folder, and returns a list of all the file names in an RSS feed. However I've hit a major wall... Whenever I try to read filenames with Japanese characters in them, it shows them as ?'s. I've tried the solutions mentioned here: php readdir problem with japanese language file name - however they do not work for some reason, even with:
header('Content-Type: text/html; charset=UTF-8');
setlocale(LC_ALL, 'en_US.UTF8');
mb_internal_encoding("UTF-8");
At the top (Exporting as plain text until I can sort this out).
What can I do? I need this to work and I don't have much time.
function fx_dir_utf8 ($path)
{
// use this as failback on windows for usual dir listing
// give it a UTF-8 path and receive a UTF-8 listing
$path = iconv ('UTF-8', 'UTF-16LE', $path);
$cmd = 'cmd /U /C dir '. str_replace ('/', '\\', $path);
// windows command line returns CP850 or UTF-16LE
$dir_str = shell_exec ($cmd);
$dir_str = iconv ('UTF-16LE', 'UTF-8', $dir_str);
print_r ($dir_str);
// further parse $dir_str
return ($dir_str);
}
This is not possible. It is a limitation of PHP itself. PHP does not use the wide WIN32 API calls, so you're limited by the codepage. UTF-8 (65001) is not valid for this purpose.
If you set a breakpoint at readdir_r()
in win32\readdir.c
, you'll see that FindNextFile
already returns a filename with question marks in place of the characters you want, so there's nothing you can do about it, apart from patching PHP itself.
This displays Japanese filenames correctly on a Windows server
if ($handle = opendir($this->dir)) {
while (false !== ($file = readdir($handle))){
$name = mb_convert_encoding($file, "UTF-8", "SJIS-win" );
echo "$name<br>";
}
closedir($handle);
}
Yeah, no, as others stated it, PHP CAN'T do it… Shame on you PHP!
As others also suggested, one alternative could be to write a proxy in another language that can read those file names:
Some suggested C, but personally I found Python much more simpler/attractive (here Python3).
** BE SURE TO SANITIZE YOUR VARIABLES BEFORE USING THIS **
$success = (bool)(int)shell_exec('python -c "import os;'.
'os.chdir(\''.$dir.'\'); '.
'import urllib.parse; '.
'file_list = tuple(map(urllib.parse.quote_plus, os.listdir())); '.
'print(int(\''.urlencode($_GET['src']).'\' in file_list and \''.urlencode($_GET['src'].'.part').'\' not in file_list))"'
);
Yup, not pretty, but this snippet allowed me to check against file names by urlencode
'ing them.
(Ndla: That particular snippet was used to find out when a file was done downloading with Firefox without having to mess with the API. Not the best but WORKING and fast to setup)
You can do it in PHP. Write a small C program to read directories and call that program from PHP.
See also: http://en.literateprograms.org/Directory_listing_(C,_Windows) http://www.daniweb.com/forums/thread74944.html http://forums.devshed.com/c-programming-42/reading-a-directory-in-windows-36169.html
精彩评论