Как настроить фасады в Laravel 5.2 (вне /app)

Я спрашиваю/отвечаю, потому что у меня было так много проблем с тем, чтобы это работало, и я хотел бы показать пошаговую реализацию.

Рекомендации:


person Martin    schedule 25.02.2016    source источник


Ответы (1)


Это может быть не единственный способ реализации фасадов в Laravel 5, но вот как я это сделал.

Мы собираемся создать собственный фасад Foo, доступный в пространстве имен Foobar.

1. Создайте собственный класс

Во-первых, для этого примера я создам новую папку в своем проекте. Он получит собственное пространство имен, которое облегчит поиск.

В моем случае каталог называется Foobar:

введите здесь описание изображения

Здесь мы создадим новый файл PHP с нашим определением класса. В моем случае я назвал это Foo.php.

<?php
// %LARAVEL_ROOT%/Foobar/Foo.php

namespace Foobar;


class Foo
{
    public function Bar()
    {
        return 'got it!';
    }
}

2. Создайте класс фасада

В нашу причудливую новую папку мы можем добавить новый файл PHP для нашего фасада. Я назову его FooFacade.php и помещу в другое пространство имен Foobar\Facades. Имейте в виду, что пространство имен в данном случае не отражает структуру папок!

<?php
// %LARAVEL_ROO%/Foobar/FooFacade.php

namespace Foobar\Facades;


use Illuminate\Support\Facades\Facade;

class Foo extends Facade
{
    protected static function getFacadeAccessor()
    {
        return 'foo'; // Keep this in mind
    }
}
  • Имейте в виду, что вы возвращаете в getFacadeAccessor, так как это понадобится вам через мгновение.

Также обратите внимание, что здесь вы расширяете существующий класс Facade.

3. Создайте нового провайдера, используя php artisan

Итак, теперь нам нужен новый модный провайдер. К счастью, у нас есть замечательный инструмент artisan. В моем случае я назову его FooProvider.

php artisan make:provider FooProvider

Бац! У нас есть провайдер. Подробнее о поставщиках услуг читайте здесь. Пока просто знайте, что у него две функции (boot и register). ) и добавим код в register. Мы собираемся связать нашего нового провайдера с нашим приложением:

$this->app->bind('foo', function () {
    return new Foo; //Add the proper namespace at the top
});

Таким образом, эта часть bind('foo' фактически совпадет с тем, что вы добавили в код FooFacade.php. Там, где я сказал return 'foo'; раньше, я хочу, чтобы это связывание соответствовало этому. (Если бы я сказал return 'wtv';, я бы сказал здесь bind('wtv',.)

Кроме того, нам нужно сообщить Laravel, где найти Foo!

Итак, вверху мы добавляем пространство имен

use \Foobar\Foo;

Проверьте весь файл прямо сейчас:

<?php
// %LARAVEL_ROOT%/app/Providers/FooProvider.php

namespace App\Providers;

use Illuminate\Support\ServiceProvider;
use Foobar\Foo;

class FooProvider extends ServiceProvider
{
    /**
     * Bootstrap the application services.
     *
     * @return void
     */
    public function boot()
    {
        //
    }

    /**
     * Register the application services.
     *
     * @return void
     */
    public function register()
    {
        $this->app->bind('foo', function () {
            return new Foo;
        });
    }
}
  • Убедитесь, что вы используете Foobar\Foo, а не Foobar\Facades\Foo — ваша IDE может предложить неправильное завершение.

4. Добавьте наши ссылки на config/app.php

Теперь мы должны сказать Laravel, что мы заинтересованы в использовании этих случайных файлов, которые мы только что создали, и мы можем сделать это в нашем файле config/app.php.

  1. Добавьте ссылку на класс вашего провайдера в 'providers': App\Providers\FooProvider::class

  2. Добавьте ссылку на свой фасадный класс в 'aliases': 'Foo' => Foobar\Facades\Foo::class

Помните, что в псевдонимах, где я написал 'Foo', вам нужно указать имя, с которым вы хотите сослаться на свой фасад. Поэтому, если вы хотите использовать MyBigOlFacade::helloWorld() в своем приложении, вы должны начать эту строку с 'MyBigOlFacade' => MyApp\WhereEverMyFacadesAre\MyBigOlFacade::class

5. Обновите composer.json

Последнее изменение кода, которое вам нужно, — обновить пробелы psr-4 вашего composer.json. . Вам нужно будет добавить это:

    "psr-4": {
        "Foobar\\" : "Foobar/",
        // Whatever you had already can stay
    }

Последний ход

Итак, теперь, когда вы все изменили, последнее, что вам нужно, это обновить кеши как в композиторе, так и в ремесленнике. Попробуй это:

composer dumpautoload
php artisan cache:clear

Использование и быстрый тест:

Создайте маршрут в app/routes.php:

Route::get('/foobar', 'FooBarController@testFoo');

Затем запустите

php artisan make:controller FooBarController

И добавьте немного кода, чтобы он выглядел так:

<?php

namespace App\Http\Controllers;

use Foobar\Facades\Foo;

use App\Http\Requests;

class FooBarController extends Controller
{
    public function testFoo()
    {
        dd(Foo::Bar());
    }
}

У вас должна получиться следующая строка:

введите здесь описание изображения


Поиск проблемы

  • Если вы получите сообщение об ошибке, говорящее, что он не может найти класс Foobar\Facades\Foo, попробуйте запустить php artisan optimize
person Martin    schedule 25.02.2016
comment
Пожалуйста! Если вы используете это руководство и что-то не работает, дайте мне знать, чтобы я мог это исправить! - person Martin; 26.02.2016
comment
Другое дело, я пропустил очистку кеша, и Laravel вернул мне ошибку Class not found, поэтому я запустил команду php artisan optimise и все заработало - person IlGala; 01.03.2016
comment
Спасибо @IlGala, я внес некоторые изменения, включая указатель на использование команды artisan optimize. - person Martin; 02.03.2016
comment
Какая польза Foobar\Join;? И, к сожалению, все, что я получаю в результате, это Class 'Foobar\Facades\Foo' not found. Следовали указаниям в письме. - person Jiho Kang; 23.08.2016
comment
Я изменил имена своих классов, прежде чем помещать их в SO. Я думаю, я забыл изменить это имя класса! Я думаю, должно читаться Foobar\Foo. - person Martin; 23.08.2016