Question

I have an PHP app with houndreds of files. The problem is that one or several files apparently have a BOM in them, so including them causes error when creating the session... Is there a way how to reconfigure PHP or the server or how can I get rid of the BOM? Or at least identify the source? I would prefer a PHP solution if available

Was it helpful?

Solution 2

I have been able to identify the files that carried BOM inside them with this script, maybe it helps someone else with the same problem in the future. Works without 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("."); 

OTHER TIPS

The real solution of course is to fix your editor settings (and the other team members as well) to not store files with UTF byte order mark. Read on here: https://stackoverflow.com/a/2558793/43959

You could use this function to "transparently" remove the BOM before including another PHP file.

Note: I really recommend you to fix your editor(s) / files instead of doing nasty things with eval() which i demonstrate here.

This is just a proof of concept:

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, with BOM at beginning

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

OUTPUT:

kaii@test$ php bom_test.php
test
Hello World!
vim $(find . -name \*.php)

once inside vim:

:argdo :set nobomb | :w
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top