How can I create a file using the PHP function fop

2019-07-06 05:41发布

I am using fopen() to create files with file names based on the user's input. In most of the cases that input will be cyrillic. I want to be able to see the file names on my computer, but seemingly they aren't with the right encoding and my OS (Windows 10) displays something like this - "ЙосиС.txt".

Windows uses UTF-16, so I tried to convert the encoding of the variable where the name is stored to UTF-16, but I got errors when using fopen, fwrite and fclose.

This is the code:

<?php
if(isset($_POST["submit"])) {
$name = $_POST["name"];
$file = fopen("$name.txt", "a");
fwrite($file, $string);
fclose($file);
}?>

标签: php encoding
1条回答
狗以群分
2楼-- · 2019-07-06 05:50

It's true that Windows and NTFS use UTF-16 for filenames, so you can read and write files with Unicode characters in their name.

However, you need to call the appropriate function in order to leverage Unicode: _wfopen() (C runtime) or CreateFileW() (Windows API). See What encoding are filenames in NTFS stored as?.

PHP's fopen() does not call either of those functions, it uses the plain old ANSI fopen(), as apparently PHP is not compiled with the _UNICODE constant which will cause fopen() to be converted to _wfopen() and so on (see also How to open file in PHP that has unicode characters in its name? and glob() can't find file names with multibyte characters on Windows?).

See below for a couple of possible solutions.

Database

A database solution: write the Unicode name in a table, and use the primary key of the table as your filename.

Transliteration

You could also use transliteration (as explained in PHP: How to create unicode filenames), which will substitute the Unicode characters that aren't available in the target character set with similar characters. See php.net/iconv:

$filename = iconv('UTF-8', 'ASCII//TRANSLIT', "Žluťoučký kůň\n");
// "Zlutoucky kun"

Note that this can cause collisions, as multiple different Unicode characters could be transliterated to the same ANSI character sequences.

Percent-encoding

Another suggestion, as found in How do I use filesystem functions in PHP, using UTF-8 strings?, is to urlencode the filename (note that you shouldn't directly pass user input to the filesystem like this, you're allowing users to overwrite system files):

$name = urlencode($_POST["name"]) . ".txt";
$file = fopen($name, "a");

Recompile PHP with Windows Unicode support

If your end goal is to write files with Unicode file names without changing any code, you'll have to compile PHP yourself on Windows using the _UNICODE constant and a Microsoft compiler, and hope it'll work. I suppose not.

Most viable: WFIO

Alternatively, you can use the suggestion from How to open file in PHP that has unicode characters in its name? and use the WFIO extension, and refer to files via the wfio:// protocol.

file_get_contents("wfio://你好.xml");
查看更多
登录 后发表回答