【问题标题】:Check if csv file is in UTF-8 with PHP使用 PHP 检查 csv 文件是否为 UTF-8
【发布时间】:2012-02-12 23:58:27
【问题描述】:

有没有一种方法可以在没有 BOM 编码的情况下检查 CSV 文件的 UTF-8?我想检查整个文件而不是单个字符串。

我会尝试使用特殊字符设置第一行,然后读取字符串并检查它是否与我脚本中硬编码的相同字符串匹配。但我不知道这是否是个好主意。

仅限 Google showed me this。但是上一篇文章的链接不可用。

【问题讨论】:

    标签: php csv utf-8


    【解决方案1】:

    我推荐这个函数(来自 symfony 工具包):

    <?php
      /**
       * Checks if a string is an utf8.
       *
       * Yi Stone Li<yili@yahoo-inc.com>
       * Copyright (c) 2007 Yahoo! Inc. All rights reserved.
       * Licensed under the BSD open source license
       *
       * @param string
       *
       * @return bool true if $string is valid UTF-8 and false otherwise.
       */
      public static function isUTF8($string)
      {
        for ($idx = 0, $strlen = strlen($string); $idx < $strlen; $idx++)
        {
          $byte = ord($string[$idx]);
    
          if ($byte & 0x80)
          {
            if (($byte & 0xE0) == 0xC0)
            {
              // 2 byte char
              $bytes_remaining = 1;
            }
            else if (($byte & 0xF0) == 0xE0)
            {
              // 3 byte char
              $bytes_remaining = 2;
            }
            else if (($byte & 0xF8) == 0xF0)
            {
              // 4 byte char
              $bytes_remaining = 3;
            }
            else
            {
              return false;
            }
    
            if ($idx + $bytes_remaining >= $strlen)
            {
              return false;
            }
    
            while ($bytes_remaining--)
            {
              if ((ord($string[++$idx]) & 0xC0) != 0x80)
              {
                return false;
              }
            }
          }
        }
    
        return true;
      }
    

    但是当它检查字符串的所有字符时,我不建议在大文件上使用它。只需检查前 10 行,即

    <?php
    $handle = fopen("mycsv.csv", "r");
    $check_string = "";
    $line = 1;
    if ($handle) {
        while ((($buffer = fgets($handle, 4096)) !== false) && $line < 11) {
            $check_string .= $buffer;
            $line++;
        }
        if (!feof($handle)) {
            echo "Error: unexpected fgets() fail\n";
        }
        fclose($handle);
    
        var_dump( self::isUTF8($check_string) );
    }
    

    【讨论】:

      【解决方案2】:
      if (mb_check_encoding(file_get_contents($file), 'UTF-8')) {
          // yup, all UTF-8
      }
      

      如果文件很大并且您不想一次将其全部存储在内存中,您也可以使用fgets 逐行浏览它。不知道你的问题的第二部分是什么意思。

      【讨论】:

      • 这个函数不检查坏字节序列,它只检查字节流是否有效。
      • @Damien 如果您能澄清这到底是什么意思,我将不胜感激。它捕获格式错误的 UTF-8 字节序列,那么什么是“坏字节序列”呢? codepad.viper-7.com/6yvKe9.
      • 有一个 bug report 关于这个函数在 UTF-8 中不能捕获代理,但我 can't reproduce that 了。
      • 一个 UTF8 坏字节序列就像 \x00\xE3 (两个序列,UTF-32)。它是有效的 UTF-8,但不是有效的序列:�
      • @Damien 和 mb_check_encoding 很好地抓住了这一点:codepad.viper-7.com/FBjzrC
      猜你喜欢
      • 2010-09-12
      • 2019-05-17
      • 1970-01-01
      • 2018-09-07
      • 2012-04-26
      • 2021-10-11
      • 1970-01-01
      • 2010-12-01
      • 1970-01-01
      相关资源
      最近更新 更多