Laravel: внедрение зависимостей в команды

Возможно ли внедрение зависимостей пользовательского класса в command?

Я пытаюсь это:

<?php

namespace vendor\package\Commands;

use Illuminate\Console\Command;
use vendor\package\Models\Log;
use vendor\package\Updates\UpdateStatistics;

class UpdatePublishmentStats extends Command
{
    /**
     * The name and signature of the console command.
     *
     * @var string
     */
    protected $signature = 'vendorname:updatePublishmentStats';

    /**
     * The console command description.
     *
     * @var string
     */
    protected $description = 'Updates Twitter followers & Facebook page likes';

    /**
     * Contact implementation
     * @var vendor\package\Update\UpdateStatistics
     */
    protected $stats;

    /**
     * Create a new command instance.
     *
     * @return void
     */
    public function __construct(
        Log $log,
        UpdateStatistics $stats
    ) {
        parent::__construct();
        $this->log = $log;
        $this->stats = $stats;
    }

Но когда я пытаюсь сделать это:

public function handle()
{
    $this->stats->updateFbStats();

}

Я вдруг получаю Segmentation fault: 11

Когда я удаляю часть use vendor\package\Updates\UpdateStatistics;, я не получаю эту ошибку.

Так что я делаю неправильно здесь? Разве нельзя использовать внедрение зависимостей в команде?


person RW24    schedule 05.06.2016    source источник


Ответы (2)


Согласно разделу «Структура команд» документации 5.2 (https://laravel.com/docs/5.2/artisan#writing-commands):

«Обратите внимание, что мы можем внедрить любые зависимости, которые нам нужны, в конструктор команды. Контейнер службы Laravel автоматически внедрит все зависимости, указанные в конструкторе».

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

Что касается того, чтобы заставить его работать, для меня segfault указывает на что-то не так с классом UpdateStats, как на него ссылаются в контейнере службы или как он разрешается из контейнера службы.

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

Кроме того, если вы просто не можете заставить это работать, функция app() будет разрешать элементы из контейнера службы, когда вы хотите (хотя, просматривая документы 5.2, я больше не вижу ее, поэтому она может быть устаревшей - я вижу $this->app->make() однако).

Это может сработать для вас, если больше ничего не работает:

public function __construct(
    Log $log,
) {
    parent::__construct();
    $this->log = $log;
    $this->stats = app(UpdateStatistics::class);
}

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

Надеюсь хоть немного поможет.


Обновление функции app()

Таким образом, функция app() не задокументирована, но у меня сейчас установлена ​​версия 5.2, и файл helpers.php в Illuminate/Foundation определенно содержит эту функцию:

if (! function_exists('app')) {
    /**
     * Get the available container instance.
     *
     * @param  string  $make
     * @param  array   $parameters
     * @return mixed|\Illuminate\Foundation\Application
     */
    function app($make = null, $parameters = [])
    {
        if (is_null($make)) {
            return Container::getInstance();
        }

        return Container::getInstance()->make($make, $parameters);
    }
}

К сожалению, документация по API не включает никаких вспомогательных функций, но в текущей основной версии файла, версии 5.2 и версии 5.3 на Github есть функция:

person stratedge    schedule 05.06.2016
comment
Просто будьте осторожны, когда вы вводите зависимости в конструктор, потому что, если какой-либо из этих классов, которые вы вводите, запрашивает базу данных, ваш тест может сломаться из-за того, что Laravel разрешает введенные зависимости до запуска миграции - при создании приложения, то есть - person peterchaula; 21.08.2019

Вы можете внедрить любой сервис в метод handle:

Обратите внимание, что мы можем внедрить любые зависимости, которые нам нужны, в метод команды handle.

Источник: https://laravel.com/docs/5.8/artisan#command-structure< /а>

person eightyfive    schedule 07.03.2019