Порядок следования байтов, вызывающий ошибки сеанса - PullRequest
0 голосов
/ 10 марта 2012

У меня есть приложение PHP с хаундредами файлов.Проблема заключается в том, что один или несколько файлов, очевидно, содержат спецификацию, поэтому их включение приводит к ошибке при создании сеанса ... Есть ли способ перенастроить PHP или сервер или как избавиться от спецификации?Или хотя бы определить источник?Я бы предпочел PHP-решение, если оно доступно

Ответы [ 3 ]

1 голос
/ 10 марта 2012

Разумеется, реальное решение состоит в том, чтобы исправить настройки вашего редактора (и других членов команды), чтобы они не хранили файлы с меткой порядка байтов UTF. Читайте здесь: https://stackoverflow.com/a/2558793/43959

Эту функцию можно использовать для «прозрачного» удаления спецификации перед включением другого файла PHP.

Примечание: я действительно рекомендую вам исправить ваши файлы / редакторы вместо того, чтобы делать неприятные вещи с 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, с спецификацией в начале

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

ВЫВОД:

kaii@test$ php bom_test.php
test
Hello World!
0 голосов
/ 12 марта 2012

С помощью этого скрипта мне удалось идентифицировать файлы, которые содержали спецификацию внутри них, возможно, это поможет кому-то еще с той же проблемой в будущем. Работает без 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("."); 
0 голосов
/ 10 марта 2012
vim $(find . -name \*.php)

один раз внутри vim:

:argdo :set nobomb | :w
...