pdoTools::getChunk -обработка прочих прейсхолдеров
Вопрос такой. pdoTools::getChunk() самостоятельно обрабатывает только те плейсхолдеры, которые указаны вторым параметром? Все остальные плейсхолдеры (за исключением лексикона) обрабатывает стандартный парсер modx?
И для того, чтобы pdoTools::getChunk() самостоятельно обработал все плейсхолдеры modx (не передавая их стандартному парсеру), необходимо:
а) либо вторым параметром передавать что-то вроде array_merge($placeholders, $modx->placeholders);
б) либо перегрузить метод pdoTools::getChunk(), добавив обработку плейсхолдеров modx, не указанных вторым параметром
Так?
И для того, чтобы pdoTools::getChunk() самостоятельно обработал все плейсхолдеры modx (не передавая их стандартному парсеру), необходимо:
а) либо вторым параметром передавать что-то вроде array_merge($placeholders, $modx->placeholders);
б) либо перегрузить метод pdoTools::getChunk(), добавив обработку плейсхолдеров modx, не указанных вторым параметром
Так?
Комментарии: 18
Да.
Можно еще использовать fastMode (третий параметр) — тогда тоже будет использован modX::placeholders.
Можно еще использовать fastMode (третий параметр) — тогда тоже будет использован modX::placeholders.
Режим fastMode не использую в сабжевых целях, т.к. не обрабатываются вложенные чанки и прочие теги modx.
Провёл тест суммарного времени выполнения методов pdoTools::getChunk() на странице с большим числом вызовов чанков. Результаты получились такие:
То, что 2-й вариант отработал вдвое быстрее 1-го варианта, можно объяснить тем, что у меня в большинстве чанков размещены только те плейхолдеры, которые передаются вторым параметром в pdoTools::getChunk():
— в первом варианте для каждого вызова pdoTools::getChunk() идёт вызов метода str_replace для большого числа плейсхолдеров (из которых в чанке содержатся только некоторые), но при этом до стандартного парсера modx дело не доходит;
— во 2-м варианте метод str_replace вызывается только для малого числа плейсхолдеров, которые заведомо присутствуют в чанках, при этом стандартный парсер modx вызывается только для единичных чанков, в которых присутствуют плейсхолдеры, не переданные вторым параметром в pdoTools::getChunk().
Таким образом, вызовы st_replace для большого числа плейсхолдеров по времени вдвое перевешивают редкие вызовы стандартного парсера modx.
Но не пойму я, почему 3-й вариант (fastMode c «ручной» обработкой всех плейсхолдеров из $modx->placeholders) выполняется в 5 раз быстрее, чем 1-й вариант. Ведь в обоих этих случаях выполняется «ручная» обработка всех плейсхолдеров (переданных 2-м параметром + $modx->placeholders) и в обоих случаях до стандартного парсера modx дело не доходит.
Провёл тест суммарного времени выполнения методов pdoTools::getChunk() на странице с большим числом вызовов чанков. Результаты получились такие:
1) $modx->pdoTools->getChunk($chunkName, array_merge($placeholders, $modx->placeholders), false); // время: X сек
2) $modx->pdoTools->getChunk($chunkName, $placeholders, false); // время: 0.5X сек
3) $modx->pdoTools->getChunk($chunkName, $placeholders, true); // время: 0.2X сек
То, что 2-й вариант отработал вдвое быстрее 1-го варианта, можно объяснить тем, что у меня в большинстве чанков размещены только те плейхолдеры, которые передаются вторым параметром в pdoTools::getChunk():
— в первом варианте для каждого вызова pdoTools::getChunk() идёт вызов метода str_replace для большого числа плейсхолдеров (из которых в чанке содержатся только некоторые), но при этом до стандартного парсера modx дело не доходит;
— во 2-м варианте метод str_replace вызывается только для малого числа плейсхолдеров, которые заведомо присутствуют в чанках, при этом стандартный парсер modx вызывается только для единичных чанков, в которых присутствуют плейсхолдеры, не переданные вторым параметром в pdoTools::getChunk().
Таким образом, вызовы st_replace для большого числа плейсхолдеров по времени вдвое перевешивают редкие вызовы стандартного парсера modx.
Но не пойму я, почему 3-й вариант (fastMode c «ручной» обработкой всех плейсхолдеров из $modx->placeholders) выполняется в 5 раз быстрее, чем 1-й вариант. Ведь в обоих этих случаях выполняется «ручная» обработка всех плейсхолдеров (переданных 2-м параметром + $modx->placeholders) и в обоих случаях до стандартного парсера modx дело не доходит.
Метод fastProcess не использует makePlaceholders и не генерирует большой массив плейсхолдеры-значения, как в первом случае. Чем больше массив, тем дольше подстановка.
В третьем вызове идёт точечная проверка ключей в modX::placeholders — это гораздо быстрее.
Можно попробовать сделать двойную обработку:
В третьем вызове идёт точечная проверка ключей в modX::placeholders — это гораздо быстрее.
Можно попробовать сделать двойную обработку:
// обработка всех переданных плейсхолдеров с условиями
$html = $modx->pdoTools->getChunk($chunkName, $placeholders, false);
// подстановка из modX::placeholders
$html = $modx->pdoTools->fastProcess($html);
В третьем вызове идёт точечная проверка ключей в modX::placeholders — это гораздо быстрее.
Хотел было спросить, почему такой же «точечный» метод (на основе collectElementTags) не реализован в отношении плейсхолдеров, передаваемых вторым параметром. Но здесь всё ясно: каждый из плейсхолдеров, передаваемых вторым параметром, заведомо присутствует в чанке. Поэтому, быстрее будет выполнить str_replace для массива всех этих плейсхолдеров. Что касается $modx->placeholders, то в большинстве чанков они либо будут отсутствовать, либо будет присутствовать только малая часть из них. Поэтому, обработку плейсхолдеров $modx->placeholders быстрее выполнить «по факту» (точечно).
Можно попробовать сделать двойную обработку:
// обработка всех переданных плейсхолдеров с условиями $html = $modx->pdoTools->getChunk($chunkName, $placeholders, false); // подстановка из modX::placeholders $html = $modx->pdoTools->fastProcess($html);
А вот здесь идея не ясна. В первом комментарии идёт речь об обработке плейсхолдеров с условиями. О каких условиях речь? Здесь первый вызов getChunk так и так обработает все плейсхолдеры, включая $modx->placeholders (путём вызова стандартного парсера $modx). И вызов fastProcess уже будет не нужен (отработает «вхолостую»).
===================================================================================
Сабжевая задача выглядит следующим образом:
а) плейсхолдеры, передаваемые 2-параметром, должны быть обработаны как есть (через массив «плейсхолдеры-значения»), т.к. все они присутствуют в чанке
б) стандартные плейсхолдеры $modx->placeholders обрабатываются «точечно», т.к. в чанке присутствует только малая часть из них (либо отсутствуют вообще)
в) если после обработки в чанке остаются какие-либо теги modx, управление передаётся стандартному парсеру $modx
Сейчас (без переделки кода) возможно реализовать только такие комбинации:
— либо (а + в)
— либо (а + б) // fastMode
====================================================================================
Один из вариантов — методу getChunk вместо параметра fastMode передавать 2 параметра:
— modxPlaceholders — обрабатывать ли $modx->placeholders (обработка выполняется точечно)
— modxParser — передавать ли обработку стандартному парсеру modx, если остаются теги
А алгоритм будет таким:
1. Выполняется обработка quick placeholders, standard placeholders, lexicon placeholders (как сейчас)
2. Если остаются теги и [modxPaceholders = true], выполняется «точечная» обработка $modx->placeholders
3. Если остаются теги и [modxParser = true], вызывается стандартный парсер modx
Такой вариант является более гибким и более быстрым (для случаев, когда чанк содержит стандартные плейсхолдеры modx), а режим fastMode будет равносилен набору параметров [modxPlaceholders = true], [modxParser = false].
==============================================================================
Другой вариант: оставляем параметр fastMode, но при этом «точечная» обработка $modx->placeholders выполняется всегда (если остаются теги modx). При [fastMode = true] обработка стандартному парсеру не передаётся никогда, при [fastMode = false] и при наличии тегов modx обработка передаётся стандартному парсеру.
В данном варианте параметр fastMode целесообразно будет переименовать, например, в useModxParser.
Но я за параметры modxPlaceholders и modxParser — это более гибкий вариант.
А вот здесь идея не ясна.… Здесь первый вызов getChunk так и так обработает все плейсхолдеры, включая $modx->placeholdersНе обработает. Эти плейсхолдеры останутся и будут процесситься уже потом, при выводе страницы.
Причем, не str_replace, а созданием modTag и вызовом modTag::process(), что будет дольше.
Все остальное — ты там сам усложняй наздоровье, у меня на это времени нет.
пункт
2. Если остаются теги и [modxPaceholders = true], выполняется «точечная» обработка $modx->placeholdersчитать так:
2. Если остаются теги '[[+', '[[!+' и [modxPaceholders = true], выполняется «точечная» обработка $modx->placeholders
Учитывая, что время работы парсера в сабжевых тестах не учитывается, получаем:
Интерес здесь представляют варианты 1,2,4 (чанк обрабатывается полностью). Вариант 4 по скорости лидирует.
1)// время: X сек (чанк обрабатывается полностью)$modx->pdoTools->getChunk($chunkName, array_merge($placeholders, $modx->placeholders), false);
2)// время: 0.5X сек + время обработки $modx->placeholders парсером modx (чанк обрабатывается полностью)$modx->pdoTools->getChunk($chunkName, $placeholders, false);
3)// время: 0.2X сек (вложенные чанки и прочие теги не обрабатываются)$modx->pdoTools->getChunk($chunkName, $placeholders, true);
4)// время: 0,5X (чанк обрабатывается полностью)$html = $modx->pdoTools->getChunk($chunkName, $placeholders, false); $html = $modx->pdoTools->fastProcess($html);
Интерес здесь представляют варианты 1,2,4 (чанк обрабатывается полностью). Вариант 4 по скорости лидирует.
5)
$modx->getChunk($chunkName, $placeholders);
// время: 1.3Х-1.6X сек (чанк обрабатывается полностью)Не обработает. Эти плейсхолдеры останутся и будут процесситься уже потом, при выводе страницы.
Причем, не str_replace, а созданием modTag и вызовом modTag::process(), что будет дольше.
Проверил — не остаются:
$html = $modx->pdoTools->getChunk($chunk, $placeholders, false);
func_dumper($html, true); // все глобальные плейсхолдеры из $modx->placeholders уже подставлены (в $placeholders их нет)
$html = $modx->pdoTools->fastProcess($html);
И pdoTools::fastProcess() отрабатывает уже впустую.
Вот последний кусок метода getChunk:
if (strpos($content, '[[') !== false) {
return $fastMode
? $this->fastProcess($content, $properties)
: $chunk['object']->process($properties, $content); // вызывается парсер modx, который обрабатывает все оставшиеся теги, в т.ч. $modx->placeholders
}
Значит, я не прав. В любом случае, там обработка через modPlaceholderTag::getContent(), а не через str_replace.
Так какой из этого всего следует вывод? Что метод pdoTools::getChunk() c fastMode быстрее, но не всё обрабатывает, а без него медленнее?
Так какой из этого всего следует вывод? Что метод pdoTools::getChunk() c fastMode быстрее, но не всё обрабатывает, а без него медленнее?
Так какой из этого всего следует вывод? Что метод pdoTools::getChunk() c fastMode быстрее, но не всё обрабатывает, а без него медленнее?
Да, fastMode обрабатывает $modx->placeholders быстрее, но вырезает все прочие теги.
Получается, что вот эти действия:
а) плейсхолдеры, передаваемые 2-м параметром, обрабатываются как есть (через массив «плейсхолдеры-значения»);
б) стандартные плейсхолдеры $modx->placeholders обрабатываются «точечно», т.к. в большинстве чанков присутствует только малая часть из них (либо отсутствуют вообще);
в) если после обработки в чанке остаются какие-либо теги modx, управление передаётся стандартному парсеру $modx
на базе имеющихся методов pdoTools никак не реализовать (без коррекции кода)?Если нет, состряпаю что-нибудь сам.
Думаю, можно добавить обработку modX::placeholders в getChunk. Там уже есть работа с % и ~, пусть будет и ++.
Состряпал тест:
Со старой передачей в парсер выходит 0.25 сек, с новой — 0.026. Надеюсь, глюков это не прибавит.
Состряпал тест:
$pdo = $modx->getService('pdoFetch');
$time = microtime(true);
for ($i = 1; $i <= 1000; $i++) {
$res = $pdo->getChunk('@INLINE [[++site_name]]', array(), false);
}
echo microtime(true) - $time;
Со старой передачей в парсер выходит 0.25 сек, с новой — 0.026. Надеюсь, глюков это не прибавит.
Попробуй вот эту версию класса, в ней добавлена обработка ++ и *, ну и переписан метод fastProcess().
Если нормально будет у тебя работать (у себя я уже проверил), то выпущу бету версию.
Если нормально будет у тебя работать (у себя я уже проверил), то выпущу бету версию.
Проверил. Всё, что реализовано, — работает нормально (++, *, ~, + передаваемые, + из $modx->placeholders).
[[% ]] — не проверял.
В режиме fastMode не работает следующее:
а) вызовы чанков
б) теги, содержащие вложенные теги (насколько я понимаю, вложенные теги подставляются, но затем внешний тег вырезается)
в) ссылки с параметрами, например:
[[~190? &p1=`111` &p2=`222`]]
[[% ]] — не проверял.
В режиме fastMode не работает следующее:
а) вызовы чанков
б) теги, содержащие вложенные теги (насколько я понимаю, вложенные теги подставляются, но затем внешний тег вырезается)
в) ссылки с параметрами, например:
[[~190? &p1=`111` &p2=`222`]]
Так и должно быть.
fastMode на то и fast, что вырезает все лишнее. Для него нужно подготовить чанк, убрать все условия и вложенные вызовы. Например в комментариях к тикетам его просто необходимо использовать, иначе тормоза.
Лично я использую его часто, но по умолчанию он отключен.
fastMode на то и fast, что вырезает все лишнее. Для него нужно подготовить чанк, убрать все условия и вложенные вызовы. Например в комментариях к тикетам его просто необходимо использовать, иначе тормоза.
Лично я использую его часто, но по умолчанию он отключен.
Стоп. Подстановка системных плейсхолдеров из $modx->placeholders не работает.
Ставим в чанке, например, [[+modx.user.id]], указываем fastMode, делаем print_r — в результате вызов [[+modx.user.id]] остаётся. Если отменить fastMode — значение подставляется нормально (парсер modx).
Ставим в чанке, например, [[+modx.user.id]], указываем fastMode, делаем print_r — в результате вызов [[+modx.user.id]] остаётся. Если отменить fastMode — значение подставляется нормально (парсер modx).
в строках 347 и 349 нужно плюсик убрать:
case '+':
if (isset($this->modx->placeholders['+'.$value])) {
$src[] = $v[0];
$dst[] = $this->modx->placeholders['+'.$value];
$processed = true;
}
break;
++ тоже не работает. Только подстановка системных настроек вроде и не реализована в коде.
P.S. * и ~ (без параметров) — работают. Точно.
P.S. * и ~ (без параметров) — работают. Точно.
Авторизуйтесь или зарегистрируйтесь, чтобы оставлять комментарии.