Хочу поделиться с Хабром простым PHP-фреймворком, выросшим из идей минимализма и нацеленным на быструю разработку простых сайтов.
Не хочу показаться зазывалой, впаривающим вам очередной фреймворк, потому все ссылки для быстрого ознакомления с проектом оставляю над катом:
<?php $sp = [ 'layout' => [ 'title' => 'Статья', ], 'input' => [ INPUT_GET => [ 'id' => [ FILTER_SANITIZE_NUMBER_INT, [ 'filter' => FILTER_VALIDATE_INT, 'options' => ['min_range' => 1], 'comment' => 'Идентификатор должен быть положительным, целым числом' ] ], ], ], 'pdo' => [ 'queries' => [ 'article' => [ 'SELECT * FROM article WHERE id = :id', 'params' => [ 'id' => &$_GET['id'], ], ], ], ], ]; include('../../sp.php'); $article = $article->fetch(); ?> <h1> <?= $article->title ?> </h1> <div> <?= $article->content ?> </div> <ul> <li> <a href="/articles/edit?id=<?= $article->id ?>">edit</a> </li> <li> <a href="/articles/delete.php?id=<?= $article->id ?>">delete</a> </li> </ul>
<?php <?php if($_SERVER['REQUEST_METHOD'] != 'GET'){ http_response_code(404); exit; } $sp = [ 'input' => [ INPUT_GET => [ 'id' => [ FILTER_SANITIZE_NUMBER_INT, [ 'filter' => FILTER_VALIDATE_INT, 'options' => ['min_range' => 1], 'comment' => 'Идентификатор должен быть положительным, целым числом' ] ], ], ], 'pdo' => [ 'queries' => [ [ 'DELETE FROM article WHERE id = :id', 'params' => [ 'id' => &$_GET['id'], ], ] ], ], ]; include('../sp.php'); header('Location: /articles', 302);
Для заинтересовавшихся, под катом будет краткое описание возможностей проекта, его преимуществ и пример использования.
Краткое введение
Если вы знакомы с Jekyll, то вы уже познакомились с большей частью возможностей SimplePage, а именно:
- Конфигурация системы на уровне конкретной страницы и всего сайта
<?php $sp = [ // Вводные страницы заменяют дефолтные конфигурации сайта 'layout' => [ 'title' => 'Редактор статьи', ], ]; include('../../sp.php'); ?> <form action="/articles/create.php" method="POST"> <div> <input type="text" name="title" placeholder="Заголовок"/> </div> <div> <textarea name="content"></textarea> </div> <div> <input type="submit" value="Сохранить"/> </div> </form>
- Роутинг на уровне веб-сервера
▾ articles/ ▸ _locale/ ▸ create/ ▾ edit/ index.php // Страница редактирования статьи ▸ view/ create.php // Экшен создания статьи delete.php edit.php index.php // Страница со списком статей index.php // Главная страница
- Отсутствие зависимостей — фреймворк использует только возможности самого PHP. Выбор базы данных и веб-сервера остаются на совести разработчика
Преимущества и недостатки
Преимущества:
- Очень низкий порог входа — если вы умеете HTML/CSS и немного PHP, вы можете использовать этот фреймворк
- Очень прост в установке — достаточно скопировать несколько PHP-скриптов, и фреймворк готов к работе
- Очень прост в использовании — каждая страница сайта это отдельный PHP-скрипт, содержащий как логику для обработки запроса, так и HTML-шаблон для генерации ответа
Недостатки:
- Процедурный код и global — с увеличением проекта, поддержка может заметно усложниться
- Низкоуровневая инфраструктура — используются возможности самого PHP, без дополнительных слоев абстракции и интерфейсов
Плагины и модули
Для расширения функционала фреймворка и разработки прикладных решений с его помощью используются плагины и модули соответственно. Первые, как правило, представляют собой инфраструктурные и вспомогательные компоненты приложения, а вторые прикладные решения.
Для подключения плагина, достаточно указать его в конфигурации:
return [ 'plugins' => [ '_plugins/autoload.php', '_plugins/input.php', '_plugins/middleware.php', '_plugins/i18n.php', '_plugins/error.php', '_plugins/pdo.php', '_plugins/acl.php', '_plugins/layout.php', '_plugins/hook.php', ], ... ];
По умолчанию фреймворк поставляется со следующими плагинами:
- Acl — разграничение прав доступа к страницам сайта
- Autoload — загрузка классов с использованием прямых ссылок или путей PSR-4
- Error — обработка ошибок и исключений
- Hook — модель событий (хуков)
- I18n — интернационализация
- Input — фильтрация ввода
- Layout — HTML-обертки
- Middleware — модель последовательной обработки ввода-вывода
- Pdo — декларативная работа с БД
Разработчик может дополнять эти плагины собственными, в том числе используя внешние зависимости и composer:
return [ 'plugins' => [ 'vendor/autoload.php', '_plugins/markdown.php', ... ], ... ];
В отличии от плагинов, модули представлены набором PHP-скриптов и даже страниц, решающих прикладные задачи проекта, такие как "Панель администратора" или "Форум".
Пример простого блога
Рассмотрим пример создания блога с использованием данного фреймворка.
Для начала реализуем общую конфигурацию сайта, создав файл config.php в корне проекта:
<?php return [ 'plugins' => [ '_plugins/input.php', '_plugins/middleware.php', '_plugins/i18n.php', '_plugins/error.php', '_plugins/pdo.php', '_plugins/layout.php', ], 'layout' => [ 'title' => 'SimplePage', 'layout' => '_layout/default.html', ], 'pdo' => [ 'dsn' => [ 'mysql', 'dbname' => 'sp', 'charset' => 'UTF8', ], 'username' => 'root', 'password' => 'root', 'options' => [ PDO::ATTR_PERSISTENT => true ], ], ];
Далее реализуем layout, создав шаблон _layout/default.html, который будет применяться ко всем страницам сайта:
<!DOCTYPE html> <html> <head> <title><?= i18n($title) ?></title> <meta charset="utf-8" /> <link href="/_css/style.css" rel="stylesheet"> </head> <body> <?= $content ?> </body> </html>
Пришло время создать главную страницу сайта, для этого запишем в файл index.php следующее:
<?php include('sp.php') ?> <h1>Hello world</h1> <p> Моя главная страница <p> <ul> <li> <a href="/articles">Статьи</a> </li> </ul>
Далее создадим страницу со списком статей (предполагается, что таблицы для этого модуля уже созданы в БД), для этого запишем в файл articles/index.php следующий код:
<?php $start = isset($_GET['start'])? (int) $_GET['start'] : 0; $offset = isset($_GET['offset'])? (int) $_GET['offset'] : 2; $sp = [ 'layout' => [ 'title' => 'Articles', ], 'pdo' => [ 'queries' => [ 'articles' => [ 'SELECT * FROM article LIMIT :start, :offset', 'params' => [ 'start' => $start, 'offset' => $offset, ], ], 'articlesCount' => [ 'SELECT COUNT(*) FROM article', ], ], ], ]; include('../sp.php'); $articlesCount = $articlesCount->fetchColumn(); ?> <h1>Статьи</h1> <p> <ul> <?php foreach($articles as $article): ?> <li> <a href="/articles/view?id=<?= $article->id ?>"> <?= $article->title ?> </a> </li> <?php endforeach; ?> </ul> <ul> <li> Всего <?= i18n_plural($articlesCount, '%d article') ?> </li> <li> <a href="/articles/create"><?= i18n('create') ?></a> </li> <li> <a href="/articles?start=<?= $start - $offset ?>"><?= i18n('prev') ?></a> </li> <li> <a href="/articles?start=<?= $start + $offset?>"><?= i18n('next') ?></a> </li> </ul> </p>
Как можно заметить, в шаблоне страницы используется интернационализация. Следовательно необходимо создать файл articles/_locale/ru_RU.php для ее корректной работы:
<?php return [ '' => [ 'plural_forms' => function($n){ if($n % 10 == 1 && $n % 100 != 11){ return 0; } elseif($n % 10 >= 2 && $n % 10 <= 4 && ($n % 100 < 10 || $n % 100 >= 20)){ return 1; } else{ return 2; } }, ], '%d article' => [ '%d статья', '%d статьи', '%d статей', ], 'Articles' => 'Статьи', 'create' => 'создать', 'prev' => 'назад', 'next' => 'вперед', ];
На последок рассмотрим экшен создания новой статьи в блоге, для этого создадим файл articles/create.php:
<?php if($_SERVER['REQUEST_METHOD'] != 'POST'){ http_response_code(404); exit; } $sp = [ 'pdo' => [ 'queries' => [ [ 'INSERT INTO article (title, content) VALUES (:title, :content)', 'params' => [ 'title' => $_POST['title'], 'content' => $_POST['content'], ], ], ], ], ]; include('../sp.php'); header('Location: /articles/view?id=' . pdo_build($sp['pdo'])->lastInsertId(), 302);
ссылка на оригинал статьи https://habrahabr.ru/post/328002/
Добавить комментарий