Хорошо, я знаю, что это плохая практика, но часть кода существовала, и я должен расширить ее для запуска пользовательских функций с одним аргументом.
Итак, наши страницы хранятся в БД, и когда они отображаются в нашем шаблоне, мы в настоящее время используем три разные функции preg_replace с модификаторами e на всей html-странице.
Это кажется медленным, поэтому я хотел бы изменить его на использование только одного вызова preg_replace и иметь возможность предоставлять пользовательскую функцию с 1 аргументом способом bbcode: Пример:
[FUNC: testfunc (тестовая строка)]
Итак, это то, что я придумал ... Я не уверен, какой метод более безопасен, preg_rplace с e modifer или preg_replace_callback:
<?php
$str = '
<h2>Title That should Not Be Affected</h2>
<p>[FUNC:linkbox(/somestuff/newpage.html)]</p>
<a href="[FUNC:getvar(url)]">[FUNC:getvar(title)]</a>
<p>Random Html THat should not be affected</p>
<p>[FUNC:linkbox(/somestuff/otherpage.html)]</p>
';
$str2 = preg_replace_callback('~\[FUNC:(.*?)\((.*?)\)\]~', 'callback_caller', $str);
$str = preg_replace('~\[FUNC:(.*?)\((.*?)\)\]~e', 'emodcaller("\\1", "\\2")', $str);
echo $str.'<br><br>'.$str2;
function callback_caller($args){
if(!isset($args[0], $args[1]))
return false;
$func = strip_tags($args[1]);
$param = isset($args[2]) ? strip_tags($args[2]) : '';
//Only allow calling of known functions
switch($func){
case 'linkbox':
return linkbox($param);
break;
case 'getvar':
return getvar($param);
break;
case 'default':
return '';
break;
}
}
function emodcaller($fun, $arg){
$arg = strip_tags($arg);
//Only allow calling of known functions
switch($fun){
case 'linkbox':
return linkbox($arg);
break;
case 'getvar':
return getvar($arg);
break;
case 'default':
return '';
break;
}
}
function linkbox($addy){
return 'Linkbox Called: '.$addy;
}
function getvar($arg) {
switch($arg){
case 'url':
return '/index.html';
break;
case 'title':
return 'This is a test title';
break;
}
}
?>
Что мне нравится в использовании модификатора e, так это то, что я могу добавить другой параметр к вызову функции непосредственно в php, если мне нужно, например:
preg_replace('~\[FUNC:(.*?)\((.*?)\)\]~e', 'emodcaller("\\1", "\\2", $page->getid())', $str);
Один метод безопаснее другого? Они оба огромные угрозы безопасности? Я должен иметь некоторую реализацию этих ..
Редактировать: я понял, что вы можете передать функции обратного вызова дополнительные параметры, используя анонимную функцию, такую как:
$content = preg_replace_callback(
'~(?:\<p\>)?\[FUNC:(.*?)\((.*?)\)\](?:\<\/p\>)?~',
function($matches) use ($article) {
return callback_caller($matches, $article);
},
$content);
Это передает функции callback_caller () весь мой класс статьи для использования.
Является ли создание анонимной функции для каждого совпадения плохим с точки зрения производительности?