cotonti.com : Шаблонизатор https://www.cotonti.com Neueste Themenbeiträge Cotonti en Thu, 19 Mar 2026 07:10:59 -0000 Macik # Sergeich : Macik, по поводу дополнения, собственно вы делаете обратную работу, одним из приоритетов в развитии котонти было вынесенеие всего хтмл из пхп-кода, плюс разбиение крупных тегов (несущих большой кусок хтмл) на мелкие составляющие.
Видимо я не до конца донес мысль. Я не предлягаю переносить ХТМЛ в код, отнюдь. Наоборот из кода он пропадает практически полностью, т.к. все Тэги парсятся отдельной библиотекой, и уже она на основе внутренних шаблонов (тоже настраиваемых) создает готовый к работе ХТМЛ-тэг.
Примерно так:
Дизайнер пишет в шаблоне что-то типа:
 {INPUT_PASSWORD}
Программист пишет примерно следующее:
$ctl['Type'] = 'password';
$ctl['Name'] = 'rpassword';
$ctl['Class'] = '_default';
init_control('INPUT_PASSWORD',$ctl);
parse_control('INPUT_PASSWORD');
На выходе в шаблоне получаем готовый тэг:
<input type="password" class="password" name="rpassword" size="16" maxlength="32" />

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

# Sergeich : По поводу начала поста, а ваша конструкция сможет отрабатывать сложные куски хтмл с включением различных тегов движка? и будет ли это проще для дизайнера?
Да это вопрос. Я просто всегда иду со стороны того, что если не хватает функциональности - постарайся ее сделать доступными (читай предлагаемыми) методами и до последнего не залезать в "Core".]]>
Fr, 10 Jul 2009 02:57:43 -0000
Sergeich
По поводу начала поста, а ваша конструкция сможет отрабатывать сложные куски хтмл с включением различных тегов движка? и будет ли это проще для дизайнера?]]>
Do, 09 Jul 2009 23:33:35 -0000
Macik Хотя логика в блочном виде как сейчас не менее громоздка чем callback-функции.
Отдельного плагина на каждый случай не потребуется - достаточно описать класс с минимальным и достаточным набором callback функций.
Верстальщику вообще практически ничего объяснять не надо - надо показать 1 пример и все будет понятно.

Вот конкретика и примеры:
Вместо вот этого
<!-- IF {PAGE_DESC}== "" -->
Описание страницы пустое.
<!-- ENDIF -->

Можно будет писать так:
{PAGE_DESC|IS_NULL('Описание страницы пустое.')}

Все что нужно для этого - создать в системе дочерний класс:
class XT extends XTemplate {
  // функция проверки на предмет присвоено ли тэгу значение
  public function IS_NULL ($tag,$str) {
    // $tag - тело тэга с уже присвоеным значением
    // $str - строка, которую необходимо вывести если тег пустой
    if ($tag=='') {return $str;} else {return $tag;}
  }
}

Аналогичным образом можно реализовать любое другое условие.
Из плюсов такого подхода:
1. Мы не трогаем исходный класс;
2. Никаких отдельных плагинов - один раз описываем в системе класс и прописываем необходимую функциональность;
3. Экономим на размерах шаблона и соответственно меньше шансов допустить в шаблоне ошибку/опечатку.

Как дополнение:

В своем проекте пытаюсь реализовать "прозрачную" (более абстрактную) для верстальщиков систему интерфейса.

Сейчас по сути в шаблонах огромное количество HTML кода, и при том программно зависимого, как например:
<form action="{PAGEADD_FORM_SEND}" method="post" name="newpage" enctype="multipart/form-data">
...
<form>
в таком случае дизайнер/верстальщик должен знать что указать в параметрах action, mothod, name, и т.п.

Идея в том, что бы абстрагироваться от этого. Дизайнер указывает в шаблоне только ключевые Тэги:
<!-- BEGIN: MAIN -->
Форма регистрации:
{FORM_LOGIN}
<!-- END: MAIN -->
<!-- BEGIN: FORM_LOGIN -->
Введите свои данные:
Login: {INPUT_USER_LOG}
Password: {INPUT_USER_PASS}
{BUTTON_LOGIN_SEND}
{SOME_TEXT}
<!-- END: FORM_LOGIN -->

Задача программиста договориться с дизайнером о наборе тегов для конкретной формы.
Затем проинициализировать структуру данных, которая задаст парамертры конкретных элементов.
Далее вызвать автоматический обработчик, который уже на основании заполненых данных и на основании названия тегов решит что и как парсить.]]>
Do, 09 Jul 2009 22:26:29 -0000
Trustmaster 1. б. XTemplate развивается очень пассивно. Выше вероятность, что мы перепишем XTemplate, чем то, что выйдет новая версия с важными патчами, которые на придётся включать. Последнее не так уж страшно.
1. в. Опять же, callback-функции надо будет писать в виде специальных плагинов. И верстальщику непросто объяснить, что такое callback-функция.]]>
Mo, 06 Jul 2009 14:48:27 -0000
Macik
1. Не поддерживаю вашу инициативу по внесению логики в шаблоны в таком виде, по следующим причинам:
а. Логика должна быть в программной части, визуальная часть в шаблонах.
б. XTemplate сторонняя разработка и не есть гут ее "строгать" напильником, тем более, что в случае ее обновления будет трудно совмещать одно с другим.
в. Почти все (а может и все) можно реализовать за счет Callback функций - встроенного в XTemplate механизма. Причем без громоздких блочных IF-ENDIF конструкций в шаблоне.


2. В своем проекте наткнулся на баг XTemplate - при попытке переопределния tag_start_delim, tag_end_delim
перестают работать callback функции. Видимо где-то косяк с правилами и сочетанием RegExp. Но разобраться в коде не осилил.

Безотносительно написанного - спасибо вам за вашу работу. И развитие проекта.]]>
So, 05 Jul 2009 08:46:45 -0000
medar dervan, dayver, супер, молодцы. :)
У меня, к сожалению, сейчас аврал на работе, времени для cotonti сейчас нет. Надеюсь скоро вернуться.

Предложенный вариант xtemplate, мне кажется, можно коммитить.

По поводу вложенности условий - сложно сказать, нужны ли они. Это будет провоцировать людей на программинг в шаблонах, а это все-таки лучше делать в плагинах.

По поводу eval(). В принципе, это дыра в безопасности, так как ушлый сторонний скинмейкер может разместить в условии кусок вредоносного кода. По хорошему надо бы от него совсем отказаться, сделав парсер условных выражений..]]>
Mi, 25 Mär 2009 17:59:03 -0000
dervan # Trustmaster : Ещё бы сделали ... разбор условий без eval'а

Хорошая мысль. :)

Пожалуй, совсем от варианта с eval() отказываться не надо - может потребоваться сложное условие. Но для простейших вариантов, когда в IF проверяется значение переменной bool или int, несложно сделать вариант без eval().

Мы с Dayver'ом, когда обсуждали разные варианты условий для IF (с вызовом функцищ, с использованием $GLOBALS для передачи аргументов функцищам), решили по возможности использовать в шаблонах для IF'ов не код PHP, а сформированные специально для шаблонов переменные bool. Именно такой подход использовал Dayver в выложенных им файлах, которые демонстрируют использование IF'ов в шаблонах.

Если придерживаться такого подхода и использовать в условиях IF шаблона только значения переменных bool или int, то эти условия будут проверяться без вызова eval().

Предлагаем улучшенный вариант XTemplate, проверяющий простые условия без eval(): xtemplate.class.php_57.zip
Остальные условия, которые не сводятся к простой проверке значения bool или int, как и прежде будут обрабатываться вызовом eval().

Все условия в выложенных Dayver'ом файлах этим вариантом XTemplate будут проверяться без eval(), т.е. будут обработаны быстрее.


Пример.

# Sergeich : В шаблоне page.tpl мне нужно разделять теги запятой (или любым другим разделителем), сейчас я это реализовал так:
<!-- BEGIN: PAGE_TAGS_ROW -->
	<a href=https://www.cotonti.com/"{PAGE_TAGS_ROW_URL}">{PAGE_TAGS_ROW_TAG}</a>,
<!-- END: PAGE_TAGS_ROW -->
Проблема в том, что после последнего тега также вставляется запятая (разделитель), что есть не красиво. Как бы убрать эту лишнюю запятую?

Если решать эту задачу, исходя из существующего кода плагина tags, получится вот что.

# dervan :
		<!-- BEGIN: PAGE_TAGS_ROW -->
		<a href=https://www.cotonti.com/"{PAGE_TAGS_ROW_URL}">{PAGE_TAGS_ROW_TAG}</a><!-- IF $GLOBALS['tag'] != $GLOBALS['tags'][count($GLOBALS['tags']) - 1] -->,<!-- ENDIF -->
		<!-- END: PAGE_TAGS_ROW -->
Только вот есть сомнения, правильно ли это - раз уж убирать HTML из кода, IMHO тогда не следует злоупотреблять кодом в шаблонах. А тут при каждом проходе парсера будет вызываться функцища count(). По-хорошему, в plugins/tags/tags.page.php надо добавить флажок, чтобы IF определял по нему последний проход парсера в блоке PAGE_TAGS_ROW.

Правильнее будет сформировать в plugins/tags/tags.page.php переменную для шаблона:
	$tags_cntdwn = count($tags);
	if($tags_cntdwn > 0)
	{
		foreach($tags as $tag)
		{
			$tags_cntdwn--;
и использовать в шаблоне простое условие:
		<!-- BEGIN: PAGE_TAGS_ROW -->
		<a href=https://www.cotonti.com/"{PAGE_TAGS_ROW_URL}">{PAGE_TAGS_ROW_TAG}</a><!-- IF {PHP.tags_cntdwn} -->,<!-- ENDIF -->
		<!-- END: PAGE_TAGS_ROW -->
При таком решении условие IF будет проверяться без eval(), и шаблон будет распарсен быстрее.]]>
Mi, 25 Mär 2009 07:24:54 -0000
Trustmaster ]]> Mo, 23 Mär 2009 12:57:06 -0000 dervan esclkm, больших изменений мы не делали - было улучшено то, что сделал medar. Это он говорил про оптимизацию, но будут ли это частичные изменения, или же предстоит серьёзный рефакторинг - сказать сложно, мы с Dayver'ом этот вопрос не рассматривали.]]> Mo, 23 Mär 2009 05:48:28 -0000 esclkm Mo, 23 Mär 2009 05:00:46 -0000 Dayver
его тплка

его тпл

Эти два файла так сказать наиболее показательны в плане применения логики в шаблонизаторе потому код остальных переделаных файлов приводить не буду. Посему просьба к медару потестить скорость так сказать переделаного шаблонизатора с реальным примером применения. Если не возникнет замечаний то и шаблонизатор и части переделаной админки пойдут в транк.[/][/][/]]]>
Mo, 23 Mär 2009 03:47:28 -0000
Sergeich Mo, 23 Mär 2009 03:37:40 -0000 dervan Dayver'ом представляем результаты практического применения XTemplate с IF'ами - из опыта работы Dayver'а по выносу HTML из админки.

Предлагаем для тестирования доработанный XTemplate: xtemplate.class.php_57.zip

Просьба к medar'у - посмотреть внесённые изменения, может будут какие замечания. Существенных изменений не вносилось, все исправления - простые.


1.
Использование переменных bool приводило к ошибке.

Пример.
Переменная в коде PHP:
$is_test = false;
Условие в шаблоне:
<!-- IF !{PHP.is_test} -->not is_test<!-- ENDIF -->
В результате - ошибка:
Parse error: syntax error, unexpected ')' in mysite.com/system/xtemplate.class.php(781) : eval()'d code on line 1

Причина - в XTemplate не было поддержки bool, они не нужны в шаблонах. Это мы поправили, тут вроде обсуждать нечего - bool в условиях использоваться будут.


2.
Исходя из практики, кроме короткого варианта с IF нужен ещё и вариант с ELSE. Такой вариант добавлен, сейчас в шаблоне возможны такие условия:
<!-- IF <'if' statement> -->['then' content]<!-- ENDIF -->
<!-- IF <'if' statement> -->['then' content]<!-- ELSE -->['else' content]<!-- ENDIF -->

Реализация получилась простой - в коде medar'а исправлено 2 строки, и добавлена одна необязательная (в стиле уже сделанного им кода).

Немного усложнился regex, но в целом применение такой конструкции должно давать выигрыш во времени обработки.

Примеры из этого топика.

# medar :
<!-- IF strpos({PAGE_TITLE}, "жуй") -->
{PAGE_TITLE|str_replace('жуй', '', %s)} ц-ц-ц как нехорошо
<!-- ENDIF -->
<!-- IF !strpos({PAGE_TITLE}, "жуй") -->
{PAGE_TITLE}
<!-- ENDIF -->

# dervan :
<!-- IF {PHP.usr.id} < 1 -->
вы - гость
<!-- ENDIF -->
<!-- IF {PHP.usr.id} >= 1 -->
вы - зарегистрированный посетитель
<!-- ENDIF -->

В каждом из этих примеров парсится 2 условия IF, т.е. regex обрабатывается 2 раза. Кроме того, в 1-м примере в условиях IF дважды вызывается функцища strpos(), а во 2-м примере - дважды парсится тег {PHP.usr.id}. Если переписать эти примеры с ELSE, они будут работать быстрее, хотя regex для реализации ELSE чуть сложнее.

<!-- IF strpos({PAGE_TITLE}, "жуй") -->
{PAGE_TITLE|str_replace('жуй', '', %s)} ц-ц-ц как нехорошо
<!-- ELSE -->
{PAGE_TITLE}
<!-- ENDIF -->

<!-- IF {PHP.usr.id} < 1 -->
вы - гость
<!-- ELSE -->
вы - зарегистрированный посетитель
<!-- ENDIF -->

В шаблоне для админки, который переделал Dayver, подобных конструкций - подавляющее большинство, поэтому исходя из практики выгоднее использовать вариант с ELSE.

Предлагаем оставить в XTemplate вариант с поддержкой ELSE.


3.
Проблема из-за копирования глобальных переменных методом scan_globals(), в результате чего в шаблоне не видны глобальные переменные, присвоенные после создания объекта XTemplate. На практике это создаёт большие сложности.

Пример.
Эту переменную $lincif_conf можно использовать в шаблоне:
$lincif_conf = sed_auth('admin', 'a', 'A');
$t = new XTemplate(sed_skinfile('admin.inc', false, true));
А эту переменную $lincif_conf использовать в шаблоне невозможно:
$t = new XTemplate(sed_skinfile('admin.inc', false, true));
$lincif_conf = sed_auth('admin', 'a', 'A');

Для решения проблемы удалось легко реализовать то, о чём говорил medar:
# medar : Надо будет решить эту проблему по-другому - вообще отказаться от scan_globals(), а при парсинге тэгов {PHP.xxx} обращаться непосредственно к $GLOBALS.

Из метода scan_globals() убрано копирование $GLOBALS:
	public function scan_globals () {
		if ($this->force_globals && ini_get('auto_globals_jit') == true) {
			$tmp = $_SERVER;
			$tmp = $_ENV;
			$tmp = $_REQUEST;
			unset($tmp);
		}
	}

А в методе parse() присваивается указатель:
$this->vars['PHP'] =& $GLOBALS;
и уничтожается перед выходом из parse(). Т.е. $GLOBALS теперь не копируется, и в то же время нет опасности уничтожения $GLOBALS через указатель $this->vars['PHP'] - этот указатель теперь не существует вне метода parse().

Возникавшая из-за работы через указатель напрямую с $GLOBALS накладка, которая проявлялась в копировании в пустые строки умолчательных значений, определённых define(), в методе parse() была исправлена. Сообщение об этой накладке:
# dervan : К тому же есть нюансы при работе метода parse(). Например, такой код в конце system/header.php, плюс тег {PHP.TEST_DEFINE} в header.tpl:
define('TEST_DEFINE', 'test_define');
$TEST_DEFINE = '';

$t->parse("HEADER");
$t->out("HEADER");

echo $TEST_DEFINE, '<br />';
В случае оригинального scan_globals() глобальная переменная $TEST_DEFINE останется пустой строкой (значение будет присвоено её копии), а с переделанным scan_globals() после работы парсера $TEST_DEFINE получит значение 'test_define'.

Из метода get_vars_value() аналогичный код был удалён - пустую строку, которая пойдёт на проверку в IF, не надо подменять умолчательным значением.

Остальной код в parse() был внимательно изучен, других накладок из-за работы через указатель напрямую с $GLOBALS не обнаружено.

Предлагаем оставить в XTemplate этот вариант без копирования $GLOBALS.]]>
Mo, 23 Mär 2009 02:50:33 -0000
Dayver medar а как с логикой типа else? Не получилось реализовать? Или уже есть такое(если есть то моно примерчик?)?]]> Mo, 16 Mär 2009 23:44:30 -0000 medar Mo, 16 Mär 2009 04:31:09 -0000 dervan # Ratibor : Осталось только доработать, чтоб все лишнее вырезалось если условие совпадает.
А у medar'а для этого всё готово.
				$short_tpl_block = $ifs[2][$i];
...
				if(!$if_result)
				{
					// delete this IF block with all content
					$copy = str_replace($full_tpl_block, "", $copy);
				}
				else
				{
					// delete only IF construction
					// ? delete or not - speed ?
				}

Осталось выяснить, как сильно упадёт скорость работы парсера, если коментарий
					// ? delete or not - speed ?
заменить на код
					$copy = str_replace($full_tpl_block, $short_tpl_block, $copy);

Delete or not delete? :)]]>
So, 15 Mär 2009 18:43:27 -0000
Ratibor Осталось только доработать, чтоб все лишнее вырезалось если условие совпадает.]]> So, 15 Mär 2009 14:36:47 -0000 dervan # Sergeich : ... если на сайт зашёл гость - показывается один блок, а если юзер - другой.
<!-- IF {PHP.usr.id} < 1 -->
вы - гость
<!-- ENDIF -->
<!-- IF {PHP.usr.id} >= 1 -->
вы - зарегистрированный посетитель
<!-- ENDIF -->
]]>
So, 15 Mär 2009 06:17:47 -0000
Sergeich So, 15 Mär 2009 05:25:16 -0000 Ratibor # medar : Использование.

Итак, у нас в шаблонах стала доступна вот такая вот конструкция:
<!-- IF <if_statement> -->
этот текст будет показан если <if_statement> является true
<!-- ENDIF -->

<if_statement> - это логическое php-выражение, только вместо переменных используются tpl-тэги (в том числе и глобальные!)

Примеры:
<!-- IF {PHP.usr.profile.user_name} == "admin" -->
привет, админ !
<!-- ENDIF -->

Попробовал сейчас добавить логику в шаблон.
Работает вроде все нормально, но есть небольшое замечание.

Чтоб было более понятно, объясню на приведенном выше примере:
если имя не admin, т.е. условие не срабатывает, то все нормально,
всмысле в выходном коде это все вырезается,
но если это admin, т.е. условие срабатывает, то в выходном коде мы видим следующее:
<!-- IF admin == "admin" -->
привет, админ !
<!-- ENDIF -->

Не порядок, надо бы вырезать вот это:
<!-- IF admin == "admin" -->
<!-- ENDIF -->
]]>
So, 15 Mär 2009 04:06:11 -0000
medar Приличия соблюдены, сейчас закоммичу.]]> Di, 10 Mär 2009 15:28:08 -0000 Dayver # medar : Логику написали, теперь регулярки поправить внутри и все ок будет.
Тогда может уже закинешь в транк хотя бы с прикрученой логикой(в англ ветке отписался = офф. часть выполнил .... там молчат - знач моно закидывать!)? .... а с регулярками уже как нить опосля!?]]>
Di, 10 Mär 2009 04:51:26 -0000
dervan # medar : dervan
Надо будет решить эту проблему по-другому - вообще отказаться от scan_globals(), а при парсинге тэгов {PHP.xxx} обращаться непосредственно к $GLOBALS.

Кстати, medar, если так переделывать, то вот от таких накладок при работе parse() всё равно не избавишься:
# dervan : К тому же есть нюансы при работе метода parse(). Например, такой код в конце system/header.php, плюс тег {PHP.TEST_DEFINE) в header.tpl:
define('TEST_DEFINE', 'test_define');
$TEST_DEFINE = '';

$t->parse("HEADER");
$t->out("HEADER");

echo $TEST_DEFINE, '<br />';
В случае оригинального scan_globals() глобальная переменная $TEST_DEFINE останется пустой строкой (значение будет присвоено её копии), а с переделанным scan_globals() после работы парсера $TEST_DEFINE получит значение 'test_define'.

А действия, подобные
$t->assign('PHP', 'test_assign');
это совершенно идиотские действия, что со старым scan_globals(), что с переделанным - из того же разряда, что и доступ к глобальным переменным через $t->vars. Так что если отказываться от локальной копии $GLOBALS, пожалуй нет смысла совсем убирать scan_globals(), проще его подправить.]]>
Di, 10 Mär 2009 04:05:57 -0000
medar ну так может посмотрим пристально на другие шаблонизаторы не, проще обустроить xtemplate.
Логику написали, теперь регулярки поправить внутри и все ок будет.]]>
Di, 10 Mär 2009 03:30:59 -0000
esclkm тем более что у нас появился специалист по xtemplate - поэтому возможно скоро мы увидим medarTemplate]]> Di, 10 Mär 2009 02:55:59 -0000 Sergeich Di, 10 Mär 2009 01:47:38 -0000 dervan Di, 10 Mär 2009 00:44:57 -0000 medar Если человек копался в коде и знает, что существует $t->vars, то он должен понимать, что брать оттуда данные, а не из например $cfg[] напрямую - это оперировать гланды через задницу. :)[/]]]> Di, 10 Mär 2009 00:08:49 -0000 Trustmaster
ЗЫ: я тут глянул еще раз на код XTemplate. Возникает законный вопрос "неужели это всё хоть сколько-нибудь работоспособно" :-D]]>
Di, 10 Mär 2009 00:08:27 -0000
dervan # medar : dervan
Надо будет решить эту проблему по-другому - вообще отказаться от scan_globals(), а при парсинге тэгов {PHP.xxx} обращаться непосредственно к $GLOBALS.
Тогда посыпятся плагины, которые используют $t->vars.]]>
Mo, 09 Mär 2009 23:42:51 -0000
medar dervan
Да, наверное, лучше убрать.
Надо будет решить эту проблему по-другому - вообще отказаться от scan_globals(), а при парсинге тэгов {PHP.xxx} обращаться непосредственно к $GLOBALS.]]>
Mo, 09 Mär 2009 22:38:55 -0000
Sergeich Mo, 09 Mär 2009 22:18:30 -0000 medar UPD
Провел тестирование на линуксовом серваке. Цифры стали логичными и предсказуемыми.
Все-таки php под виндой - это странная вещь. :)

Старый xtemplate
Requests per second: 16.30 [#/sec] (mean)
Time per request: 245.377 [ms] (mean)
Time per request: 61.344 [ms] (mean, across all concurrent requests)
Transfer rate: 123.87 [Kbytes/sec] received

Новый xtemplate + хак dervan (здесь и далее) шаблон без логики
Requests per second: 17.47 [#/sec] (mean)
Time per request: 229.007 [ms] (mean)
Time per request: 57.252 [ms] (mean, across all concurrent requests)
Transfer rate: 132.60 [Kbytes/sec] received

Новый xtemplate, шаблон с логикой, 1 условие
Requests per second: 16.78 [#/sec] (mean)
Time per request: 238.446 [ms] (mean)
Time per request: 59.611 [ms] (mean, across all concurrent requests)
Transfer rate: 128.34 [Kbytes/sec] received

Новый xtemplate, шаблон с логикой, 25 условий
Requests per second: 15.60 [#/sec] (mean)
Time per request: 256.485 [ms] (mean)
Time per request: 64.121 [ms] (mean, across all concurrent requests)
Transfer rate: 119.25 [Kbytes/sec] received]]>
Mo, 09 Mär 2009 22:13:47 -0000
dervan # medar : Кто-нибудь может прокомментировать, что происходит ? :) Как-то это всё нелогично..
Получается, что по ссылке на $GLOBALS парсинг работает дольше, чем при использовании локальной копии.

================

medar, я извиняюсь - не пойдёт этот хак scan_globals().

Во-первых, я не учёл, что после такой переделки весь $GLOBALS можно убить методом assign(), например так:
$t->assign('PHP', 'test_assign');
$t->assign(array('PHP' => 'test_assign_array'));

Добавлял в конец system/header.php такой код, всё так и есть - $GLOBALS уничтожается:
$t->assign('PHP', 'test_assign');

$t->parse("HEADER");
$t->out("HEADER");

echo '<pre>', strip_tags(print_r($GLOBALS, true)), '</pre>';

В принципе, можно в методе assign() проверять ключ на значение 'PHP' и не присваивать в этом случае значение. Но $GLOBALS всё равно можно убить напрямую через vars:
$t->vars['PHP'] = 'test_assign';
А vars - public, и менять это нельзя, могут отказаться работать какие-нибудь плагины.

К тому же есть нюансы при работе метода parse(). Например, такой код в конце system/header.php, плюс тег {PHP.TEST_DEFINE) в header.tpl:
define('TEST_DEFINE', 'test_define');
$TEST_DEFINE = '';

$t->parse("HEADER");
$t->out("HEADER");

echo $TEST_DEFINE, '<br />';
В случае оригинального scan_globals() глобальная переменная $TEST_DEFINE останется пустой строкой (значение будет присвоено её копии), а с переделанным scan_globals() после работы парсера $TEST_DEFINE получит значение 'test_define'.

И вдобавок по твоим тестам с переделанным scan_globals() парсер работает медленнее. Так что в сад. :)

Ещё раз извиняюсь.]]>
Mo, 09 Mär 2009 22:08:14 -0000
medar
Бенчмарк на локалхосте, php под виндой.

ab -c 4 -n1000 "http://localhost/svn.cotonti.com/trunk/page.php?id=2"

Новый xtemplate, два логических блока в tpl.
Requests per second: 8.48 [#/sec] (mean)
Time per request: 471.563 [ms] (mean)
Time per request: 117.891 [ms] (mean, across all concurrent requests)
Transfer rate: 64.49 [Kbytes/sec] received

Новый xtemplate, без логических блоков.
Requests per second: 8.81 [#/sec] (mean)
Time per request: 454.188 [ms] (mean)
Time per request: 113.547 [ms] (mean, across all concurrent requests)
Transfer rate: 66.25 [Kbytes/sec] received

Разницы практически нет, ок.

Теперь старый xtemplate
Requests per second: 13.06 [#/sec] (mean)
Time per request: 306.188 [ms] (mean)
Time per request: 76.547 [ms] (mean, across all concurrent requests)
Transfer rate: 99.96 [Kbytes/sec] received

Результат, мягко говоря, обескураживает. Старый более чем в полтора раза быстрее.
Начал разбираться в чем дело.

Новый xtemplate, но со старой функцией scan_globals() (без хака dervan)
Requests per second: 9.41 [#/sec] (mean)
Time per request: 424.875 [ms] (mean)
Time per request: 106.219 [ms] (mean, across all concurrent requests)
Transfer rate: 70.83 [Kbytes/sec] received

Кто-нибудь может прокомментировать, что происходит ? :) Как-то это всё нелогично..

Надо проштудировать хабр, вроде бы кто-то уже сталкивался с подобной ситуацией.]]>
Mo, 09 Mär 2009 15:35:27 -0000
Dayver Mo, 09 Mär 2009 08:42:48 -0000 dervan # medar : Да, я тоже хотел сделать ссылкой, но меня насторожил код ниже:
case 'GLOBALS':
// Stop Recursion
break;
Наверное он там не просто так.
...
Это ссылка в $GLOBALS на самого себя - она там ещё с PHP3, когда ещё в языке ссылки не поддерживались. Проверка - чтобы не зацикливаться при копировании.

Про этот хак в XTemplate подробно рассказано здесь.]]>
Mo, 09 Mär 2009 08:30:45 -0000
Sergeich Mo, 09 Mär 2009 08:16:52 -0000 medar
case 'GLOBALS':
// Stop Recursion
break;
Наверное он там не просто так.

Вроде со ссылкой на глаз все работает.
Но print_r($this->vars); показывает вот что:
Array
(
    [PHP] => Array
        (
            [GLOBALS] => Array
 *RECURSION*
Я такое вижу в первый раз, не знаю, чем это может нам грозить :)]]>
Mo, 09 Mär 2009 08:08:42 -0000
dervan # medar : Вообще, когда я увидел ужас, летящий на крыльях ночи в xtemplate в виде массы регулярок и дублирования всех переменных движка, ...
От дублирования $GLOBALS можно избавиться, поправив в XTemplate метод scan_globals():
	public function scan_globals ()
	{
		if ($this->force_globals && ini_get('auto_globals_jit') == true)
		{
			$tmp = $_SERVER;
			$tmp = $_ENV;
			$tmp = $_REQUEST;
			unset($tmp);
		}
		$this->vars['PHP'] =& $GLOBALS;
	}
]]>
Mo, 09 Mär 2009 07:33:20 -0000