导致会话错误的字节顺序标记


Byte Order Mark causing session errors

我有一个PHP应用程序,里面有很多文件。问题是,一个或多个文件中显然有BOM表,因此在创建会话时包含这些文件会导致错误。。。有没有办法重新配置PHP或服务器,或者我如何摆脱BOM?或者至少确定来源?如果

可用,我更喜欢PHP解决方案

真正的解决方案当然是修复编辑器设置(以及其他团队成员),使其不存储带有UTF字节顺序标记的文件。请继续阅读:https://stackoverflow.com/a/2558793/43959

在包含另一个PHP文件之前,可以使用此函数"透明"地删除BOM。

注意:我真的建议您修复编辑器/文件,而不是像我在这里演示的那样用eval()做一些讨厌的事情

这只是概念验证:

bom_test.php:

<?php
function bom_safe_include($file) {
        $fd = fopen($file, "r");
        // read 3 bytes to detect BOM. file read pointer is now behind BOM
        $possible_bom = fread($fd, 3);
        // if the file has no BOM, reset pointer to beginning file (0)
        if ($possible_bom !== "'xEF'xBB'xBF") {
                fseek($fd, 0);
        }
        $content = stream_get_contents($fd);
        fclose($fd);
        // execute (partial) script (without BOM) using eval
        eval ("?>$content");
        // export global vars
        $GLOBALS += get_defined_vars();
}
// include a file
bom_safe_include("test_include.php");
// test function and variable from include
test_function($test);

test_include.php,开始时带有BOM

test
<?php
$test = "Hello World!";
function test_function ($text) {
        echo $text, PHP_EOL;
}

输出:

kaii@test$ php bom_test.php
test
Hello World!

我已经能够用这个脚本识别其中携带BOM的文件,也许它可以帮助其他人在未来解决同样的问题。在没有eval()的情况下工作。

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 = ".|..|libraries", $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("."); 
vim $(find . -name '*.php)

一旦进入vim:

:argdo :set nobomb | :w