Может войдёшь?
Черновики Написать статью Профиль

Структура больших Laravel-приложений

перевод

При работе над большими Laravel-проектами всегда возникает вопрос: «Каким образом мне организовать весь этот код?» Многие люди начали предлагать новые пути решения данной проблемы. Довольно часто люди создают пространство имен в своих котроллерах, представлениях, составителях (view composers) и сервисе каталогов. Но для меня — это нечто паутины, состоящей из каталогов, и кричащей: «Я просто подгоняю все под MVC». Обычно я наблюдаю, как люди создают пространство имен с названиями типа API, Admin Panel и для самого сайта (Marketing). Таким образом, структура их приложения приобретает некий вид:

app/
|- Controllers/
|   |- Admin/
|   |- API/
|   |- Marketing/
|- Services/
|   |- Admin/
|   |- API/
|   |- Marketing/
|   |- // разные общие сервисы
|- Views/
|   |- admin/
|   |- marketing/
|   |- // какие-то общие представления
|- Models/
|- filters.php
|- routes.php

Давайте предположим, что вы нашли ошибку в коде панели управления администратора. Вы начинаете с подтягивания безумно большого файла routes.php, и находите маршрут, который приводит вас в каталог с контроллерами. Из каталога с контроллерами вы переходите в пространство имен PHPAdmin и неисправный контроллер. Теперь вам необходимо исправить ваше представление, которое, к примеру, вы назвали admin.dashboard.index. Теперь вам нужно вернуться в пространство имен PHPAdmin, подняться выше к контроллерам, а затем спуститься к вашим представлениям, еще ниже к каталогу admin и наконец, к файлу с представлением index.php.

Все становится сложнее с внутренними названиями. Представления и каталог с представлениями — это camelCase, контроллеры и пространство имен PHP — это PascalCase, URI маршрутов – это snake_case, а названия маршрутов зависят от вашего настроения в день их написания. Отчасти эта мешанина произошла по вине разработчика, отчасти – под влиянием различных соглашений разработчиков прежних PHP MVC-фреймворков. Итак, при работе над большими Laravel-проектами, я предлагаю проделать приличный рефакторинг.

На первом этапе, мы начнем с создания каталога с именем, равным названию нашего приложения, чтобы Composer смог использовать соглашение PSR-0 для выполнения автозагрузки классов. Мы назовем его Blog, и сложим туда папки Admin, API, и Marketing для организации кода. Теперь структура нашего приложения буде выглядеть следующим образом:

app/
|- Blog/
|   |- Admin/
|   |   |- Controllers/
|   |   |- Services/
|   |   |- Views/
|   |- API/
|   |   |- Controllers/
|   |   |- Services/
|   |- Marketing/
|   |   |- Controllers/
|   |   |- Services/
|   |   |- Views/
|- Services/
|   |- // разные общие сервисы
|- Views/
|   |- // какие-то общие представления
|- Models/
|- filters.php
|- routes.php

А для того, чтобы наши представления загрузились, мы должны использовать PHPView::addLocation для каждого пространства имен. Теперь пространство имен для наших контроллеров и сервисов просто необходимо обновить в routes.php и далее. Но я не рассказал настоящую правду о каталоге представлений… Каждый каталог представления будет иметь те же подкаталоги, как и прежде, аналогичные для PHPAdmin:

app/
|- Blog/
|   |- Admin/
|   |   |- Controllers/
|   |   |- Services/
|   |   |- Views/
|   |   |   |- admin/

Для меня это выглядит немного уродливо, и становится излишним при создании файлов с помощью командной строки (или с помощью плагина для редактора SublimeText2 Advanced New File, который мне нравится использовать). К тому же, мы сделали не так уж много для работы с нашими общими представлениями, фильтрами, или маршрутами. Поэтому теперь я собираюсь добавить поставщиков услуг в наш «общий котёл». Это позволит нам отделить эти места нашего приложения на маленькие приложения MVC с несколькими общими компонентами. Есть несколько трюков, которые мы будем использовать. Мы расположим наши представления в пространстве имен подобно тому, как пакеты регистрируют свои представления с помощью PHPView::addNamespace. Это позволит исключить из наших представлений дополнительный повторяющийся слой.

Мы начнем с наших общих компонентов и нашего поставщика услуг PHPBlog\ServiceProviders\Application.

PHP
<?php namespace Blog\ServiceProviders;

use 
Illuminate\Support\ServiceProvider;

class 
Application extends ServiceProvider
{
  public function 
register()
  {

  }

  public function 
boot()
  {
    
// Тут будут наши общие фильтры, такие как quest или admin
    
require_once(__DIR__.'/../filters.php');
    
View::addNamespace('Application'__DIR__.'/../views/');
  }
}

Наши общие представления теперь будут доступны в качестве PHPApplication::whateverViewWeWant. Еще у нас есть общие представления в нашем приложении. Мы также переместим наши модели и любые общие компоненты в app/Blog/Models.

Теперь, давайте посмотрим, как мы структурируем наши суб-приложения. Для нашего Blog\Applications\Admin\ServiceProviders\Admin сделаем следующее:

PHP
<?php namespace Blog\Applications\Admin\ServiceProviders;

use 
Illuminate\Support\ServiceProvider;

class 
Application extends ServiceProvider
{
  public function 
register()
  {

  }

  public function 
boot()
  {
    require_once(
__DIR__.'/../routes.php');
    
View::addNamespace('Admin'__DIR__.'/../views/');
  }
}

Теперь все наши представления панели управления администратора будут доступны как Admin::whatever. Для эстетического удовлетворения я также назвал мои маршруты в соответствии с нашими представлениями, и теперь заглавная страница интерфейса будет следующей — Admin::dashboard.index.

Теперь у нас есть хороший способ хранить наш код в разумном порядке, разделяя его на более мелкие под-приложения.

Если вы знакомы с Django, этот шаблон может показаться вам знакомым, так как я много позаимствовал оттуда за то короткое время, что я работал с Django.

Как вы считаете, полезен ли этот материал? Да Нет

Написать комментарий

Разметка: ? ?

Авторизуйся, чтобы прокомментировать.