Php fwrite()和UTF8

Php fwrite()和UTF8,php,utf-8,fwrite,Php,Utf 8,Fwrite,我使用php fwrite()创建了一个文件,我知道我所有的数据都是UTF8格式的(我已经做了大量的测试——在将数据保存到db并输出到普通网页时,所有工作都正常,并以UTF8格式报告),但我被告知我输出的文件包含非UTF8数据:(bash(CentOS)中是否有命令)检查文件的格式 使用vim时,其内容显示为: 不要做任何事……这是一场灾难 伟大的网站与 一切……我们只是 发射/ 任何帮助都将不胜感激:要么确认文件是UTF8,要么如何将UTF8内容写入文件 更新 为了澄清我如何知道我有UTF8中

我使用php fwrite()创建了一个文件,我知道我所有的数据都是UTF8格式的(我已经做了大量的测试——在将数据保存到db并输出到普通网页时,所有工作都正常,并以UTF8格式报告),但我被告知我输出的文件包含非UTF8数据:(bash(CentOS)中是否有命令)检查文件的格式

使用vim时,其内容显示为:

不要做任何事……这是一场灾难 伟大的网站与 一切……我们只是 发射/

任何帮助都将不胜感激:要么确认文件是UTF8,要么如何将UTF8内容写入文件

更新

为了澄清我如何知道我有UTF8中的数据,我做了以下工作:

  • 保存数据时,DB设置为utf8
  • 要访问数据库,我首先运行以下命令:

    $enc=mb\u detect\u编码($data);

    $data=mb\u convert\u编码($data,“UTF-8”,$enc);

  • 就在我运行fwrite之前,我已经用检查了数据。注意,每条数据返回“是utf-8”

    if(strlen($data)==mbu strlen($data,'UTF-8'))打印“非UTF-8”;
    else打印“是utf-8”;


  • 谢谢!

    我知道我所有的数据都是UTF8格式的
    -错误。
    编码它不是文件的格式。因此,请检查页面标题中的字符集,从中获取数据:
    标题(“内容类型:text/html;charset=utf-8;”;

    并检查数据是否真的采用多字节编码:
    if(strlen($data)==mb_strlen($data,'UTF-8'))打印“非UTF-8”;

    else打印“utf-8”;

    问题是您的数据是双重编码的。我假设您的原始文本是:

    Don’t do anything 您将获得与输出类似的内容。

    不是二进制安全的。这意味着,您的数据(无论编码是否正确)可能会被此命令或其底层例程损坏

    为了安全起见,您应该使用with binary mode标志。这是
    b
    。之后,
    fwrite()
    将按“原样”保护字符串数据,这在PHP中一直是二进制数据,因为PHP中的字符串是二进制字符串

    背景:某些系统在文本数据和二进制数据之间存在差异。二进制标志将显式命令此类系统上的PHP使用二进制输出。处理UTF-8时,应注意数据不会被篡改。这可以通过将字符串数据作为二进制数据处理来防止

    但是:如果不是像您在问题中说的那样,数据的UTF-8编码被保留,那么您的编码就会被破坏,甚至二进制安全处理也会保持破坏状态。但是,使用二进制标志,您仍然可以确保这不是
    fwrite()
    应用程序的一部分正在破坏某些东西


    这里的另一个答案是正确的,如果你只有数据,你不知道编码。但是,如果数据验证UTF-8编码与否,你可以验证数据,这样你至少有机会检查编码。我在一个UTF-8发布的问题中发布了一个PHP函数,我想它可能对你有用如果你需要调试东西:查找can\u be\u valid\u utf8\u statemachine,这是函数的名称。

    我唯一要做的就是向CSV添加一个utf8 BOM,数据是正确的,但是文件读取器(外部应用程序)如果知道数据是UTF8格式的,而不想设置标题,则无法在没有BOM表的情况下正确读取文件

    我写了一个与另一个步骤相适应的解决方案

    解决方案如下:由于UTF-8字节顺序标记是
    \xef\xbb\xbf
    ,我们应该将其添加到文档的标题中

    <?php
    function writeStringToFile($file, $string){
        $f=fopen($file, "wb");
        $file="\xEF\xBB\xBF".$file; // this is what makes the magic
        fputs($f, $string);
        fclose($f);
    }
    ?>
    
    
    
    您可以根据您的代码对其进行调整,基本上您只需要确保您编写了一个UTF8文件(正如您所说的,您知道您的内容是UTF8编码的)


    试试这个更有用的简单方法,并在标签前面添加到页面顶部

    <head>
      <meta charset="utf-8">
    </head>
    
    
    
    有一些原因: 首先,您从数据库获取信息,它不是utf-8。 如果你确定这是真的,使用这个,我总是使用这个,它工作:

    $file= fopen('../logs/logs.txt','a');
    fwrite($file,PHP_EOL."_____________________output_____________________".PHP_EOL);
    fwrite($file,print_r($value,true));
    

    我知道我所有的数据都是UTF8格式的-已经对此进行了广泛的测试-当将数据保存到数据库并在正常网页上输出时,都可以正常工作并以UTF8格式报告。这并不意味着你的数据是UTF-8格式的。输出是输出,输入是输入。当将数据保存到数据库时,你可以将其转换。此外,文件不能具有
    编码
    属性,只能具有数据编码。因此,如果您的文件包含非utf编码的数据,这绝对意味着数据的编码错误。为了确保-使用我答案中的代码。我确信它是utf8。我也使用您的代码进行了测试,我在文件中写入的每一行都说“utf-8”,没有提到“非utf-8”,那么vim中存在问题,可能某些地区不是我nstalled.在基于debian的系统中,在控制台中编写
    dpkg重新配置区域设置
    ,并确保选择了这些区域设置:en.GB UTF-8、en.US UTF-8、en.US UTF-8。使用
    mb_detect_编码
    这是非常错误的方式。您应该确保UTF-8中的数据只是因为所有头都正确发送。
    mb_detect_编码
    这是毫无意义的Action,不要使用它。另外,如果在转换之后检查
    if(strlen…
    ),它将无法工作到。请参阅以获取逐位检查字符串UTF-8的PHP函数。它被称为
    是否有效\u utf8\u statemachine()
    。它的结果至少比你的斯特伦比较法更准确。在你将某个东西编码到UTF-8之前,你应该确保它是否是UTF-8,因为在编码到UTF-8之后,它将始终是UTF-8。所以你不能稍后再检查。这并不能真正解决问题。他没有使用任何可能对af不利的编码受更改新行字符的影响。事实上,大多数常用的编码要么与ASCII兼容,要么至少保留ASCII字符,直到生成代码
    $handle = fopen($file,"w");
    fwrite($handle, pack("CCC",0xef,0xbb,0xbf));
    fwrite($handle,$file); 
    fclose($handle);
    
    <head>
      <meta charset="utf-8">
    </head>
    
    $file= fopen('../logs/logs.txt','a');
    fwrite($file,PHP_EOL."_____________________output_____________________".PHP_EOL);
    fwrite($file,print_r($value,true));