【问题标题】:Byte Order Mark causing session errors字节顺序标记导致会话错误
【发布时间】:2012-03-10 12:48:14
【问题描述】:

我有一个包含数百个文件的 PHP 应用程序。问题是一个或多个文件中显然有 BOM,因此在创建会话时包含它们会导致错误...有没有办法重新配置 PHP 或服务器,或者如何摆脱 BOM?或者至少确定来源?如果可用,我更喜欢 PHP 解决方案

【问题讨论】:

标签: php session utf-8 byte-order-mark


【解决方案1】:

当然,真正的解决方案是修复您的编辑器设置(以及其他团队成员)以不存储带有 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!

【讨论】:

    【解决方案2】:

    我已经能够使用此脚本识别其中包含 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("."); 
    

    【讨论】:

      【解决方案3】:
      vim $(find . -name \*.php)
      

      在 vim 中一次:

      :argdo :set nobomb | :w
      

      【讨论】:

        猜你喜欢
        • 2016-02-04
        • 2011-10-30
        • 1970-01-01
        • 2015-02-28
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2017-08-09
        • 2015-06-03
        相关资源
        最近更新 更多