#Создание пакета для Laravel 4 это перевод оригинальной статьи, без претензии на литературность. ##Вступление Одна из лучших вещей в Laravel 4 - это то, как он полностью выстроен вокруг идеи совместимости. Долгое время, в РНР-проектах было довольно трудно управлять зависимостями. Копирование и вставка кода в проект - это кошмар. А поддерживать компоненты в актуальном (up-to-date) состоянии, при таком подходе - очень сложно. Далеко не все разработчики использовали PEAR в своих проектах, а потому, в конечном итоге, с каждым новым проектом приходилось изобретать свой велосипед, вместо готовых решений предоставленных Сообществом.
Если вы выбрали какой-то фреймворк для совего проекта, Вам приходилось пользоваться компонентами только этого фреймворка, потому что нельзя было так просто взять и и переключиться на стороннее решение.
Однако с ростом популярности Composer, PHP (наконец-то) имеет свой менеджер пакетов, который призван решить данную проблему.
Laravel 4 с самого начала был устроен так, чтобы работать с Composer. Все компоненты его (laravel4) структуры, на самом деле, являются самостоятельными зависимостями, которые собраны все вместе под одним капотом. Что и позволяет очень легко переключатся между этими компонентами.
Кроме того, в Laravel 4 есть встроенные инструменты для создания собственных самостоятельных пакетов. А также, он дает возможность использовать очень красивый паттерн Facade, благодря чему, можно пользоваться красивым синтаксисом при работе с классами Вашего пакета.
В этом уроке я расскажу вам о создании вашего первого пакета в Laravel 4.
##Workbench Laravel 4 позволяет невероятно легко создавать новые пакеты. Для корректной работы пакета, нужно создать каталог с правильной файловой структурой. Эти действия могут занимать некоторое время. И поэтому Laravel 4 позволяет сгенерировать эти файлы автоматически, с помощю команд artisan.
Но прежде чем создать новый пакет, нужно настроить некоторые детали конфигурации. Откройте app/config/workbench.php и заполните поля: name и email. Данные этих полей будут включены в файл composer.json при генерации Вашего пакета.
После этого, мы можем сгенерировать новый пакет используя команду artisan.
php artisan workbench vendor/package --resources
Замените
vendor
иpackage
на имена, которые собираетесь использовать. Где:vendor
- это название поставщика (название Вашей компании/организации или просто Ваше имя); иpackage
- название Вашего пакета.
Например, если я создаю пакет, который называется supyo
, я должен ввести следующую команду:
php artisan workbench philipbrown/supyo --resources
Флаг --resources
говорит artisan'у создать пакет с дополнительными каталогами, рекомендоваными конкретно для Laravel. Если Вы создаете пакет, который может быть использован не только в Laravel, вы можете опустить этот флаг.
##Файловая труктура пакета
Теперь, если вы перейтдете в каталог vendor/workbench
, вы сможете увидеть папки содержащие сгенерированный пакет.
Перед тем как начать, не забудьте выполнить composer install
.
Если так вышло, что Вы получили "File not found error", но Вы уверены, что файлы названы коректно у Вас корректные "namespace", это обычно означает что composer еще не 'знает' о файле. Чтобы исправить это, вы можете просто запустить composer dump-autoload
. Это пересоберёт 'карту' классов пакета.
Если ваш пакет зависит от каких-то других пакетов, просто добавьте эти зависимости в массив "require"
в файлеcomposer.json
и запустите composer update
, как если бы Вы хотели добавить зависимости в Ваш основной проект.
Примечание: эти команды должны быть запущены в папке Вашего пакета, а не в корневой директории проекта.
Сначала сложность файловой стркутуры может показаться немного избыточной, но Вы поймете её, когда немного поработаете с пакетами в PHP.
- В папке
src
хранится весь код, который будет использоваться в проекте. - В папке
tests
хранятся тесты для вашего пакета. - А в папке
vendor
хранятся все внутренние зависимоти.
Обратите внимение, здесь также есть composer.json. Это очень важно для того, чтобы ваш пакет мог быть доступен на Packagist.
##Service Provider Вашего пакета.
Теперь, если вы углубитесь в каталог "src", вы сможете увидеть там файл Service Provider. Находящийся в /workbench/philipbrown/supyo/src/Philipbrown/Supyo/SupyoServiceProvider.php
.
Фaйл Service Provider - это что-то вроде отдельного файла bootstrap (bootstrap~ файл начальной загрузки приложения - п.п.) для этого пакета. Это просто файл, который расставляет все по своим местам (инициализирует пакет - п.п.), при запуске. Здесь мы просто должны задать некоторые настройки, так Laravel поймет, что делать с этим пакетом.
Сейчас Ваш файл Service Provider выглядит примерно так:
<?php namespace Philipbrown\Supyo;
use Illuminate\Support\ServiceProvider;
class SupyoServiceProvider extends ServiceProvider {
/**
* Indicates if loading of the provider is deferred.
*
* @var bool
*/
protected $defer = false;
/**
* Bootstrap the application events.
*
* @return void
*/
public function boot()
{
$this->package('philipbrown/supyo');
}
/**
* Register the service provider.
*
* @return void
*/
public function register()
{
//
}
/**
* Get the services provided by the provider.
*
* @return array
*/
public function provides()
{
return array('supyo');
}
}
Обратите внимение что у меня уже настроены методы boot()
и provides()
.
Теперь Вам нужно зарегистрировать Service Provider в конфиге Laravel. Откройте app/config/app.php
И добавьте ваш ServiceProvider в конец массива:
'providers' => array(
// --
'Philipbrown\Supyo\SupyoServiceProvider',
),
###Класс пакета
Далее мы можем создать главный класс этого пакета. В той же папке, где находится файл SupyoServiceProvider.php
создайте новый файл и назовите его Supyo.php:
<?php namespace Philipbrown\Supyo;
class Supyo {
public static function greeting(){
return "What up dawg";
}
}
Заметьте что я задал namespace для этого класса.
##Регистрация Service Provider
Сейчас, вернитесь в файл SupyoServiceProvider.php
, нам нужно зарегистрировать созданый класс с помощью Laravel IoC обертки. Я возможно расскажу вам как именно работают IoC обертки в будущем. Но все что Вам нужно знать сейчас - это то, что вы регистрируете класс, чтобы Laravel мог инстанцировать его (создавать экземпляры класса - п.п.).
Что бы сдеделать это, нам нужно изменить метод register
:
public function register()
{
$this->app['supyo'] = $this->app->share(function($app)
{
return new Supyo;
});
}
$this->app
- это всего лишь массив, в котором хранятся все экземпляры класса. ```$this->app->share`` это замыкание которое возвращает экземпляр Вашего класса. Это означает, что когда вы будете использовать данный пакет, это можно будет делать через IoC обертку.
##Создание Фасада Laravel использует прекрасный синтаксис - это делает написание кода чистым и элегантным. Хотя снаружи это выглядит как будто Laravel просто использует загрузку статических методов, Laravel на самом деле работает с этими классами извне - это и есть IoC обертка. Если все это не умещается в Вашей голове - не переживайте. Сейчас вам на самом деле не обязательно понимать, как это происходит. Я проведу Вас в глубины архитектуры и паттернов проектирования Laravel в будущих уроках.
Фасад позволяет Вам использовать Ваш класс подобным образом:
echo Supyo::greeting();
Это, как мы уже знаем, и есть фасад. Потому что это не то, как мы инстанцировали классы раньше (видимо, автор имеет ввиду опыт программирования до использования фасадов - п.п.).
Чтобы создать фасад, сначала создайте новую папку в директории Вашего пакета и назовите ее Facades. В этой папке создайте новый файл и назовате его Supyo.php и скопируйте туда следующий код:
<?php namespace Philipbrown\Supyo\Facades;
use Illuminate\Support\Facades\Facade;
class Supyo extends Facade {
/**
* Get the registered name of the component.
*
* @return string
*/
protected static function getFacadeAccessor() { return 'supyo'; }
}
Далее, добавьте метод register
в ваш Service Provider:
$this->app->booting(function()
{
$loader = \Illuminate\Foundation\AliasLoader::getInstance();
$loader->alias('Supyo', 'Philipbrown\Supyo\Facades\Supyo');
});
Это позволит фасаду работаеть без небходимости добавлять его в массив Alias в файле app/config/app.php
. Спасибо Chris Fidao за это замечание.
Теперь Вы готовы увидеть Ваш пакет в бою.
Откройте Ваш routes.php
и введите следующее:
Route::get('/test', function(){
echo Supyo::greeting();
});
Поднимите сервер и прейдет адресу /test
, вы должны увидеть приветствие выведенное на экран.
##Заключение Это был обзор того как создаются пакеты в Laravel 4. Мы затронули несколько важных аспектов работы Laravel 4. В частности, как обертки IoC позволяют Laravel иметь прекрасный синтаксис оставаясь легко тестируемым.
Не переживайте, если какие-то концепции в данном уроке показались Вам непонятными. Этот урок лишь по созданию нового пакета для Laravel. В будущем, я намного глубже рассмотрю некоторые красивые паттерны Laravel и то как он был написан для облегчения тестирования, сохраняя при том красивый выразительный синтаксис.