LINUX.ORG.RU

Повторное использование куска кода (шаблона) в цикле

 


1

2

Сильно упрощённый пример.

Используются нативные шаблоны PHP.

Есть основной шаблон, в нём в цикле для каждого элемента в массиве выполнить код дополнительного шаблона. Если наиболее тупо то:

<ul>
  <?php foreach($this->items as $this->item): ?>
    <?php include('templates/items.php'); ?>
  <?php endforeach; ?>
</ul>

Сам templates/item.php например таков:

    <li><?= $this->item ?></li>

Но в цикле инклудить многократно файл не очень эффективно. Это ведь тут пример упрощённый, реальный код сложнее.

Другой вариант, чтобы исключить многократное подключение одного и того же файла это:

<ul>
  <?php foreach($this->items as $this->item): ?>
    <?php $this->templaPart('templates/items.php'); ?>
  <?php endforeach; ?>
</ul>

где templatePart() это

    public function templatePart($template)
    {
        if(isset(!$this->cached_templates[$template]))
        {
            $this->cached_templates[$template] = file_get_contents($template);
        }
        eval('?>'. $this->cached_template[$template]);
    }

Второй вариант уже поэффективнее, но eval...

Есть ли что получше без использования сторонних библиотек?

Deleted

Последнее исправление: pyroman (всего исправлений: 3)
Ответ на: комментарий от no-such-file

Сам себя обманул?

Блин, я уже запутался :D Просто у меня разные версии php и они ведут себя по разному. Я сейчас сравнил ini файлы, obpache выключен у обоих, но в php 5.5 был включен xdebug, а он вносит задержки. Выключил, прогнал тесты заново под сервером (fcgi):

## предварительный eval
2018-05-19 11:14:59: (mod_fastcgi.c.2673) FastCGI-stderr: __DEBUG__ TIME: 0.38172316551208 MEMORY: 216160 - 22110832
2018-05-19 11:15:03: (mod_fastcgi.c.2673) FastCGI-stderr: __DEBUG__ TIME: 0.37619209289551 MEMORY: 216160 - 22110832
2018-05-19 11:15:07: (mod_fastcgi.c.2673) FastCGI-stderr: __DEBUG__ TIME: 0.28086686134338 MEMORY: 216160 - 22110832

## тупо eval в цикле
2018-05-19 11:15:23: (mod_fastcgi.c.2673) FastCGI-stderr: __DEBUG__ TIME: 1.8249011039734 MEMORY: 216152 - 20108768
2018-05-19 11:15:27: (mod_fastcgi.c.2673) FastCGI-stderr: __DEBUG__ TIME: 1.7442200183868 MEMORY: 216152 - 20108768
2018-05-19 11:15:31: (mod_fastcgi.c.2673) FastCGI-stderr: __DEBUG__ TIME: 1.8100001811981 MEMORY: 216152 - 20108768

## include в цикле
2018-05-19 11:15:41: (mod_fastcgi.c.2673) FastCGI-stderr: __DEBUG__ TIME: 0.42358207702637 MEMORY: 216144 - 20106984
2018-05-19 11:15:45: (mod_fastcgi.c.2673) FastCGI-stderr: __DEBUG__ TIME: 0.41076493263245 MEMORY: 216144 - 20106984
2018-05-19 11:15:47: (mod_fastcgi.c.2673) FastCGI-stderr: __DEBUG__ TIME: 0.4132399559021 MEMORY: 216144 - 20106984

Вобщем да, тут вариант выше всё же чуть быстрее чем include, но несущественно.

include берут из кэша.

Я у них не нашёл в документации как работает кеширование для include. То есть include обращается к файлу только один раз? Я посмотрел ini файл, opcache выключен.
Ещё меня удивило отсутствие существенного влияния на потребление памяти, хотя по идее должно в случае include, ведь он судя по описанию как бы вставляет содержимое php скрипта в текущий скрипт.

Deleted
()
Ответ на: комментарий от Deleted

Я у них не нашёл в документации как работает кеширование для include. То есть include обращается к файлу только один раз?

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

no-such-file ★★★★★
()
Последнее исправление: no-such-file (всего исправлений: 1)
Ответ на: комментарий от Deleted

включил opcache, не повлияло, результаты такие же.

А ты попробуй цикл вынести из php в bash, например жахни 100000 запросов через ab.

no-such-file ★★★★★
()
Ответ на: комментарий от no-such-file

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

Не, с этим понятно, меня больше удивило что include при повторном использовании работает так же эффективно как просто вызов существующей функции. Я ожидал гораздо больший расход памяти при инклудинге одного и того же кода в цикле.

Deleted
()
Ответ на: комментарий от no-such-file

А ты попробуй цикл вынести из php в bash, например жахни 100000 запросов через ab.

Ну это да, должно ускорить конечно...

Deleted
()
Ответ на: комментарий от Deleted

Я ожидал гораздо больший расход памяти при инклудинге одного и того же кода в цикле.

Непонятно почему? Даже если предположить, что каждый раз для чтения что-то там выделяется, то предыдущие буферы должны освобождаться.

no-such-file ★★★★★
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.