我正在编写一些带注释的 PHP 类,我偶然发现了一个问题。我的名字(@author 标签)以 ș (这是一个 UTF-8 字符,...而且是一个奇怪的名字,我知道)。

尽管我将文件保存为 UTF-8,但一些朋友报告说他们看到该字符完全混乱(È™)。添加 BOM 签名即可解决此问题。但这件事让我有点困扰,因为除了我在维基百科上看到的以及关于SO的其他一些类似问题之外,我对此了解不多。

我知道它在文件的开头添加了一些内容,据我了解,这并没有那么糟糕,但我很担心,因为我读到的唯一有问题的场景涉及 PHP 文件。由于我正在编写 PHP 类来共享它们,因此 100% 兼容比在评论中包含我的名字更重要。

但我试图理解其中的含义,我应该放心地使用它吗?或者是否存在可能造成损坏的情况?什么时候?

有帮助吗?

解决方案

事实上,BOM 是发送到浏览器的实际数据。浏览器会很乐意忽略它,但你仍然无法发送标头。

我相信问题确实出在您和您朋友的编辑器设置上。如果没有 BOM,您朋友的编辑器可能无法自动将该文件识别为 UTF-8。他可以尝试设置他的编辑器,以便编辑器 期望 UTF-8 格式的文件(如果您使用真正的 IDE,例如 NetBeans,那么甚至可以将其作为项目设置,以便与代码一起传输)。

另一种方法是尝试一些技巧:一些编辑器尝试根据输入的文本使用一些启发式方法来确定编码。您可以尝试以以下方式启动每个文件

<?php //Úτƒ-8 encoded

也许启发式就能得到它。那里可能有更好的东西,您可以通过谷歌搜索常见的编码检测启发式方法,或者尝试一下:-)

总而言之,我建议修复编辑器设置。

哦等等,我读错了最后一部分:为了将代码传播到任何地方,我想最安全的做法是让所有文件仅包含较低的 7 位字符,即简单的 ASCII,或者只是接受一些使用古老编辑器的人看到你的名字写得很有趣。没有万无一失的方法。BOM 肯定是坏的,因为标头已经发送了。另一方面,只要您在注释中只使用 UTF-8 字符,那么某些编辑器误解编码的唯一影响就是奇怪的字符。我会正确拼写你的名字并添加针对启发式的评论,以便大多数编辑者都能理解它,但总会有人看到虚假字符。

其他提示

bom会导致 Headers already sent 错误,因此,您不能在PHP文件中使用BOM

这是一篇古老的帖子,已经得到了回答,但是我可以为您留下其他一些资源,当我面对这个BOM问题时发现的其他资源。

http://people.w3.org/rishida/utils/bomtester/index.php 在此页面上,您可以检查特定文件是否包含BOM。

还有一个方便的脚本,可以在当前目录上输出所有带有BOM的文件。

<?php 
function fopen_utf8 ($filename) { 
    $file = @fopen($filename, "r"); 
    $bom = fread($file, 3); 
    if ($bom != b"\xEF\xBB\xBF") 
    { 
        return false; 
    } 
    else 
    { 
        return true; 
    } 
} 

function file_array($path, $exclude = ".|..|design", $recursive = true) { 
    $path = rtrim($path, "/") . "/"; 
    $folder_handle = opendir($path); 
    $exclude_array = explode("|", $exclude); 
    $result = array(); 
    while(false !== ($filename = readdir($folder_handle))) { 
        if(!in_array(strtolower($filename), $exclude_array)) { 
            if(is_dir($path . $filename . "/")) { 
                                // Need to include full "path" or it's an infinite loop 
                if($recursive) $result[] = file_array($path . $filename . "/", $exclude, true); 
            } else { 
                if ( fopen_utf8($path . $filename) ) 
                { 
                    //$result[] = $filename; 
                    echo ($path . $filename . "<br>"); 
                } 
            } 
        } 
    } 
    return $result; 
} 

$files = file_array("."); 
?>

我在php.net上找到了该代码

Dreamweaver还可以帮助您进行此操作,它为您提供了保存文件的选择,而不包括BOM的内容

这是一个较晚的答案,但我仍然希望它能有所帮助。再见

只是您知道,PHP有一个选择, zend.multibyte, ,这允许PHP在不提供BOM的情况下读取文件 Headers already sent 错误。

从php.ini文件中:

; If enabled, scripts may be written in encodings that are incompatible with
; the scanner.  CP936, Big5, CP949 and Shift_JIS are the examples of such
; encodings.  To use this feature, mbstring extension must be enabled.
; Default: Off
;zend.multibyte = Off

或者,您可以激活php.ini中的输出缓冲,该输出缓冲将解决“已经发送的标题”问题。如果您的网站有重大负载,则将输出缓冲进行性能使用也非常重要。

在第一行中,$nyckellista变量被隐式声明为数组,然后您将分配到其第一个位置数组。

是你需要/打算的吗?

编辑:

另一个点是在代码的计数区域中,该PHP阵列获得以0开始的数字索引,而不是1(参见 php数组参考

BOM实际上是识别UTF-8文件的最有效方法,现代浏览器和标准支持并鼓励在HTTP响应机构中使用它。

如果是PHP文件,则不是文件,而是作为响应发送的生成的输出,因此显然是在开始时使用BOM保存所有PHP文件不是一个好主意,但这并不意味着您不应该使用BOM在您的回复中。

实际上,您可以在您的Doctype声明之前安全地注入以下代码(如果您将HTML作为响应生成):

<?="\xEF\xBB\xBF"?>

要进一步阅读: https://www.w3.org/international/questions/qa-byte-order-mark#transcoding

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top