[Перевод] 25 Laravel Tips and Tricks
Было время, достаточно недавно, когда PHP и его сообщество ненавидели. Главной штукой была про то, насколько ужасен PHP.Да, к сожалению, сообщество и экосистема просто были ниже сообществ других современных языков по уровню. Казалось, что предназначение PHP было прожить большинство времени в форме беспорядочных тем для WordPress.
Но позже, на удивление, вещи начали меняться — и достаточно быстро. Как будто пока ведьма помешивала горшочек, из ниоткуда начали появляться новаторские проекты. Наверно, самый заметный проект был Composer: наиболее полный менеджер зависимостей для PHP (как Bundler для Ruby или NPM для Node.js). В прошлом PHP разработчики были вынуждены совладать с PEAR (что было страшным сном, на самом деле), сейчас, благодаря Composer, они могут просто обновить JSON файл, и немедленно подтянуть все нужные зависимости. Здесь — профайлер, там — фреймворк для тестирования. Это занимает секунды.В переполненном мире PHP фреймворков, как раз, когда CodeIgniter начал выдыхаться, фреймворк Laravel Тэйлора Отвелла возник из пепла, чтобы стать любимцем общества. С таким простым и элегантным синтаксисом, создавать приложения с Laravel и PHP было абсолютной забавой! Далее, c четвертой версией фреймворка, полностью использовавшим Composer, наконец-то показалось, что для сообщества все вещи встают на места.
Хотите миграций (контроль версий базы данных)? Сделано! Как насчёт мощной реализации Active Record? Конечно, Eloquent сделает всё за вас. Как насчёт возможности тестировать? Безусловно! Маршрутизация (роутинг)? Непременно! Что насчёт хорошо протестированного HTTP слоя? Благодаря Composer, Laravel использует много превосходных Symfony компонентов. Когда доходит до дела, есть все шансы, что Laravel уже это может вам предложить!
Раньше PHP был похож на игру Дженга — в одном кубике от того, чтобы развалиться — вдруг, благодаря Laravel и Composer, загорелся свет в конце тоннеля. Так что уберем все намёки, и давайте пороемся во всем, что фреймворк может предложить!
1. Красноречивые запросы* Laravel предлагает одну из самых мощных реализаций Active Record в мире PHP. Скажем, у вас есть таблица orders вместе с Eloquent моделью Order. class Order extends Eloquent {} Мы с легкостью можем выполнить любое количество запросов в базу данных, используя простой и элегантый код PHP. Не надо разбрасываться беспорядочно SQL. Давайте получим все заказы. Order: all (); Готово! Или, может, эти заказы должны быть отсортированы по дате. Легко: $orders = Order: orderBy ('release_date', 'desc')→get (); А что, если вместо получения записи, нам надо сохранить нвоый заказ в базу. Мы, конечно, можем это сделать. $order = new Order; $order→title = 'Xbox One'; $order→save (); Готово! С Laravel, задачи, которые раньше были громоздкими для выполнения, теперь до смеха просты.* — Eloquent — название реализации Active Record в Laravel, а также в переводе с английского красноречивый.
2. Гибкая маршрутизация (роутинг) Laravel уникален тем, что может быть использован разными способами. Предпочитаете более простой и похожий на Sinatra роутинг? Laravel легко может это сделать, используя анонимные функции Route: get ('orders', function () { return View: make ('orders.index') →with ('orders', Order: all ()); }); Это может быть полезным для маленьким проектов и API, но есть большие шансы, что вам понадобятся контроллеры для большинства ваших проектов. Окей, Laravel это тоже умеет. Route: get ('orders', 'OrdersController@index'); Готово! Заметили, как Laravel растет по мере ваших потребностей? Уровень приспособления — вот, что делает фреймворк таким популярным сегодня.3. Отношения без проблем Что мы делаем в объектах, когда нужно определить отношения? Например, задача точно принадлежит пользователю. Как это указать в Laravel? Предположив, что нужные таблицы в базе данных созданы, мы только должны обратиться к связанным Eloquent моделям. class Task extends Eloquent { public function user () { return $this→belongsTo ('User'); } }
class User extends Eloquent { public function tasks () { return $this→hasMany ('Task'); } } Всё готово! Давайте получим все задачи пользователя с id = 1. Для этого нам понадобится всего 2 строчки кода. $user = User: find (1); $tasks = $user→tasks; Впрочем, так как мы указали отношение с обеих сторон, если мы захотим получить пользователя, за которым закреплена данная задача, это также легко сделать. $task = Task: find (1); $user = $task→user; 4. Связь формы с моделью Очень часто, будет полезным связать форму с моделью. Очевидный пример — когда Вы хотите изменить какую-то запись в базе. Связав форму с моделью, мы можем моментально заполнить поля формы данными из базы. {{ Form: model ($order) }}
$questions = Question: remember (60)→get (); Вот и всё! Теперь, в течение следующего часа, этот запрос будет храниться в кеше, и база будет нетронутой.6. Композиторы шаблонов Вы столкнётесь с ситуациями, когда несколько шаблонов потребуют некоторую переменную или кусок данных. Хороший пример этого — навигационное меню, которое отображает список тегов.Чтобы контроллеры были с минимальным кодом, Laravel предлагает композиторы шаблонов (вьюшек), чтобы управлять такими вещами. View: composer ('layouts.nav', function ($view) { $view→with ('tags', ['tag1', 'tag2']); }); Использовав этот кусок кода, в любой момент, когда подгружен файл layouts/nav.blade.php, у него (у файла) будет доступ к переменной $tags.7. Простая авторизация Laravel использует очень простой подход к авторизации. Просто передайте массив данных, которые Вы, скорее всего, получили из формы логина, в Auth: attempt (). Если предоставленный массив соответствует тому, что сохранено в таблице users, пользователь моментально будет авторизован. $user = [ 'email' => 'email', 'password' => 'password' ]; if (Auth: attempt ($user)) { // пользователь авторизован } Что если надо произвести выход при переходе, например на /logout URI? Route: get ('logout', function () { Auth: logout (); return Redirect: home (); }); 8. Ресурсы Работать RESTfully в Laravel также очень легко! Чтобы объявить контроллер ресурс, просто вызовите Route: resource () следующим образом. Route: resource ('orders', 'OrdersController'); Этот код зарегистрирует 8 роутов.GET /orders GET /orders/: order GET /orders/create GET /orders/: order/edit POST /orders PUT /orders/: order PATCH /orders/: order DELETE /orders/: order Далее, OrdersController может быть сгенерирован из командной строки:
php artisan controller: make OrdersController
В этом контроллере, каждый метод будет соответствовать одному из роутов, описанных выше. Например, /orders вызовет метод index, /orders/create — метод create и так далее.
Теперь у нас есть необходимая сила, чтобы с легкостью строить RESTful приложения и API.
9. Шаблонизатор Blade Да, PHP по натуре язык шаблонов, но он не стал слишком хорошим. Впрочем, ничего страшного. Laravel предлагает свой движок Blade, чтобы восполнить пробел. Просто назовите ваши шаблоны с расширением .blade.php, и они соответствующим образом будут парситься. Теперь мы можем делать следующее: @if ($orders→count ())
-
@foreach ($orders as $order)
- {{ $order→title }} @endforeach
Давайте проверим, что домашняя страница возвращает код ответа 200.
public function test_home_page () { $this→call ('GET', '/'); $this→assertResponseOk (); } Или, может, мы хотим проверить, что, когда контактная форма отправлена на сервер, пользователь перенаправлен на домашнюю страницу с сообщением. public function test_contact_page_redirects_user_to_home_page () { $postData = [ 'name' => 'Joe Example', 'email' => 'email-address', 'message' => 'I love your website' ]; $this→call ('POST', '/contact', $postData); $this→assertRedirectedToRoute ('home', null, ['flash_message']); } 11. Компонент «Дистанционное управление» Частью Laravel 4.1, который был выпущен в ноябре 2013, стала возможность написать консольную команду для Artisan, чтобы по SSH подключаться к серверу и выполнять любые действия. Просто используйте SSH фасад: SSH: into ('production')→run ([ 'cd /var/www', 'git pull origin master' ]); В метод run () передайте массив команд, а Laravel займётся всем остальным! Теперь, так как есть смысл выполнять команды в качестве Artisan команд, вам всего лишь нужно выполнить php artisan command: make DeployCommand и в метод fire () написать нужный код для выполнения деплоя.12. События Laravel предлагает элегантную реализацию шаблона Observer, которую вы можете использовать где угодно в Вашем приложении. Подписывайтесь на нативные события, такие, как illuminate.query, или запускайте и слушайте свои собственные.Продуманное использование событий даст вам много возможностей.
Event: listen ('user.signUp', function () { // выполните то, что надо, // когда пользователь регистрируется }); Как и большинство вещей в Laravel, если вы предпочитаете указывать название класса, а не анонимную функцию, вы можете спокойно это сделать. Laravel разрулит всё, используя IoC контейнер. Event: listen ('user.signUp', 'UserEventHandler'); 13. Покажите маршруты Приложение растёт, и может стать тяжело посмотреть, какие роуты описаны. Особенно, если Вы не уделяли должного внимания файлу routes.php (например, излишния описания роутов).
Laravel предлагает удобную команду routes, которая покажет все зарегистрированные роуты, наряду с методами контроллеров, которые эти роуты вызывают.
php artisan routes 14. Очереди Подумайте о событии, когда пользователь регистрируется в Вашем приложении. Скорее всего, произойдет некоторое количество побочных событий. База данных должна быть обновлена, должен увеличиться счёт, письмо приветствия должно быть отправлено, и так далее. К сожалению, такие действия имеют тенденцию занимать много времени.Зачем заставлять пользователей ждать, пока произойдут эти события, если мы можем отправить выполняться эти события в бекграунде?
Queue: push ('SignUpService', compact ('user')); Наверно, самое замечательно, это то, что Laravel превосходно работает с Iron.io «push» очередями. Это значит, что даже не имея опыта работы с воркерами или демонами, мы всё равно можем использовать очереди. Просто опишите роут с помощью команды php artisan queue: subscribe, и Iron.io будет отправлять данные на этот урл каждый раз, когда задача отправлена в очередь. А этот роут в свою очередь выполнит нужные действия.15. Простая валидация Когда нужна валидация, Laravel снова приходит нам на помощь! Используя класс Validator как нельзя просто. Просто передайте объект для валидации вместе с правилами в метод make, а Laravel сделает всё остальное. $order = [ 'title' => 'Wii U', 'description' => 'Game console from Nintendo' ]; $rules = [ 'title' => 'required', 'description' => 'required' ]; $validator = Validator: make ($order, $rules); if ($validator→fails ()) { var_dump ($validator→messages ()); // validation errors array }
16. Tinker Особенно, если вы используете Laravel в первый раз, может быть полезным повозиться с ядром. Команда tinker поможет с этим.
Tinker использует популярный компонент Boris.
$ php artisan tinker
> $order = Order: find (1); > var_dump ($order→toArray ()); > array (…) 17. Миграции Думайте о миграциях, как о контроле версий базы данных. В любой момент, вы можете «откатить» миграции, вернуть их, обновить, и так далее. Наверно, сила миграций таится в том, чтобы запушить приложение в продакшн и просто выполнить команду php artisan migrate, чтобы сконструировать базу данных.Чтобы приготовить схема для новой таблицы users, мы можем выполнить: php artisan migrate: make create_users_table
Команда сгененерирует файл миграции, который вы наполните так, как вам нужно. Как будете готовы, команда php artisan migrate создаст таблицу. Вот и всё! Нужно откатить изменения? Легко! php artisan migrate: rollback.
Вот пример таблица для таблицы ЧаВО.
public function up () { Schema: create ('faqs', function (Blueprint $table) { $table→integer ('id', true); $table→text ('question'); $table→text ('answer'); $table→timestamps (); }); } public function down () { Schema: drop ('faqs'); } Обратите внимание, что метод drop () выполняет обратные действия метода up (). Это то, что позволяет «откатить» миграцию. Не правда ли, что это намного легче, чем мучаться с чистым SQL?18. Генераторы Laravel предлагает некоторое количество генераторов. Но также есть пакет, который называется «Laravel 4 Generators», и он зашел еще дальше. Он может генерировать ресурсы, файлы для наполнения базы, pivot таблицы и миграции.В предыдущем пункте мы были вынуждены были сами писать схему. Но используя пакет генераторов, мы можем выполнить команду:
php artisan generate: migration create_users_table --fields=«username: string, password: string» А генератор сделает всё остальное. С этой командой вы сможет подоготовить и создать новую таблицу в базе.Laravel 4 Generators может быть установлен через Composer.
19. Консольные команды Уже было описано некоторое количество случаев, когда полезно будет написать кастомные команды. Их можно использовать при построении приложений, генерации файлов, деплое приложений и все остального.Так как это распространенная задач, Laravel делает процесс создания команд наиболее простым.php artisan command: make MyCustomCommand
Это команда сгенерирует нужный шаблон для Вашей кастомной команды. Далее, в только что созданном файле app/commands/MyCustomCommand.php, заполните название и описание.
protected $name = 'command: name'; protected $description = 'Command description.'; И, в методе fire () выполните нужные действия. После этого останется только зарегистрировать команду для Artisan, в файле app/start/artisan.php. Artisan: add (new MyCustomCommand); Хотите верьте, хотите нет, но это всё! Теперь вы можете вызывать эту команду из терминала.20. Тестируйте фасады Laravel много использует шаблон Фасад. Это даёт возможность использовать «статический» синтаксис, который, без сомнений, Вам понравится (Route: get (), Config: get (), и так далее), и при этом позволяет полностью тестировать их.Так как «лежащий в основе» класс разруливается через IoC контейнер, мы легко можем подменить «нижние» классы с нашими тестовыми. Это позволяет нам делать следующее:
Validator: shouldReceive ('make')→once (); Да, мы вызываем shouldReceive прямо из фасада. «За кулисами», Laravel использует фреймворк Mockery. Это значит, что Вы абсолютно спокойно можете использовать фасады, и при этом тестировать абсолютно все куски кода.21. Хелперы форм Так как построение форм часто бывает громоздкой задачей, в дело вступает построитель форм в Laravel, чтобы облегчить этот процесс, а также использовать некоторые «особенности стиля», связанные с конструированием форм. Вот несколько примеров: {{ Form: open () }} {{ Form: text ('name') }} {{ Form: textarea ('bio') }} {{ Form: selectYear ('dob', date ('Y') — 80, date ('Y')) }} {{ Form: close () }} Что насчёт задачи запоминания введенных данных при прошлой отправке формы? Laravel это делает автоматически!22. IoC контейнер (Inverse of control) В ядре Laravel находится мощнейший IoC контейнер, который является инструментом, помогающим в управлении зависимостями класса. Стоит заметить, что у него есть мощь автоматически определять нужные классы без предварительных настроек.Просто сделайт typehint ваших зависимостей в конструкторе, и при инициализации Laravel, используя PHP Reflection API, грамотно прочитает ваши подсказки и постарается вставить эти классы за вас.
public function __construct (MyDependency $thing) { $this→thing = $thing; } Пока вы запрашиваете класс из IoC контейнера, разрешение зависимости произойдет автоматически. $myClass = App: make ('MyClass'); Важно заметить, что контроллеры всегда запрашиваются из IoC контейнера. Поэтому вы можете свободно делать typehint для зависимостей ваших контроллеров, а Laravel постарается внедрить их.23. Окружения Одно окружение может подойти для маленьких проектов. Для других проектов, несколько окружений — жизненно важно! Разработка, тестирование, продакшн. Всё это жизненно важно и каждое окружение требует своих настроек.Возможно ваше тестовое окружение использует базу данных в памяти для тестирование. Может ваше dev окружение использует другие ключи API. А продакшн окружение использует свои настройки подключения к базе.
К счастью, Laravel снова облегчает нашу работу. Взгляните на файл bootstrap/start.php.
Там находится простая демонстрация настройки local окружения, которое базируется на hostname компьютера.
$env = $app→detectEnvironment (array (
'local' => array ('your-machine-name'),
)); В общем, это будет работать. Но предпочтительнее использовать переменные окружения для таких вещей. Не беспокойтесь, это легко сделать в Laravel! Просто передайте функция в метод detectEnvironment. $env = $app→detectEnvironment (function () { return getenv ('ENV_NAME') ?: 'local'; }); Теперь, если переменная окружения не задана (а для продакшна Вы её установите), окружение будет иметь значение local.24. Простая настройка Laravel опять таки использует очень простой подход к конфигурированию. Создайте в папке app/config папку с названием окружения, и любые файлы конфигурации в этой папке будут иметь приоритет над другими, при условии, что вы находитесь в этом окружении. Например, можно задать другой API ключ для dev окружения. 'your-development-mode-api-key' ]; Конфигурация полностью автоматическая. Просто вызовите метод Config: get («billing.api_key») и Laravel сам определит из какого именно файла, считать это значение.25. Обучаемость Когда дело доходит до обучения, Laravel сообщество, несмотря на маленький возраст, бесконечно хорошее. В течение чуть более года, полдюжины разных книг, связанных с разработкой на Laravel, были опубликованы.