Включение View Composers в Laravel с помощью Composer

Я сделал ниже composer view для своего приложения. Я поместил его в отдельный файл по адресу app/composers.php.

<?php

// namespace App\Modules\Manager\Composer;
// use Illuminate\Support\Facades\View as View ;

/*
|--------------------------------------------------------------------------
| Composers
|--------------------------------------------------------------------------
|
|
*/


View::composer('tshop.includes.header', function($view)
{

    $categories = Categories::getWithChilds();

    $view->withCategories( $categories);

});

Мой файл composer.php

"autoload": {
    "classmap": [
        "app/commands",
        "app/controllers",
        "app/models",
        "app/database/migrations",
        "app/database/seeds",
        "app/tests/TestCase.php"
    ],
    "files": [
        "app/composers.php"
    ]
},

К сожалению, я получаю эту ошибку

Fatal error: Class 'View' not found in C:\xampp\htdocs\eshop\app\composers.php on line 15

Обновлять

Я также пробовал это. Я написал внутри app/start/global.php

require app_path().'/composers.php';

а также

use Illuminate\Support\Facades\View as View ;

в app/composers.php, получая эту ошибку

Неустранимая ошибка: вызов функции-члена composer() для не-объекта в C:\xampp\htdocs\eshop\vendor\laravel\framework\src\Illuminate\Support\Facades\Facade.php в строке 211


person giannis christofakis    schedule 09.06.2014    source источник
comment
Вы сделали дамп-автозагрузку композитора после изменений?   -  person Laurence    schedule 16.06.2014
comment
@TheShiftExchange Да, я сделал.   -  person giannis christofakis    schedule 16.06.2014
comment
Ваша ошибка говорит о строке 15, но в вашем коде всего около 5 строк - можете ли вы опубликовать ВЕСЬ файл composers.php? Я так понимаю ошибка в другом?   -  person Laurence    schedule 16.06.2014
comment
@TheShiftExchange Я разместил весь код.   -  person giannis christofakis    schedule 16.06.2014
comment
Странный. Я попробовал это так, как вы упомянули, и, похоже, это работает для меня.   -  person SUB0DH    schedule 17.06.2014
comment
Вы упомянули, что пробовали require app_path().'/composers.php'; в global.php. Вы удалили "files": ["app/composers.php"] из вашего composer.json?   -  person Unnawut    schedule 18.06.2014


Ответы (2)


Как выяснил @TheShiftExchange, одна из проблем заключается в том, что вы использовали параметры «файлы».

Как вы можете видеть в коде композитора, раздел автозагрузки соответствует этому:

class ComposerAutoloaderInitf8489489s7f894ds98f47d
{
    ....
    ....
    public static function getLoader()
    {
        ....
        ....
        $includeFiles = require __DIR__ . '/autoload_files.php';
        foreach ($includeFiles as $file) {
            composerRequiref4s65f4556sd4f564fsdfd($file);
        }

        return $loader;
    }
}

function composerRequire5894s89f4sd98498489f7b37d($file)

{
    require $file;
}

Таким образом, указанный вами массив файлов требуется во время процесса автозагрузки композитора, задолго до загрузки фасада представления.

Поставщики фасадов загружаются в vendor/laravel/framework/illuminate/foundation/start.php

/*
|--------------------------------------------------------------------------
| Register The Core Service Providers
|--------------------------------------------------------------------------
|
| The Illuminate core service providers register all of the core pieces
| of the Illuminate framework including session, caching, encryption
| and more. It's simply a convenient wrapper for the registration.
|
*/

$providers = $config['providers'];

$app->getProviderRepository()->load($app, $providers);

На самом деле проблема с картами классов заключается в другом: они не являются классом в вашем файле, поэтому файл никогда не будет загружен, поэтому он ничего не делает.

Чтобы это работало, вы должны добавить в app/start/global.php в конце файла:

Вместо

require app_path() . '/filters.php';

Напишите

require app_path() . '/composers.php';
require app_path() . '/filters.php';

Это лучший способ, который я могу придумать, чтобы включать файлы при каждой загрузке вашего приложения, которые не являются классами.

person edi9999    schedule 16.06.2014

Я не думаю, что ваш app/composers.php должен автоматически загружаться в composer. Composer отвечает за разрешение пакетов и их установку для вас, что не имеет ничего общего с логикой вашего приложения, не говоря уже о представлениях вашего приложения.

На момент запуска composer он не будет знать о вашем приложении Laravel. Это означает, что ваши фасады Laravel, такие как View, Input, DB, Auth и т. д., еще не загружены. Таким образом, ваш код выдает Call to a member function composer() on a non-object.


Подход 1:

Laravel не указывает строго, где вы размещаете свои компоновщики представлений laravel, поэтому требуете этого, добавляя:

require app_path() . '/composers.php';

в нижней части app/start/global.php, как edi9999, было бы хорошо.

Не забудьте удалить в этом случае:

"files": [
    "app/composers.php"
]

Подход 2: есть способ автоматически загружать композиторы ваших представлений в composer.json!

Из примера в документах Laravel по композиторам представлений вы можете сделать что-то вроде...

приложение/viewcomposers/HeaderViewComposer.php:

class HeaderViewComposer
{
    public function compose($view)
    {
        $categories = Categories::getWithChilds();
        $view->withCategories( $categories);
    }
}

composer.json:

"classmap": [
    ...
    "app/viewcomposers"
]

app/composers.php:

View::composer('tshop.includes.header', 'HeaderViewComposer');

нижняя часть app/start/global.php:

require app_path() . '/composers.php';

К сожалению, вам все еще нужно добавить строку выше в app/start/global.php, чтобы Laravel знал, какие композиторы представлений определены.


Подход 3. Выполните автозагрузку класса в composer.json + зарегистрируйте пользовательский ServiceProvider

Уроки Использование View Composers в Laravel 4 от Филип Браун, мы могли бы также добавить нашего собственного поставщика пользовательских услуг и не редактировать наш файл app/start/global.php.

приложение/viewcomposers/HeaderViewComposer.php:

<?php namespace App\Modules\Manager\Composer;

class HeaderViewComposer
{
    public function compose($view)
    {
        $categories = Categories::getWithChilds();
        $view->withCategories( $categories);
    }
}

composer.json:

"classmap": [
    ...
    "app/viewcomposers"
]

приложение/viewcomposers/ViewComposerServiceProvider.php:

<?php namespace App\Modules\Manager\Composer;

use Illuminate\Support\ServiceProvider;

class ViewComposerServiceProvider extends ServiceProvider {

    public function register()
    {
        $this->app->view->composer('tshop.includes.header', 'App\Modules\Manager\Composer\HeaderViewComposer');
    }

}

приложение/config/app.php:

'providers' => array(
    ...
    'App\Modules\Manager\Composer\ViewComposerServiceProvider',
),
person Unnawut    schedule 18.06.2014