PHP MVC. Как разделить файлы вёрстки в views
Можно ли используя MVC реализовать разделение файла index.php (основная страница с контентом) на header, content, footer, то есть на несколько частей. Если да, то как? Проблема заключается в том, что мне нужно вывести все данные из таблицы, но вывод я могу сделать только в начале или конце index.php.
default.php (макет) Вывод табличных данных в конце кода
<!DOCTYPE html>
<html>
<head>
<link rel="stylesheet" href="<?php echo $style; ?>" type="text/css"/>
<title><?php echo $title ;?></title>
</head>
<body>
<header class="header">
<div class="header__inner">
<div class="header__btns">
<a id="nickname" href="#"><button><?php echo $_SESSION['user']['nickname']; ?></button></a>
<a href="/admin"><button>Админка</button></a>
</div>
<div class="header__headline">
<h1>Литературный <span>мир</span></h1>
<p>Электронная библиотека литературы</p>
</div>
<div class="header__search-book">
<form action="#" method="get">
<input type="text" placeholder="Найти книгу...">
<button type="submit"><img src="public/image/icon_search.png" alt="#"></button>
</form>
</div>
</div>
</header>
<?php echo $booksContent; ?> <--------------- Вывод табличных данных которые хранятся в переменной
<?php echo $content; ?>
<script src="<?php echo $script ?>"></script>
</body>
</html>
View.php (рендеринг макета) Наверное лишнее, но оставлю на всякий случай.
public function render($title, $vars = []) : void {
extract($vars);
$pathView = 'application/views/' . $this->path . '.php';
if(file_exists($pathView)) {
ob_start();
require $pathView;
$content = ob_get_clean();
ob_start();
$db = new Db();
$result = $db::prepare("SELECT * FROM books ORDER BY id");
$result->execute();
if($result->rowCount() > 0){
while($row = $result->fetch()){
?>
<div class="book">
<div class="book__image">
<img src="" alt="">
</div>
<div class="book__title"><?php echo $row['name'] ?></div>
<div class="book__author">Автор: <span class="bold_info"><a href="#"><?php echo $row['author'] ?></a></span></div>
<div class="book__genre">Жанр: <span class="bold_info"><?php echo $row['genre'] ?></span></div>
<div class="book__pages">Страниц: <span class="bold_info"><?php echo $row['pages'] ?></span></div>
<a href="#"><button>Читать</button></a>
</div>
<?php
}
}
$booksContent = ob_get_clean();
Ответы (1 шт):
Конечно можно. View это не только шаблоны, а целый слой вашего приложения, который выражает логику формирования HTML. Этот слой может содержать классы форм, меню и прочего.
Забабахайте класс Layout
<?php
class Layout implements Stringable {
// ...
public function render(): string
{
return ob_include($this->template, [
'styles' => $this->styles,
'scripts' => $this->scripts,
'header' => $this->header,
'content' => $this->content,
'footer' => $this->footer,
'menu' => $this->menu?->render()?? '',
]);
}
public function __toString(): string
{
return $this->render();
}
}
Который будет рендерить шаблон типа:
<html>
<head>
<?php foreach($styles as $href): ?>
<link href="<?= htmlspecialchars($href) ?>" rel="stylesheet">
<?php endforeach ?>
<?php foreach ($scripts as $src): ?>
<script src="<?= htmlspecialchars($src) ?>"></script>
<?php endforeach ?>
</head>
<body>
<?= $header ?>
<nav class="menu">
<?= $menu ?>
</nav>
<?= $content ?>
<?= $footer ?>
</body>
</html>
Отдельно отрендерите шаблоны шапки, контента и подвала и передайте их в инстанс Layout. Чаще всего шапка и подвал не зависят о того, что отображается в части content, поэтому их можно отрендерить заранее, а в конкретном контроллере останется только добить content.
<?php
// ...
return $layout
->setMenu($menu->setActive('/myPage'))
->setContent(ob_include(__DIR__ . '/myPage.phtml', []));
Ваш код функции render содержит ошибку (extract может извлекать переменные с именами, которые вы используете ниже). Я написал небольшую заметку про php-шаблоны для новичков. Почитайте.
