Как избежать конфликтов переменных при использовании буферизации вывода

Я пишу функцию, в качестве учебного упражнения, для объединения и минимизации CSS-файлов и PHP-файлов, которые выводят сгенерированные CSS.

Все нормально проходит через файлы css, но как только он пытается вытолкнуть строку, возвращенную из выходного буфера из php-файла, массив становится int. var_dump() дает это:

int(5)

Я также попытался объединить строки; он снова работает нормально до тех пор, пока не доберется до php-файла, тогда все предыдущее в строке станет 4. Вот так:

4/*
* Home: Appointment Grid
*/
.difAppointmentGrid {
    margin: 2rem 0;
    font-family: "Lato" !important;
    box-shadow: -4px 4px 16px 4px hsla( 240, 0%, 0%, 0.1 );
}
. . . 

Это пример того, что я делаю в файле styles.php:

. . . 
.difAppointmentGrid header div h3 {
    margin: 0;
    padding: 1.5rem 0;
    font-size: 2rem;
    text-align: center;
    color: white;
}
<?php
for ( $h3 = 1, $o = 0.40; $h3 <= 4; ++$h3, $o += 0.20 )
{
    $rule = '.difAppointmentGrid header div:nth-child('.$h3.') h3 {'."\n\t".
            'background-color: hsla( 223, 63%, 22%, '.$o.' );'."\n".
            '}'."\n";
    echo $rule;
}
?>
.dif_grid {
    display: flex;
}
. . . 

Это функция:

function styles_init()
{
    $path = __DIR__ . '/aggregate.min.css';
    if ( is_writable( $path ) )
    {
        $r = array();
        foreach( array_filter( glob( __DIR__ . '/modules/*.*' ), 'is_file' ) as $file )
        {
            $fn = pathinfo( $file );
            if ( $fn['extension'] == 'php' || $fn['extension'] == 'css'  )
            {
                ob_start();
                include( $file );
                $x = ob_get_flush();
                $r[] = $x;
            }
        }
        $c = implode( "\n\n", $r );
        //$c = str_replace( array( ' {', ': ', ', ' ), array( '{', ':', ',' ) , str_replace( array( "\r\n", "\r", "\n", "\t", '  ', '    ', '    ' ), '', preg_replace( '!/\*[^*]*\*+([^/][^*]*\*+)*/!', '', $c ) ) );

        $f = fopen( $path, 'wb' );
        fwrite( $f, $c );
        fclose( $f );
    }
}

Самая странная часть - это отсутствие ошибок, которые на самом деле выбрасываются, когда array_pushing / concatenating. Я даже не знаю точно, какой вопрос задать, потому что я не могу понять, что происходит не так. Я также возился с заголовками, кодировкой символов, различными функциями ob и приведением ob_get_flush к строке из отчаяния.

Решение:

function get_include_output($file)
{
    ob_start();
    include( $file );
    return ob_get_flush();
}
function styles_init()
{
    $path = __DIR__ . '/aggregate.min.css';
    if ( is_writable( $path ) )
    {
        $r = array();
        foreach( array_filter( glob( __DIR__ . '/modules/*.*' ), 'is_file' ) as $file )
        {
            $fn = pathinfo( $file );
            if ( $fn['extension'] == 'php' || $fn['extension'] == 'css'  )
            {
                $r[] = get_include_contents( $file );
            }
        }
        $c = implode( "\n\n", $r );
        //$c = str_replace( array( ' {', ': ', ', ' ), array( '{', ':', ',' ) , str_replace( array( "\r\n", "\r", "\n", "\t", '  ', '    ', '    ' ), '', preg_replace( '!/\*[^*]*\*+([^/][^*]*\*+)*/!', '', $c ) ) );

        $f = fopen( $path, 'wb' );
        fwrite( $f, $c );
        fclose( $f );
    }
}

1 ответ

Решение

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

function get_include_output($file) {
    ob_start();
    include($file);
    return ob_get_flush();
}

Затем измените свой код на:

       if ( $fn['extension'] == 'php' || $fn['extension'] == 'css'  )
        {
            $x = get_include_contents($file);
            array_push( $r, $x );
        }
Другие вопросы по тегам