Подготовка структуры директорий API. Добавление образа PHP-CLI. Установка Slim Framework. Ускорение установки в Composer v1.
- 00:00:50 Работа с PHP в консоли
- 00:01:59 Философия Docker по контейнеру на процесс
- 00:03:04 Образ для PHP CLI
- 00:05:16 Установка Composer
- 00:07:55 Проверка работы Composer
- 00:09:34 Ускорение Composer v1
- 00:11:52 Инициализация composer.json
- 00:13:24 Пакет Security Advisories
- 00:14:07 Установка и обзор Slim
- 00:20:15 Команда установки зависимостей
- 00:21:38 Исправление статуса ошибок в PHP
- 00:23:39 Обработчик ошибок фреймворка
- 00:25:07 Конфигурация через переменные окружения
- 00:28:24 Контейнер внедрения зависимостей
- 00:30:46 Папка src и автозагрузка
- 00:32:34 Вынос экшенов в классы
- 00:33:40 Работа с JSON
- 00:35:08 Формирование JSON-ответа
- 00:36:17 Контроллеры по PSR-15
- 00:39:26 Инъекция ResponseFactory
- 00:40:35 Контейнер с autowiring
- 00:43:19 Класс JsonResponse
- 00:46:22 Вынос маршрутов и посредников
- 00:47:20 Вынос настройки контейнера
- 00:49:06 Автозагрузка конфигурации
- 00:51:23 Поддержка разных окружений
- 00:53:43 Бутстрап приложения
- 00:55:23 Установка Symfony Console
- 00:58:14 Загрузка команд из контейнера
- 01:00:24 Запуск команд через Composer
- 01:01:48 Неинтерактивный запуск команд
- 01:02:48 Что дальше
В 44 эпизоде перейдём на Composer 2.0, где установка плагина уже не понадобится.
Скрытый контент (код, слайды, ...) для подписчиков.
Открыть →Чтобы не пропускать новые эпизоды подпишитесь на наш канал @deworkerpro в Telegram
Небольшой оффтоп. Можете показать, как реализован видео сервис?
В каком смысле?
Пока просто стандартный показ
<video><src="video.mp4"></video>
с файлового хостинга.Спасибо
Как правильно загружать и показывать видео с сервера
У композера вроде есть специально platform параметр для требования php https://getcomposer.org/doc/06-config.md#platform
Это не для требования, а для эмуляции. Чтобы он не видел реально установленную в системе версию.
56:25 А зачем использовать рефлексию, когда мы можем также явно указать класс для контейнера? рефлексия же медленная, или экономия на спичках?
Экономия на спичках.
php -- --install-dir что значат первые два тире?
Это значит, что параметры для php закончились и остальное надо игнорировать, так как далее пойдут параметры уже для самого скрипта.
Что значит объявление функции static вне класса ?
То, что функция или переменная после него создаётся всего один раз.
Здравствуйте, Дмитрий! Спасибо за огромную проделанную работу.
В коде вы неоднократно используете анонимные статические функции вне класса. В официальной документации по PHP мне удалось найти лишь, что "Начиная с PHP 5.4, анонимные функции могут быть объявлены статически. Это предотвратит их автоматическое связывание с текущим классом. Объекты также не будут с ними связаны во время выполнения."
Однако не удалось найти, что "функция или переменная после него создаётся всего один раз". Подскажите, пожалуйста, где об этом можно почитать?
В разделе об областях видимости переменных
Внимательно перечитал этот раздел официальной документации вместе с пользовательскими комментариями к нему, однако никакой информации об анонимных статических функциях там не нашел.
В различных статьях на иных ресурсах использование статических анонимных рассматривается лишь в контексте связывания с $this из текущего класса, упоминается о некотором увеличении производительности при их использовании. Но нигде нет информации, что "функция или переменная после него создаётся всего один раз".
Пожалуйста, объясните необходимость использования, например, в routes.php именно статической анонимной функции и что означает в этом контексте "функция или переменная после него создаётся всего один раз".
Это общая информация об использовании конструкций
global
иstatic
в таком виде с чем угодно. Хоть с переменными, хоть с функциями.Про это по ссылке выше есть два предложения:
Это говорит, что созданное в первый раз значение никогда не удаляется и оно же потом используется повторно.
Никакой необходимости нет. Это просто плагин EA Extended в PhpStorm рекомендует анонимные функции обозначать со словом
static
для микрооптимизации производительности. Особенно если метод с такой функцией внутри вызывается много раз в цикле, чтобы там на каждой итерации снова и снова одну и ту же анонимку не создавать.Чутка погундеть пришёл: «Чтобы не морочиться с конфигурационными файлами, типа conf или .env удобнее использовать окружение докера»
спустя 2 минуты: «Чтобы эти параметры не прописывать по всему коду удобнее создать конфигурационный файл» 0_о
Я слегка запутался, так конфигурационные файлы - это плохо или хорошо?
Имеется в виду не морочиться с копированием и ручным заполнением параметров в локальных файлах вроде
config-local.php
или.env-local
из.gitignore
, как это делается в Yii и Laravel.Вместо этого делаем фиксированный
config.php
с прямым чтениемgetenv(...)
из окружения.Универсальность порождает избыточность. Фреймворки дают готовые файлы, чтобы можно было быстро стартануть. Конечно, в нашем случае нет смысла делать какие-то conf-local, хотя в большой команде, если всё окружение будет разворачиваться локально, то, возможно и будет смысл иметь какие-то индивидуальные настройки из .local файла.
Например, если в проде у нас кэш в редиса, а очереди в реббита, в деве/стейже очереди синхронные, а локально было бы проще кэш отключить совсем.
В общем, какие-то конфиг файлы могут быть «тонко настраиваемыми» и тогда придётся их заполнять.
Как раз такое разделение весьма опасно тем, что на деве и стейже всё синхронно работает, а на проде что-то будет асинхронно падать. Или если в проде есть репликация БД и конфигурация с двумя базами, а на деве её нет и конфигурация с одной. Или если в проде почта отправляется по SMTP, а на локалке эмулируется сохранением в файлы.
Докер как раз позволяет без усилий делать везде одинаково, чтобы таких проблем от различия окружений не было.
Единственное, что в
config/dev/cache.php
и для тестов будет отключен кэш черезenable=false
.В итоге необходимость в личном файле config-local для каждого программиста полностью отпадает.
я не понял момент с php-di (с 39 минуты) . Мы сначала добавили use DI\Container; в индекс, и он на в композер подставил зависимость, или до это в композел руками вписали cтроку "php-di/php-di": "^6.0", ? Или просто из-за монтажа так получилось? а до этого было docker-compose run --rm api-php-cli composer require php-di/php-di.
Если руками редактировать composer.json , то потребуется composer update. Проясните пожалуйста.
В новом проекте не правьте вручную, а всегда делайте
composer require
. Тогда оно само с нужными версиями пропишется.Просто у меня уже готовый код из коммитов, где всё уже заранее прописалось.
Спасибо. Я понял. Думал может какая фишка есть, которая это вставляет, а я не знаю.
43min. У вас подсвечивается папка
src
и при создании класса подставляетсяnamespace
иdeclare(strict_types=1)
Как этого добиться?
По этому мануалу мне удалось добиться подстановки namespace
Папка не подсвечивается. :)
Нашел. Тупо нажать правой кнопкой и выбрать Mark as Source. Но с
declare(strict_types=1)
Как быть?Чтобы вручную не помечать папки через Mark as Source и не размечать vendor, нужно зайти в PHP > Composer и включить там опцию
Mark packages as libraries
. Это заодно правильно настроит игнор и импорт из папки vendor.А для declare перейдите в Editor > File and Code Templates и там впишите declare в PHP File Header.
Спасибо, очень помог совет.
Еще один тупой вопрос:
Когда мы делаем
$app->get('/', Http\Action\HomeAction::class)
HomeAction::class
- эта конструкция возвращает полное имя класса HomeAction, т.е. строку.а нам нужно вызвать объект как функцию т.е.
$action($request, $response, $args)
Почему без скобок происходит вызов?
Этим мы просто маршрутизатору передаём строкой имя класса. А сам фреймворк уже потом создаёт объект и производит вызов с $request и $response.
Вот у меня тут вопросик есть) Как правильно поступать с правами? Докер не под юзеровским айдишником делает папку вендор. Из за чего проблемы с правами. Знаю что в докерфайле можно присвоить uid и gid, корректен ли такой способ? Или данную манипуляцию в мэйкфайле можно? Какая практика вообще общепринятая?
С vendor всегда работаем изнутри контейнера, запуская composer require и composer update. Поэтому права здесь нам не мешают.
Но если что-то генерируем в коде и надо поменять права снаружи, то меняем владельца на себя:
Хочется поблагодарить Дмитрия и его супругу за проделанную работу и за самый годный контент по "правильному" программированию в рунет сети. Слежу за деятельностью Дмитрия ещё с создания его сайта блога. Спасибо большое.
Спасибо за тёплые слова! Очень приятно, если видеоматериалы вам помогают. Сейчас мы экспериментируем над записью эпизодов, качеством и этапами обработки. Обо всём пишу в своём блоге, возможно это покажется интересным.
Вы контроллеры сделали фреймворконезависимыми. А что насчет консольных команд? Они напрямую зависят от symfony/console. Почему в случае с консольными командами мы делаем это допущение?
Для контроллеров есть десятки HTTP-фреймворков и для независимости есть PSR-7 и PSR-15.
А для консольных команд популярен только
symfony/console
. От него уходить некуда и незачем.есть файл composer.json и к нему подключил свой собственный Compsoer-пакет(расширение находится на локальном компьютере).
Как можно сделать так чтобы при изменении Composer-пакет локальный, главный Compsoer ненужно было обновлять
composer update
Проставить с папки символическую ссылку если она не ставится автоматически.
Тут в видео array_merge_recursive, а в коммите array_replace_recursive. Помню, весной от и до прошерстил почему конфиги криво мерджились. Потом следующие уроки посмотрел и уже после этого разобрался как recursive функции php работают.
Если кто-то будет мучится с array_replace функциями из этих видео - просто не забивайте сильного голову, потом все равно либа от Laminas их заменит.
array_merge_recursice все отрабатывает не так как ожидалось, тоже на это обратил внимание
Напишу, может кому пригодится. В composer 2.0 hirak/prestissimo не работает. Видать из-за ненадобности. Так что я убрал этот плагин и вот мой рабочий вариант:
Строка
rm -rf /root/.composer/cache
теперь тоже не нужна.Спасибо за урок, тут был вопрос. Я с ним разобрался благодаря комментариям
Понимаю, что прошло много времени с этого урока,но фрэймворк не устанавливается, выдает ошибку: https://monosnap.com/file/UPKsaVIBn6VR0j3kdAanhlB7hUFnu3
Игнорируйте тест установки скелетона, идите дальше, там где всё устанавливается по мере надобности. И будет счастье :)
Вопрос по оплате и прочим удобствам, связанным с ней. Решил оформить подписку. Вбил данные карты и ничего дальше не происходит. Деньги не списываются, никаких кодов не приходит, висит пустой бланк заказа. Даже вернее сказать совсем пустой, белый, без полей. Была бы возможность прикрепить скрин - показал бы. И жаль, что в кабинете нет возможности задать вопрос по теме оплаты. Карта мастеркард. Вроде должна работать на перечисление в другую страну, по крайней мере проверена в некоторых магазинах Европы )))
В почте выяснили, что в другом браузере всё получилось. Может какое-то расширение браузера мешало.
Да, что-то я забыл тут написать о решении проблемы. В любом случае - спасибо
Почему не использовать отдельно образ с контейнером композера?
https://hub.docker.com/_/composer
Для первой установки можно сделать composer create-project через него. Но дальше уже удобнее чистый php-cli, где мы сами указываем версию PHP и доустанавливаем нужные расширения.
Понял, спасибо!)
Добрый вечер, Дмитрий. Остановился на 10 минуте данного урока. Прохожу курс на Ubuntu через VMware После добавления apk update образы перестали собираться с ошибкой
Гуглил, пишут, что проблема связана скорее всего с DNS, тк сижу под виртуалкой, пробовал несколько рецептов, в тч указывал DNS в daemon.js, раскоментировал строчку DOCKER_OPTS. Ничего не помогает. Также пробовал использовать dockerfile последней версии из вашего хранилища, в этом случае ошибка другая, не может найти ни один пакет.
Помогите пожалуйста разобраться
Дмитрий, вы ещё на связи? А то странно, деньги за курс списываются, а фидбека нет :\
В общем, разобрался сам. Проблема была действительно связана с DNS. Необходимо создать файл /etc/docker/daemon.json со следующим содержимым:
после чего, как пишут, достаточно перезапустить докер демон, но мне помогла только перезагрузка ОС
Вот тут прям хорошо реализовал "от простого к сложному". Что-то уровня 10 файликов в курсе по ООП, или может быть даже выше.
я так понимаю что скрестить rpcjson и slim плохая идея?
Если в
index.php
вписать запуск RPC-сервера, то HTTP-фреймворк с контроллерами не пригодится.Но при желании можно сделать один контроллер и запускать сервер там, передавая ему сообщение из
$request->getBody()
и возвращая его ответ в виде$response
. Это может быть полезно если помимо RPC-сервера потребуются другие контроллеры.На текущий момент slim версии 4.9.
В примерах документации слим для роутов с плейсхолдерами типа
$app->get('/path/{id}', ....)
в классах с__invoke
они попадают третьим параметром$args
. Но в psrRequestHandlerInterface
нет такого, как достать?В PSR они попадают в атрибуты
$request->getAttribute('id')
Херак реально помог, годный плагин :D
С новым Composer v2 плагин уже не нужен.
Дмитрий, не подскажите насчет написания документации
Например для описания API можно использовать Swager
А для проектной документации, что можно было бы использовать?
Например чтоб описать флоу какого то процесса, добавить диаграмы - что то в этом роде
При хранении документации в коде диаграммы удобно сочинять текстом в файлах PlantUML. Для просмотра можно поставить его плагин в PhpStorm.
делаю make init и получаю ошибки, хотя с прошлого видео сервер настроен, сайт загружен, по домену открывается, SSL сертификат установлен...
Как можно поправить?
А эти папки точно есть?
Возможно накосячил где-то, у меня бывает. Я поздно подключился, да ещё на вин10. Постоянно то с пакетами беда, то с командами. Решу. Спасибо
Здравствуйте, Дмитрий! Правильно ли я понял, что версия php в контейнере composer всегда должна совпадать с версией php в контейнере php-fpm, иначе могут быть проблемы?
Да, версии PHP везде должны быть одинаковые. Иначе новый код на более старом PHP может падать с ошибками.
Спасибо за курс, Дмитрий! Возник вопрос - мы подключаем все конфиги из папок, и потом просто мерджим получившиеся массивы с настройками, но тогда возникает проблема, вдруг кто-то добавит новый файл с каким-то конфигом, и там будут такие же ключи как и в предыдущих файлах, и получается мы просто перезатрём предыдущие значения? Стоит ли проверять дублирующиеся ключи и выдавать понятную ошибку в таком случае.
Конфигурации собираются по группам вроде
'db'=>[...]
и'log'=>[...]
. Если кто-то добавит свою конфигурацию, то обычно создаст свою группу вроде'cache'=>[...]
. Так что чужие значения он этим врядли перезапишет.А если он в своём файле
cache.php
для кэша переопределит фабрику логгераLoggerInterface::class=>fn(...)
, то это само по себе будет выглядеть странно.Так что риск нечаянной перезаписи весьма мал.
Или войти через: