Создание нового ServiceProvider / Facade как пакета в Laravel 5

Я никогда раньше не работал с фреймворком (Zend, CakePHP и т. Д.) И, наконец, решил сесть и изучить его. Я начинаю с Laravel, потому что код выглядит красиво и в отличие от некоторых других фреймворков, которые я пытался установить, «Hello, World!» Пример сработал с первой попытки.

В настоящее время я хочу, чтобы мое приложение делало что-то очень простое:

  1. Пользователь отправляет запрос в виде: GET /dist/lat,lng

  2. Приложение использует удаленный IP-адрес и MaxMind для определения $latitude1 а также $longitude1

  3. Этот путь запроса анализируется для $latitude2 а также $longitude2

  4. Используя эти две позиции, мы вычисляем расстояние между ними. Для этого я использую PHP-класс WorldDistance Рафаэля Фрагозо

Поскольку я планирую повторно использовать эту функцию в более поздних проектах, было бы неправильно выбросить весь код в /app каталог. Две повторно используемые части приложения были:

  1. Поставщик услуг, который подключается к MaxMind и возвращает широту и долготу
  2. Поставщик услуг, который берет две точки на земном шаре и возвращает расстояние

Если я правильно строю фасады, то вместо моего routes.php файл, являющийся беспорядком замыканий внутри замыканий, я могу просто написать:

Route::get('dist/{input}', function($input){
$input = explode( "," , $input );

return Distance::getDistance( GeoIP::getLocation(), $input );
});

Начальная попытка

Для первого поставщика услуг я нашел Поставщик услуг Дэниела Стейнбека Laravel 5 GeoIP. Это не так легко установить, как следовало бы (мне пришлось скопировать вручную geoip.php к /config каталог, обновление /config/app.php от руки и беги composer update а также php artisan optimize) однако это сработало: просьба GET /test вернул всю мою информацию.

Что касается второго поставщика услуг, я начал с попытки подражать структуре каталогов и соглашению об именах файлов поставщика услуг GeoIP. Я подумал, что если бы у меня было такое же соглашение об именах, автозагрузчик мог бы найти мой класс. Итак, я создал /vendor/stevendesu/worlddistance/src/Stevendesu/WorldDistance\WorldDistanceServiceProvider.php:

<?php namespace Stevendesu\WorldDistance;

use Illuminate\Support\ServiceProvider;

class WorldDistanceServiceProvider extends ServiceProvider {

protected $defer = false;

public function register()
{
// Register providers.
$this->app['distance'] = $this->app->share(function($app)
{
return new WorldDistance();
});
}

public function provides()
{
return ['distance'];
}

}

Затем я добавил это к моему /config/app.php:

        'Stevendesu\WorldDistance\WorldDistanceServiceProvider',

Это терпит неудачу с фатальной ошибкой:

FatalErrorException in ProviderRepository.php line 150:
Class 'Stevendesu\WorldDistance\WorldDistanceServiceProvider' not found

Использование WorkBench

Так как это полностью провалилось, я решил, что должна быть какая-то другая файловая зависимость: возможно, без composer.json или без README, он сдается. Я не знаю. Итак, я начал изучать создание пакетов. Несколько поисков в Google по запросу «создать пакет laravel 5» оказались бесплодными. Или:

  1. Они использовали Laravel 4.2, и в этом случае совет был «запустите php artisan workbench vendor / package —resources»

Или же

  1. Они использовали Laravel 5, и в этом случае документы были совершенно бесполезны

Официальные документы Laravel 5 дают вам множество примеров кода, например:

Все, что вам нужно сделать, это сказать Laravel, где расположены представления для данного пространства имен. Например, если ваш пакет называется «курьер», вы можете добавить следующее в метод загрузки вашего поставщика услуг:

public function boot()
{
$this->loadViewsFrom(__DIR__.'/path/to/views', 'courier');
}

Это делает предположение, что вы есть поставщик услуг, чтобы поставить метод загрузки в

Ничто в документации не говорит о том, как создать поставщика услуг таким образом, чтобы он был действительно загружен Laravel.

Я также нашел несколько разные Ресурсы все из которых предполагают, что у вас есть хранилище, и вы просто хотите включить его в свое приложение, или предполагаете, что у вас есть «верстак». Ничего о создании нового пакета полностью с нуля.

В PHP Artisan даже не было команды «workbench», и в файле «workbench.php» не было /configтак что все, что я нашел, связанное с верстаком, ничего не стоило Я начал делать некоторые исследования на Workbench и нашел несколько разные вопросы на StackOverflow.

После долгого времени и некоторых экспериментов мне удалось получить laravel/workbench в мой composer.json, обновите composer, установите composer, вручную создайте файл конфигурации workbench.php и, наконец, используйте команду PHP Artisan Workbench для создания нового пакета:

php artisan workbench Stevendesu/WorldDistance --resources

Это создало каталог: /workbench/stevendesu/world-distance с количеством подкаталогов и только одним файлом: /workbench/stevendesu/world-distance/src/Stevendesu/WorldDistance/WorldDistanceServiceProvider.php

Этот класс провайдера услуг посмотрел по существу идентичный в файл, который я создал ранее, за исключением того, что он был в /workbench каталог вместо /vendor каталог. Я попытался перезагрузить страницу, и я все еще получил фатальную ошибку:

FatalErrorException in ProviderRepository.php line 150:
Class 'Stevendesu\WorldDistance\WorldDistanceServiceProvider' not found

Я тоже пробовал php artisan vendor:publish, Я действительно не знаю, что делает эта команда, и описание не помогло, так что, может быть, это поможет? Это не так.

Как создать нового поставщика услуг в качестве пакета, чтобы в будущих проектах я мог просто включить этот пакет и иметь все те же функции? Или, скорее, что я сделал не так, чтобы созданный пакет не работал?

4

Решение

После двух дней игры с этим мне удалось найти решение. Я предполагал, что структура каталогов сопоставлена ​​непосредственно с путем автозагрузчика, который он проверял (например, пытался получить доступ к классу). Stevendesu\WorldDistance\WorldDistanceServiceProvider посмотрел бы в vendor/stevendesu/world-distance/WorldDistanceServiceProvider) … это не тот случай.

Чтение исходного кода композитора, чтобы увидеть, как это на самом деле загружает файлы, он создает «карту классов» — по сути, гигантские массивы, отображающие классы в соответствующие им файлы. Этот файл создается при запуске composer update или же composer install — и он будет построен правильно, только если композитор знает детали вашего пакета. То есть — если ваш пакет включен в файл composer.json вашего проекта

Я создал локальный git-репозиторий вне своего приложения, затем добавил свой пакет в файл composer.json моего приложения и запустил composer update — вдруг все заработало отлично.

Для:

Это не так легко установить, как следовало бы

секретный соус здесь был первый добавить поставщика услуг в /config/app.php затем второй бежать php artisan vendor:publish

5

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]