Несколько месяцев назад вышла альфа версия Composer плагина Symfony Flex. С выпуском Symfony 3.3 стало возможным протестировать работу данного плагина и «попробовать на вкус» подход к построению приложений на Symfony 4. Что мы сейчас и попробуем сделать.

В предыдущем посте я писал про структуру приложения Symfony 4 и некоторых особенностях, поэтому сейчас заострять внимание на этом не буду. Для того, чтобы процесс установки прошел гладко, рекомендую пользователям Windows использовать GitBash или Cygwin терминал. Вообще-то вы можете использовать любой терминал, главное чтобы в окружении была доступна утилита make и установленные linux-tools. Так же вам понадобится PHP версии ^7.1.3

Symfony Flex


Несколько слов о самом плагине. Symfony Flex берет на себя заботу по настройке компонент, устанавливаемых в ваше приложение с помощью Composer. Это не обязательно должны быть компоненты Symfony. Плагин работает с рецептами. Если рецепт для пакета определен в репозитории, то Symfony Flex сделает свою работу, в противном случае вам придется как и раньше настроить все руками.

На данный момент существует два репозитория рецептов, главный (или официальный) и публичный. Главный репозиторий отличается тем, что может определять алиасы для пакетов и размещение рецепта в этот репозиторий должно быть одобрено core-team Symfony. В публичном репозитории более мягкие правила для размещения.

Установка плагина


Первым делом установим Symfony Flex:

composer require symfony/flex

С этого момента плагин контролирует процесс установки пакетов в ваше приложение. Чтобы получить простое «Hello World» приложение установим symfony/framework-bundle. Мы уже можем воспользоваться «магией» Symfony Flex плагина и использовать удобный алиас для этого:

composer req frameworkbundle

Теперь давайте посмотрим на структуру каталогов:

/etc
/src
/vendor
/web
.env
.env.dist
.gitignore
composer.json
composer.lock
Makefile

В каталоге /etc, теперь находится вся конфигурация и файл bundles.php, который содержит массив всех бандлов установленных в вашем проекте. Этот файл модифицируется плагином Symfony Flex, каждый раз когда вы устанавливаете или удаляете бандл. Если вы хотите использовать локальный бандл, вам придется самостоятельно прописать его в этот файл.

Для конфигурации контейнера предусмотрен файл container.yaml, для роутинга routing.yaml. Так же в /etc вы увидите каталог packages, в котором хранятся минимальные конфигурации по умолчанию для всех компонентов. По сути эти конфигурации копируются из рецептов.

В каталоге /src, располагается класс Kernel, переработанный под новую структуру каталогов. Так же здесь есть пустой каталог Controller.

В папке /web теперь только index.php для всех видов окружения. Если посмотреть содержимое этого файла, можно заметить, что для имитации присутствия переменных окружения используется компонент symfony/dotenv. Этот компонент поставляется по умолчанию с symfony 3.3. В режиме разработки он позволяет определять переменные окружения в файле .env

Давайте установим этот компонент:

composer req symfony/dotenv

Теоретически мы установили минимальный набор компонентов необходимых для запуска приложения. Но есть один нюанс. По умолчанию рецепты поставляются с конфигурацией в YAML. И поэтому даже если собственные конфигурации вы хотите писать в другом формате, вам все равно придется установить компонент symfony/yaml, чтобы конфигурации всех компонентов могли быть загружены. В противном случае вам придется переписывать все конфиги в каталоге /etc/packages в нужный вам формат каждый раз когда вы добавляете новый компонент.

Давайте установим symfony/yaml:

composer req symfony/yaml

Почти все готово. Осталось немного «поколдовать» над файлом composer.json. Первое, что нужно сделать это прописать секцию psr-4, для автозагрузки наших классов. Так как весь код у нас лежит теперь прямо в /src, добавим:

{
    "autoload": {
        "psr-4": {
            "App\\": "src/"
        }
    }
}

Обратите внимание на следующую секцию в composer.json:

{
    "scripts": {
        "auto-scripts": {
            "make cache-warmup": "script",
            "assets:install --symlink --relative %WEB_DIR%": "symfony-cmd"
        }
    }
}

В эту секцию плагин Symfony Flex, добавляет необходимые вызовы команд для каждого компонента. Данные вызовы прописаны в рецептах. При текущей конфигурации, секция «auto-scripts» не будет исполнена плагином. Для того, чтобы это исправить нужно добавить вот такие параметры:

        "post-install-cmd": [
            "@auto-scripts"
        ],
        "post-update-cmd": [
            "@auto-scripts"
        ]

Этот шаблон позволяет плагину Symfony Flex включиться в процесс при наступлении событий «post-install» и «post-update» композера.

Финальный вид composer.json
{
    "require": {
        "symfony/flex": "^1.0",
        "symfony/framework-bundle": "^3.3",
        "symfony/dotenv": "^3.3",
        "symfony/yaml": "^3.3"
    },
    "autoload": {
        "psr-4": {
            "App\\": "src/"
        }
    },
    "scripts": {
        "auto-scripts": {
            "make cache-warmup": "script",
            "assets:install --symlink --relative %WEB_DIR%": "symfony-cmd"
        },
        "post-install-cmd": [
            "@auto-scripts"
        ],
        "post-update-cmd": [
            "@auto-scripts"
        ]
    }
}


Теперь попросим Composer пересобрать класс автозагрузки:

composer dump-autoload

Самое время добавить контроллер. Создадим в папке /src/Controller класс TestController:

namespace App\Controller;
use Symfony\Component\HttpFoundation\Response;

class TestController
{
    public function test()
    {
        return new Response('It works!');
    }
}

Теперь нужно прописать маршрут в файле /etc/routing.yaml:

index:
  path: /
  defaults: {_controller: 'App\Controller\TestController::test'}

Запускаем веб-сервер с помощью make:

make serve

Переходим в браузере по 127.0.0.1:8000 и видим наше сообщение «It works!».

Минимальное приложение собрано и запущено, но хочется использовать аннотации для определения маршрутов. Без проблем! Для этого нам потребуется sensio/framework-extra-bundle и symfony/annotations-pack, для последнего предусмотрен удобный алиас annot.

composer req sensio/framework-extra-bundle

composer req annot

Теперь закомментируем маршрут в файле routing.yaml, который определили до этого и вместо него укажем где лежат наши классы контроллеров для парсера аннотаций:

controllers:
    resource: ../src/Controller/
    type: annotation

Изменим наш контроллер, добавив аннотацию для маршрута (не забудьте так же добавить use Sensio\Bundle\FrameworkExtraBundle\Configuration\Route):

namespace App\Controller;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Route;
use Symfony\Component\HttpFoundation\Response;

class TestController
{
    /**
     * @return Response
     * @Route("/test", name="test")
     */
    public function test()
    {
        return new Response('It works!');
    }
}

Переходим по 127.0.0.1:8000/test и видим наше сообщение. Если нам больше не нужно использовать аннотации, то мы можем удалить компоненты:

composer rem annot
composer rem sensio/framework-extra-bundle

Останется только вернуть настройки роутинга в routing.yaml, и все будет работать. Плагин Symfony Flex позаботится о том, чтобы удалить за собой весь мусор, а так же убрать из конфигурации бандл sensio/framework-extra-bundle.

Вот таким образом можно уже сейчас экспериментировать с приложениями в стиле Symfony 4.
По правде говоря, вы можете воспользоваться уже готовым composer.json файлом для установки такого приложения «из коробки»:

composer create-project "symfony/skeleton:^3.3" demo

Я описал процесс ручной сборки проекта, чтобы акцентировать внимание на некоторых деталях.
Исходники проекта можно посмотреть тут.

Спасибо за внимание.
Поделиться с друзьями
-->

Комментарии (4)


  1. VolCh
    25.06.2017 13:49
    +1

    А разобрались, что будет, когда рецепт в репозитории обновится? Как я понял, рецепты работают только при начальной установке пакета и если, например, в index.php найдутся какие-то баги, то обновления сами не прилетят. Или прилетят?


    1. shude
      25.06.2017 13:56
      +1

      Интересный вопрос. В данный момент пишу пост как раз с подробным разбором рецептов. Обязательно этот момент разберу. На вскидку сразу приходит две мысли: с одной стороны механизмы позволяют сделать обновление при изменении рецепта, с другой, учитывая тот факт, что вы можете определять настройки и модифицировать файлы установленные по рецептам, возникает проблема с правильным объединением изменений. Я обязательно разберусь в этом вопросе. Спасибо за идею.


  1. himik_od_ua
    28.06.2017 10:41

    Уточните в своем посте, что Flex требует установленного PHP 7.1. Ниже версии не поддерживаются от слова совсем.


    1. shude
      28.06.2017 11:22

      Спасибо, добавил.