PSR-7 фреймворк: Консольные команды, базы данных и ресурсы

Завершающий урок серии скринкастов по изучению PSR-7 микрофреймворков в PHP. Добавляем поддержку написания консольных команд, добавляем работу с базами данных с помощью PDO и готовых ORM, оптимизируем запросы:

Исходный код на GitHub

Для более комфортного просмотра откройте скринкаст на YouTube, разверните видео до оригинального размера значком и поставьте скорость 1,75:


Содержание:

  • 00:00:00 - Вступление, повторение выводов, цели урока
  • 00:03:00 - Доработки, символические ссылки
  • 00:07:06 - Автопроверка стиля кода
  • 00:10:28 - PHP_CodeSniffer
  • 00:13:50 - Конфигурационный файл phpcs
  • 00:19:13 - Запуск командой в composer.json
  • 00:22:35 - Консольный скрипт app.php
  • 00:29:41 - Код очистки кеша в консоли
  • 00:33:40 - Вынос в класс CacheClearCommand
  • 00:37:59 - Аргументы консольной команды argv и argc
  • 00:48:47 - Интерактивный ввод для консольной команды
  • 00:56:08 - Объект ввода, класс Input
  • 01:01:13 - Вынос диалогов в Input
  • 01:02:33 - Объект вывода Output
  • 01:03:55 - Поддержка цветов с помощью спецсимволов
  • 01:08:13 - Выделение слов цветом, псевдотэги
  • 01:10:36 - Вынос списка папок кеша в конфигурацию
  • 01:13:17 - Вынос метода delete в файловый менеджер
  • 01:16:52 - Маршрутизация консольных команд
  • 01:24:07 - Интерфейс консольных команд
  • 01:26:01 - Добавление метода для имени команды
  • 01:35:11 - Создание класса Console Application
  • 01:39:40 - Хранение списка кманд в конфигурации
  • 01:42:24 - Компонент zend-console
  • 01:45:28 - Компонент symfony console
  • 01:50:13 - Переписывание команды для Symfony
  • 02:02:26 - Интерактивность через QuestionHelper
  • 02:11:05 - Применение готового хэлпера
  • 02:13:34 - Общая теория подключения к БД
  • 02:15:12 - Добавление базы данных
  • 02:18:15 - Расширение ext-pdo и composer
  • 02:20:52 - Конфигурирование PDO для бросания исключений
  • 02:24:18 - Подключение SQLite
  • 02:34:28 - Конфигурирование в контейнере
  • 02:37:27 - Вынос в отдельный файл конфигурации
  • 02:39:34 - Вывод постов, PostReadRepository
  • 02:46:07 - Вынос метода гидрации
  • 02:49:07 - Создание таблиц в БД, теория
  • 02:52:46 - Миграции базы данных, теория
  • 03:01:47 - Библиотека Phinx Migration
  • 03:05:57 - Подключение Phinx в проект
  • 03:11:53 - Заполнение демо-данными, PostsSeeder
  • 03:13:37 - Генерация случайных данных через Faker
  • 03:17:13 - Постраничный вывод по 10 постов на страницу
  • 03:22:14 - Вывод постраничной навигации
  • 03:28:06 - Вынос расчётов в объект Pagination
  • 03:33:17 - Промежуточные итоги
  • 03:34:39 - Библиотека Illuminate DB
  • 03:37:20 - Библиотека Doctrine ORM
  • 03:42:01 - Установка через пакет container-interop-doctrine
  • 03:46:10 - Подключение Doctrine
  • 03:50:27 - Сущность Post с Content, Meta и Comment
  • 03:57:39 - Подход Code-First и генерация миграций БД
  • 04:01:37 - Просмотр таблиц в db.sqlite
  • 04:04:23 - Возвращение HelperSet
  • 04:06:36 - Интеграция команд Doctrine в наше приложение
  • 04:09:08 - EntityMahagerHelper
  • 04:11:33 - Пакет Doctrine Migrations
  • 04:16:32 - Настройка путей для миграций
  • 04:20:19 - Генерация миграций
  • 04:24:08 - Doctrine Fixtures
  • 04:27:47 - FixtureCommand
  • 04:31:11 - Фикстура BlogFixture
  • 04:34:19 - Отключение фикстур из production
  • 04:35:56 - Переписывание PostReadRepository на работу с EntityRepository
  • 04:40:50 - Доработка представлений
  • 04:43:07 - Избавляемся от своего PDO
  • 04:47:28 - Работа с кешированием в Doctrine
  • 04:55:06 - Проблема производительности, теория
  • 04:59:58 - Создание производительной Read Model
  • 05:05:06 - Промежуточные итоги
  • 05:10:13 - Альтернативный возврат ошибки 404
  • 05:16:50 - Генеация ошибок для API
  • 05:22:51 - Подключение ассетов
  • 05:24:21 - Обновление на Bootstrap 4
  • 05:28:38 - Подключение NodeJS и npm yarn
  • 05:30:58 - Указание зависимостей в package.json
  • 05:33:22 - Установка пакетов
  • 05:36:19 - Написание скриптов и стилей
  • 05:37:39 - Препроцессинг SASS
  • 05:39:56 - Библиотека WebPack
  • 05:44:35 - Библиотека Laravel Mix
  • 05:47:34 - Конвертация скриптов и стилей
  • 05:51:21 - Генерация ресурсов для публикации через yarn prod
  • 05:52:07 - Другие команды
  • 05:54:48 - Кастомизация бутстраповских стилей
  • 05:58:53 - Переопределение переменных в variables.scss
  • 06:01:44 - Борьба с кэшированием, версионирование
  • 06:06:13 - Расширение stormiix/laravel-mix-twig-extension
  • 06:10:57 - Подведение итогов

  1. Структура и работа с HTTP
  2. Контроллеры и маршрутизация
  3. Middleware и Pipeline
  4. Контейнер внедрения зависимостей
  5. Шаблонизаторы и вёрстка
  6. Обновление до PSR-15, вывод ошибок и логирование
  7. Консольные команды, базы данных и ресурсы

Задавайте вопросы в комментариях. Заранее спасибо и до встречи в следующих видео!

Комментарии

 

Егор

Отличное видео, вдумчиво проработанный и очень полезный материал. Мелкие уточнения:

1. NPM уже поддерживает lock файлы. Новый NPM создаёт package-lock.json и никаких yarn'ов ставить не нужно:

2. В случае с Doctrine ORM не обязательно использовать сырые запросы если нужны агрегации в запросе:

$query = $em->createQuery('SELECT u, count(g.id) FROM Entities\User u JOIN u.groups g GROUP BY u.id');
$result = $query->getResult();

И можно ничего руками не гидрировать.

Ответить

 

Дмитрий Елисеев

1. Поддерживает, но криво при переходе между операционными системами. По lock-файлу, сгенерированному в Linux не устанавливает в MacOS и наоборот.

2. Да, можно.

Ответить

 

Max Гордиенко

Круто, спасибо.

Ответить

 

Husniddin

hello thanks this great course and please create new course(frontend(Angular or React) and backend(php, yii2 or laravel)). Many thanks Dmitriy. Your great teacher and devaloper.

Ответить

 

slo_nik

Доброе утро.
Наконец-то дождался.
Теперь можно пересматривать с первого урока)))

Ответить

 

Алексей

У диакторовского EmptyResponse, боди - is not writable. Поэтому, не плохо бы в EmptyResponseMiddleware, проводить проверку, а можем ли мы что-нибудь записать в тело, прилетевшего нам ответа? Можем - пишем в него, нет - устанавливаем в боди свой writable strim и пишем уже в него. А так как, собственно говоря, мы определили что в прилетевшем response, тело пустое, то можно обойтись и без проверки:

if ($body->getSize() === 0) {
        switch ($response->getStatusCode()) {
            case 403: $html = $this->template->render('error/403', compact('request')); break;
            case 404: $html = $this->template->render('error/404', compact('request'));
        }

        $body = new Stream('php://temp', 'w');
        $body->write($html);

        $response = $response->withBody($body);
 }
Ответить

 

rukuki

Если уже пользуетесь SplQueue, то почему бы и дальше не использовать Spl

        $directoryIterator = new \RecursiveIteratorIterator(
            new \RecursiveDirectoryIterator($path, \RecursiveDirectoryIterator::SKIP_DOTS),
            \RecursiveIteratorIterator::CHILD_FIRST
        );

        /**
         * @var $fileInfoItem \SplFileInfo
         */
        foreach ($directoryIterator as $fileInfoItem) {
            if ($fileInfoItem->isDir()) {
                rmdir($fileInfoItem->getPathname());
            } else {
                unlink($fileInfoItem->getPathname());
            }
        }
Ответить

 

Максим Ковалёв

Доброго дня!
Курс очень шикарный! Многое подчерпнул для себя, для команды.
Скажите, есть ли возможность аналогично illuminate database использовать predis глобально? Я много где рылся, в том числе в исходниках, но так и не нашёл ничего подобного, используем глобальные переменные

Ответить

 

Дмитрий Елисеев

А какой смысл в глобальном, если есть контейнер?

Ответить

 

Максим Ковалёв

Однако контейнер так же придётся таскать за собой глобально. Либо передавать в конструктор везде и всюду

Ответить

 

Дмитрий Елисеев

Принимать Client $redis в конструктор как PDO $pdo.

Ответить

 

Роман

Круто, еще бы книгу по этому выпустил бы, цены б не было.

Ответить

 

Valdemar Nebonyr

Спасибо, Дмитрий! Отличный формат.

Стоит ли его проходить или есть смысл подождать обновления? Все таки 2018 год..

Крайний коммит, к сожалению не взлетает на веб сервере nginx/php-fpm 7.4, несмотря на composer update. Возможно потому что компзер жестко не фиксирует версии зависимостей.
Придется по шагам дебажить :

PHP Warning:  file_get_contents(public/build/mix-manifest.json): failed to open stream: No such file or directory in /home/vladp/dev/sites/eliseev-fwork/vendor/stormiix/laravel-mix-twig-extension/src/MixExtension.php on line 66
PHP Fatal error:  Uncaught InvalidArgumentException: File /css/app.css not defined in asset manifest. in /home/vladp/dev/sites/eliseev-fwork/vendor/stormiix/laravel-mix-twig-extension/src/MixExtension.php:51
Stack trace:
#0 /var/cache/twig/69/69f0d0e707e0c8355c1ab489880bd3dd2921ad287c1c5cdbde5acb8d679e0306.php(56): Stormiix\Twig\Extension\MixExtension->getVersionedFilePath()
#1 /vendor/twig/twig/src/Template.php(405): __TwigTemplate_25a4ed4d7822d9a49473ee68b9bc39eebd4f98ba13c18f3bfac816c7fa7a79eb->doDisplay()
#2 /vendor/twig/twig/src/Template.php(378): Twig\Template->displayWithErrorHandling()
#3 /var/cache/twig/7c/7cbd04204c1fd4aee97030c3486277ef0b269dcb85aa6c7dc88e8cc921b7343a.php(44): Twig\Template->display()
#4 /vendor/twig/twig/src/Template.php(405): __TwigTemplate_51a0becf94cc2bb8028a81b119a562923d31b5ebc115016540ca902378153d76->doDisplay()
#5 /home in /templates/layout/default.html.twig on line 9
Ответить

 

Дмитрий Елисеев

Запустить сразу не получится. Но можно просто посмотреть для понимания идей.

А так да, все компоненты недавно доперенесли на PHP 8, так что я уже начал готовить код для обновлённых скринкастов.

Ответить

 

Valdemar Nebonyr

Да, я уже запустил код: были проблемы с версиями php + забыл про установку webpack.

Дмитрий, тут вот еще в чём фишка:

в Вашем репозитории (аукцион) мне случалось видеть нерабочий черновой код, который не проходит даже синтаксическую проверку.
Видимо, это временные куски.

Будет гораздо круче, если бы Вы смогли помечать тегами (номер видео) работающий код, который советует завершенному скринкасту.
Тогда люди смогут оценить видео с помощью гарантированно рабочего кода, который соответсвует видео..

Ответить

 

Дмитрий Елисеев

Обычно стараюсь при чистовой записи каждый коммит в репозитории проверять по check. Если не проходит, то потом исправляю коммиты через rebase.

Так что если встретите нерабочий коммит, то сообщите и я исправлю.

Ответить

 

Valdemar Nebonyr

А про метки подумайте плз.
Как здорово: увидел интересный код в видео, переключился на тег в репе и работает!!

А сейчас трудно понять - к какому видео код относится. По именам коммитов - код не совпадает.

Ответить

Оставить комментарий

Войти | Завести аккаунт | Войти через


(никто не увидит)





Можно использовать теги <p> <ul> <li> <b> <i> <a> <pre>