Pergunta

I am trying to replace content of some tags in included files with content from other files:

$view = preg_replace('/{include ([[:alnum:]\.-]+)}/', ((file_exists('template/$1.html')) ? 'OK $1' : 'KO $1'), file_get_contents('myTemplateFile.tpl'));

All the {include file.ext} references I got in myTemplateFile.tpl are replaced with KO file.ext instead of OK file.ext.

However, if I hardcode file_exists('template/file.ext'), then the right string is displayed.

It appears to me the back-reference is not correctly resolved inside the file_exists call.

What am I doing wrong?

Foi útil?

Solução

preg_replace('/{include ([[:alnum:]\.-]+)}/', ((file_exists('template/$1.html')) ? 'OK $1' : 'KO $1'), file_get_contents('myTemplateFile.tpl'))

This first executes file_exists('template/$1.html'), then passes OK $1 or KO $1 (likely the latter) to preg_replace, which then replaces all occurrences.

You'll have to use a callback to make this work, not call file_exists as argument:

preg_replace_callback(
    '/{include ([[:alnum:]\.-]+)}/',
    function (array $m) {
        return file_exists("template/$m[1].html") ? "OK $m[1]" : "KO $m[1]";
    },
    file_get_contents('myTemplateFile.tpl')
)

Outras dicas

$view = preg_replace(
    '/{include ([[:alnum:]\.-]+)}/', 
    ((file_exists('template/$1.html')) ? 'OK $1' : 'KO $1'), 
    file_get_contents('myTemplateFile.tpl')
);

The above code is executed as follows:

$contents = file_get_contents('myTemplateFile.tpl');

if ((file_exists('template/$1.html')) {
    $result = preg_replace('/{include ([[:alnum:]\.-]+)}/', 'OK $1', $contents);
} else {
    $result = preg_replace('/{include ([[:alnum:]\.-]+)}/', 'KO $1', $contents);
}

As you can see, the file_exists() call is performed before the preg_replace() statement. It is checking for the existence of the file "template/$1.html", where $1 is a literal string which has no special meaning. That file doesn't exist, and the else block (originally 'KO $1') will always get executed.

In short, you can't use the backreferences from preg_replace() function outside the preg_replace() function. The solution is preg_replace_callback():

preg_replace_callback(
    '/{include ([[:alnum:]\.-]+)}/',
    function ($m) {
        return file_exists('template/'.$m[1].'html') ? 'OK '.$m[1]: 'KO '.$m[1];
    },
    file_get_contents('myTemplateFile.tpl')
);

See also:

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top