Как организован вывод списка в PHP-шаблонах

Раздел: Веб-разработка на PHP -> Шаблонизаторы

Основные методы отображения списков

Какое решение считается наиболее эффективным для вывода списка в современных проектах?

Наиболее эффективным считается использование шаблонизатора Twig с циклом for. Он обеспечивает четкое разделение логики и представления, автоматическое экранирование и гибкие фильтры. Рассмотрим пример вывода списка пользователей.

Код контроллера (PHP):


// index.php
require_once 'vendor/autoload.php';

$loader = new \Twig\Loader\FilesystemLoader('templates');
$twig = new \Twig\Environment($loader);

$users = [
    ['id' => 1, 'name' => 'Анна', 'email' => 'anna@example.com'],
    ['id' => 2, 'name' => 'Иван', 'email' => 'ivan@example.com'],
    ['id' => 3, 'name' => 'Мария', 'email' => 'maria@example.com']
];

echo $twig->render('users.html.twig', ['users' => $users]);
    

View php list (просмотр списка php)

Шаблон users.html.twig:


<table border="1">
    <tr><th>ID</th><th>Имя</th><th>Email</th></tr>
    {% for user in users %}
        <tr>
            <td>{{ user.id }}</td>
            <td>{{ user.name }}</td>
            <td>{{ user.email }}</td>
        </tr>
    {% else %}
        <tr><td colspan="3">Пользователи не найдены</td></tr>
    {% endfor %}
</table>
    

Результат:

<table border="1">
    <tr><th>ID</th><th>Имя</th><th>Email</th></tr>
    <tr><td>1</td><td>Анна</td><td>anna@example.com</td></tr>
    <tr><td>2</td><td>Иван</td><td>ivan@example.com</td></tr>
    <tr><td>3</td><td>Мария</td><td>maria@example.com</td></tr>
</table>
    

Типичная ошибка: переменная users не передана в шаблон. Вместо списка выводится пустая строка или ошибка Undefined variable. Решение: проверить наличие переменной через {% if users is defined %} или использовать фильтр default: {% for user in users|default([]) %}.

Цели использования: Twig идеален для сложных проектов с множеством представлений, где важна безопасность и поддержка.

Как отобразить список без использования стороннего шаблонизатора?

Использование чистого PHP с включением файлов (include) и циклом foreach.


<?php
// index.php
$users = [
    ['id' => 1, 'name' => 'Анна', 'email' => 'anna@example.com'],
    ['id' => 2, 'name' => 'Иван', 'email' => 'ivan@example.com']
];
include 'list.phtml';
?>
    

<!-- list.phtml -->
<ul>
<?php foreach ($users as $user): ?>
    <li><?= htmlspecialchars($user['name'], ENT_QUOTES, 'UTF-8') ?></li>
<?php endforeach; ?>
</ul>
    

Проблема: легко забыть экранирование, что приводит к XSS-уязвимостям. Решение: всегда использовать htmlspecialchars или strip_tags для вывода данных.

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

Как использовать Smarty для перебора массива?

Smarty предлагает тег {foreach}.


// index.php
$smarty = new Smarty();
$smarty->assign('users', [
    ['id' => 1, 'name' => 'Анна'],
    ['id' => 2, 'name' => 'Иван']
]);
$smarty->display('list.tpl');
    

<ul>
{foreach from=$users item=user}
    <li>{$user.name}</li>
{foreachelse}
    <li>Список пуст</li>
{/foreach}
</ul>
    

Ошибка: если переменная $users не назначена, Smarty выведет предупреждение. Решение: проверить через {if isset($users)}...{/if}.

Цель: Smarty подходит для старых проектов или когда требуется строгий синтаксис.

Как в Blade (Laravel) отобразить коллекцию элементов?

Blade использует директиву @foreach и встроенную поддержку @forelse для пустых коллекций.


// Контроллер Laravel
$users = User::all();
return view('users.index', compact('users'));
    

<!-- resources/views/users/index.blade.php -->
@forelse ($users as $user)
    <p>{{ $user->name }} ({{ $user->email }})</p>
@empty
    <p>Нет пользователей.</p>
@endforelse
    

Проблема: отсутствие данных из-за неправильной передачи переменной. Решение: использовать @isset или проверять $users->count().

Применение: Blade рекомендуется в экосистеме Laravel для всех шаблонов.

Как создать универсальную функцию для рендеринга списка в чистом PHP?

Можно написать функцию, принимающую массив и замыкание для форматирования каждой строки.


function renderList(array $items, callable $formatItem): string {
    if (empty($items)) {
        return '<p>Список пуст.</p>';
    }
    $html = '<ul>';
    foreach ($items as $item) {
        $html .= '<li>' . $formatItem($item) . '</li>';
    }
    $html .= '</ul>';
    return $html;
}

$users = [['name' => 'Анна'], ['name' => 'Иван']];
echo renderList($users, function($user) {
    return htmlspecialchars($user['name']);
});
    

Ошибка: забыли экранировать вывод внутри замыкания. Решение: обязательное экранирование внутри callback.

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

Расширенные примеры работы со списками

Вложенные списки в Twig

Отображение категорий с подкатегориями.

Пример

// PHP
$categories = [
    [
        'name' => 'Электроника',
        'children' => [
            ['name' => 'Телефоны'],
            ['name' => 'Ноутбуки']
        ]
    ],
    [
        'name' => 'Одежда',
        'children' => []
    ]
];
echo $twig->render('categories.html.twig', ['categories' => $categories]);
Пример

<!-- categories.html.twig -->
<ul>
{% for category in categories %}
    <li>
        {{ category.name }}
        {% if category.children is not empty %}
            <ul>
            {% for child in category.children %}
                <li>{{ child.name }}</li>
            {% endfor %}
            </ul>
        {% endif %}
    </li>
{% endfor %}
</ul>
<ul>
    <li>Электроника
        <ul>
            <li>Телефоны</li>
            <li>Ноутбуки</li>
        </ul>
    </li>
    <li>Одежда</li>
</ul>

Постраничная навигация (пагинация) с Blade

Передача объекта LengthAwarePaginator из Laravel в шаблон.

Пример

// Контроллер
$users = User::paginate(10);
return view('users.index', compact('users'));
Пример

<!-- users/index.blade.php -->
<table>
    @foreach ($users as $user)
        <tr><td>{{ $user->name }}</td></tr>
    @endforeach
</table>

{{ $users->links() }}

Результат: Bootstrap-стилизованные ссылки на страницы.

Фильтрация и сортировка в Smarty

Использование модификаторов для изменения порядка вывода.

Пример

// PHP
$items = [3, 1, 2];
$smarty->assign('items', $items);
Пример

<ol>
{foreach from=$items|@sort item=val}
    <li>{$val}</li>
{/foreach}
</ol>
<ol>
    <li>1</li>
    <li>2</li>
    <li>3</li>
</ol>

Группировка элементов по ключу в чистом PHP

Вывод списка, сгруппированного по первой букве имени.

Пример

$users = ['Анна', 'Алексей', 'Борис', 'Валентина'];
$grouped = [];
foreach ($users as $name) {
    $firstLetter = mb_strtoupper(mb_substr($name, 0, 1));
    $grouped[$firstLetter][] = $name;
}
ksort($grouped);

echo '<dl>';
foreach ($grouped as $letter => $names) {
    echo '<dt>' . htmlspecialchars($letter) . '</dt>';
    echo '<dd><ul>';
    foreach ($names as $name) {
        echo '<li>' . htmlspecialchars($name) . '</li>';
    }
    echo '</ul></dd>';
}
echo '</dl>';
<dl>
    <dt>А</dt>
    <dd><ul>
        <li>Анна</li>
        <li>Алексей</li>
    </ul></dd>
    <dt>Б</dt>
    <dd><ul>
        <li>Борис</li>
    </ul></dd>
    <dt>В</dt>
    <dd><ul>
        <li>Валентина</li>
    </ul></dd>
</dl>

Просмотр списка PHP - comments

En
View php list (php)