Выполнить содержимое строковой переменной (расширенный eval)

dimases

Новичок
Выполнить содержимое строковой переменной (расширенный eval)

Все думаю, как это сделать, так как для eval нужен чистый синтаксис, а если содержимое переменной, к примеру, вот такое:
PHP:
$a='<table align="center" width="200" border=0>
<tr><td><img src="<?=$add_dir?>img/line_200x2_green.gif" width="200" height="2"></td></tr>
<tr><td align=center>

<?
foreach ($get_type_r as $value){
?>

<font color=red>&nbsp;aaa</font>

<?
}
?>
</td>
</tr
</table>';
Как передать на "съедение" парсеру $a, eval($a) врядли получится... Что делать?
 

dimases

Новичок
Автор оригинала: rotoZOOM
eval ("echo \"$a\""); ?
Eval примет только PHP-синтаксис и выдаст ошибку на "<table..."

А вообще это изврат.
Увы, жизненая необходимость, ибо надо как-то выкруться, чтобы влить темплейт в темплейт...

Вообще, конечно, можно создать файл с этим содержимым, сделать над ним include и удалить... Но боюсь тормоза будут.
 

Gas

может по одной?
А почему один не собирается в переменную, а другой собирается, в этом скрыт какой-то тайный смысл?
 

dimases

Новичок
Автор оригинала: Gas
А почему один не собирается в переменную, а другой собирается, в этом скрыт какой-то тайный смысл?
Угу... Короче, хочу прикрутить IPB на сайт... Темплейты сайта просто инклудятся, например,
page.php :
<? include "templates/header.inc"?>
<p><br>
<?=stripslashes($set_page[txt]);?>

<? include "templates/footer.inc"?>

В header.inc, к примеру, помимо статического HTML еще идет динамика в виде вывода меню из БД и пр. (то есть, достаточно реальное решение).

В IPB, как известно, основной шаблон допускается только в виде HTML с внедренными в него макро-тэгами типа "<% BOARD %>".

Да, можно, конечно, забить просто HTML, но это не интересно, неправда ли?
А хочется немного нарастить движок шаблонов IPB, чтобы можно было помимо ститатики использовать и динамику.

То есть, например, если свести шаблон IPB к:

<$ INCLUDE ../forum_ini.inc $>
<$ INCLUDE ../templates/header.inc $>

<% BOARD HEADER %>
<% NAVIGATION %>
<% BOARD %>
<% STATS %>
<% COPYRIGHT %>

<$ INCLUDE ../templates/footer.inc $>

где "<$ INCLUDE файл $>" - макротэг - директива на вставку внешенего файла и обработать его следующим кодом:
PHP:
function include_template($matches){
  ob_start();
    readfile($matches[1]);
    $return=ob_get_contents();
  ob_end_clean();
  return $return;
}
$a=preg_replace_callback('#<\$\s+include\s+(.*?)\s*\$>#si','include_template',$a);
где шаблон будет в переменной $a, то мы получим результирующий код, с которым, если бы был бы в файле, можно сделать include и все...

Идея понятна?
 

Gas

может по одной?
Проверяем существует ли файл с именем, как в директиве. Если нет такого, то сохраняем переменную в файл и подключаем. Если файл существует, то сразу include.

-~{}~ 25.02.05 14:48:

Стоп, а вместо readfile($matches[1]); разве нельзя сделать include?
 

dimases

Новичок
Автор оригинала: Gas
Проверяем существует ли файл с именем, как в директиве. Если нет такого, то сохраняем переменную в файл и подключаем. Если файл существует, то сразу include.
Я тож так думаю... А тормозить из-за дисковых операций сильно будет?

Стоп, а вместо readfile($matches[1]); разве нельзя сделать include?
Можно, но увы, бяка в том, что через функцию все работает, а там свои переменные, если, конечно, не определить как глобальные... те же идентификаторы классов, определнные в одном инклуде не будт работать в другом =( поэтому ёк =(

-~{}~ 25.02.05 16:06:

Автор оригинала: Gas
Проверяем существует ли файл с именем, как в директиве. Если нет такого, то сохраняем переменную в файл и подключаем. Если файл существует, то сразу include.
Заработало:
PHP:
function include_template($matches){
  ob_start();
    readfile($matches[1]);
    $return=ob_get_contents();
  ob_end_clean();
  return $return;
}
$ibforums->skin['template']=preg_replace_callback('#<\$\s+include\s+(.*?)\s*\$>#si','include_template',$ibforums->skin['template']);
global $DOCUMENT_ROOT;
$path=$DOCUMENT_ROOT;
$tmpfname = tempnam($path, "FOO");

$handle = fopen($tmpfname, "w");
fwrite($handle, $ibforums->skin['template']);

fclose($handle);
include ($tmpfname);
unlink($tmpfname);
 

Gas

может по одной?
Ещё как вариант preg_match_all'ом вытягиваешь список файлов для инклуда, в цикле ob_start(), include, ob_get_clean() и preg_replace_callback'ом вставляешь полученный контент за место макросов.

Сразу скажу что скорее всего есть вариант лучше и не я не знаю как работает с шаблонами этот форум, может лучше поменять там что-то.
Сделать профайлинг, посмотри как всё это по скорости.
 

dimases

Новичок
Автор оригинала: Gas
Ещё как вариант preg_match_all'ом вытягиваешь список файлов для инклуда, в цикле ob_start(), include, ob_get_clean() и preg_replace_callback'ом вставляешь полученный контент за место макросов.
Это пробовал, но говорю, что проблема появляется с тем, что вызывается в теле функции =(
 

Gas

может по одной?
так я и не предлагаю вызывать в теле функции
 

Gas

может по одной?
привожу схематически, чтоб пояснить что имел ввиду, а вот что быстрее будет не знаю
PHP:
if (preg_match_all('~includes~', $content, $includes_list)) {
  $tpls = array();
  foreach ($includes_list as $inc) {
     ob_start();
     include $inc;
     $tpls[$inc]  = ob_get_clean();
  }
   $content = preg_replace_callback(заменяем макросы инклудов на значения в массиве $tpls)
}
 

dimases

Новичок
Автор оригинала: Gas
привожу схематически, чтоб пояснить что имел ввиду, а вот что быстрее будет не знаю
PHP:
   $content = preg_replace_callback(заменяем макросы инклудов на значения в массиве $tpls)
}
Ну так preg_replace_callback все равно выполняется через функцию? А тут и может быть проблема с глобальностью переменных, да?

~~~~~

И к тому же, уже существующий метод через файл дает больше возможностей, размещая в шаблон php-код напрямую... У меня сейчас шаблон выглядит так:

PHP:
<?
include "db.php";
include "urler.php";
$db = new MYSQL;

$name_page="Форум";
$title="";
$descrip="";
$keywords="";

$docfile="";
$add_title="<% TITLE %>";
function add_header() {
return <<<EOF

<% GENERATOR %>
<% CSS %>
<% JAVASCRIPT %>

EOF;
}

$not_special_headers=true;

?>


<$ INCLUDE ../templates/header.inc $>

<% BOARD HEADER %>
<% NAVIGATION %>
<% BOARD %>
<% STATS %>
<% COPYRIGHT %>

<$ INCLUDE ../templates/footer.inc $>
 

Gas

может по одной?
так инклуды делаются в области где все переменные и классы определены, и в массиве $tpls у нас содержится уже только html без php. В callback ф-ции делаешь global $tpls и заменяешь соответствующий макрос на елемент массива $tpls

-~{}~ 25.02.05 17:01:

И к тому же, уже существующий метод через файл дает больше возможностей
насчёт возможностей наверное ты прав, тебе ж они надо.
А в целом стояла задача замены макросов на результат выполнения соответствующих файлов.
Задача решена, вот и отлично.
 

vitus

мимо проходил
пишим так :

eval("?>$template<?");

и не паримса, ровно те-же пироги, что и include

- в каждом рисунке - солнце :)
 
Сверху