Меня интересует, насколько правильно я генерирую динамику на сайте.
Допустим, есть основной шаблон (статика) и для генерации контента используется PHP, который в зависимости от условий генерирует HTML и "подставляет" верстку в шаблон:
<html>
<head>
...
</head>
<body>
<div id="row-1">
<h1>Заголовок</h1>
</div>
<div id="row-2">
<?php content($_SESSION['id']); ?>
</div>
</body>
</html>
В этом примере в месте, где нужна динамика, вызывается функция с аргументом id пользователя, который хранится в сессионной переменной:
<?php
session_start();
function content($id)
{
if(!empty($id))
{
$query = mysqli_query(connect(), "SELECT * FROM Post WHERE user_id = $id");
while($row = mysqli_fetch_assoc($query)
{
echo "<div>Пост $row[name]</div><br><p>$row[text]</p>";
}
}
else
{
echo "<div>Для просмотра необходимо авторизоваться</div>";
}
}
Является ли такой способ генерации верстки приемлемым?
На разных ресурсах по этому вопросу дают противоречивые ответы, вроде, что генерация на стороне сервера требует много трафика или же наоборот, что это верный способ.
Помогите разобраться или подсказать более лучшее решение. Заранее спасибо!
P.S. Я знаю про паттерны (например MVC) и фреймворки с ними связанные, но меня на данный момент интересуют способы написания грамотного кода "своими руками".
Нареканий слишком много, попробуем разобраться.
Про ООП говорить не буду, но классы позволяют гораздо лучше организовать структуру проектов, чем простые глобальные функции.
echo
без необходимостиПросто замените echo на return, и перенесите его в шаблон:
<?=content($_SESSION['id'])?>
Вынесите получение данных о пользователе в отдельную функцию:
function content($id) {
$user = getUser(intval($id));
if (empty($user)) return '...';
return '...';
}
Ведите разработку с максимально высоким уровнем вывода ошибок: error_reporting(-1);
Так, вы бы увидели, что конструкции вида "$a[some]"
генерируют лишние логи, потому как пытаются сначала обнаружить константу some
, и только потом полагают, что это строка Assume some as 'some'
. Обращения к жесткому диску для логирования могут существенно снизить производительность.
Сделайте простой класс для генерации шаблонов
Рано или поздно, html-код в функции template
станент неуправляемым.
Лучше вынести отображение данных о пользователе в отдельный шаблон.
Класс для реализации подобного шаблона пишется элементарно с использованием фунции extract
.
Пример такого шаблона:
class Template {
private $tpl;
public function __construct($tpl) {$this->tpl = $tpl;}
// можно добавлять функции-helpers, доступные в темплейте через $this
public function e($str) {return htmlspecialchars($str);}
public function render($modelData) {
try {
// Делаем переменные доступными в шаблоне
extract($modelData); // Можно также реализовать какой-нибудь \ArrayAccess и использовать тут $this->data
ob_start();
include $this->tpl;
} catch (\Exception $e) { // Файл не найден, и т.п.
ob_end_clean();
throw $e;
}
return ob_get_clean();
}
}
// Usage:
// user.tpl
<div>
<?php if (empty($user)): ?>
<div>Для просмотра необходимо авторизоваться</div>
<?php else:?>
<div>Пост <?=$this->e($user['name'])?></div><br>
<p><?=$this->e($user['text'])?></p>
<?php endif?>
</div>
// controller
$tpl = new Template(__DIR__.'/templates/layout.tpl');
$userTpl = new Template(__DIR__.'/templates/user.tpl');
echo $tpl->render([
'userBlock' => $userTpl->render(['user' => $this->userProvider->find($id)])
]);
Советую вам глянуть в сторону шаблонизаторов, вы можете реализовать всю логику сами, так например использовать паттерн HMVC
, но сам вывод динамических данных реализовать по средствам PHP/JS
Шаблонизаторов. Из PHP
Шаблонизаторов отмечу как самый простой на мой взгляд это Twig
, с JS
ситуация сложнее, так как в целом в JS
Нет такого понятия как «шаблонизатор», просто у фреймворков на JS
Есть своя удобная реализация работы с DOM
, которая легко позволяет нам выводить динамические данные на страницу.
Не стоит использовать HTML код в PHP. Лучше сделать SQL-select и вернуть массив и сделать это в самом верху к примеру:
$content = content($_SESSION['id']);
if($content['code'] !== 200) {
$error['code'] = 403;
$error['message'] = 'Необходимо авторизоваться.';
}
Тогда твоя функция content(); может выглядеть вот так.
function content($id) {
if(!empty($id)) {
$query = mysqli_query(connect(), "SELECT * FROM Post WHERE user_id = $id");
return ['code'=>200, 'posts'=>mysqli_fetch_assoc($query)];
} else {
return ['code'=>403, 'message'=> 'Unauthorized']
}
}
А в html шаблоне уже использовать Альтернативный Синтаксис Управляющих Структур и выводить.
<div class = "posts">
<? foreach($content['posts'] as $post): ?>
<div class = "post">
<div>
<?=$post['name'];?>
</div>
<br />
<div>
<?=$post['text'];?>
</div>
</div>
<? endforeach; ?>
</div>
Кофе для программистов: как напиток влияет на продуктивность кодеров?
Рекламные вывески: как привлечь внимание и увеличить продажи
Стратегії та тренди в SMM - Технології, що формують майбутнє сьогодні
Выделенный сервер, что это, для чего нужен и какие характеристики важны?
Современные решения для бизнеса: как облачные и виртуальные технологии меняют рынок
Есть ситуация, когда на сетевом диске есть несколько каталогов с разными правами доступа для разных пользователей доменаИ в эти каталоги...
Если в строке $str есть матное слово, то $str = "censored";Возможно, с помощью preg_replace?
Перечитал все, что доступно на эту тему здесь и на других ресурсах, но проблема упорно не хочет решатьсяЯ пытаюсь вызвать Python скрипт из PHP, перепробовал...