Laravel тегирует весь класс, реализующий интерфейс

Я использую Laravel 8 и хочу получить все классы, реализующие интерфейс X.

Я сделал это с symfony4 несколько месяцев назад с DI:

services.yml

_instanceof:
    App\Calculator\Budget\BudgetCalculatorInterface:
      tags: ['app.budget_calculator']
App\Handler\CalculatorBudgetHandler:
  arguments: [!tagged app.budget_calculator]

а затем в моем классе CalculatorBudgetHandler.php

private $calculatorList = [];

public function __construct(iterable $calculatorList)
{
    $this->calculatorList = $calculatorList;
}

public function __construct(iterable $calculatorList)
{
    $this->calculatorList = $calculatorList;
}

public function calculate(array $data): float
{
    foreach ($this->calculatorList as $calculator) {
        if ($calculator->supports($data)) {
            return $calculator->calculate($data);
        }
    }

  
}

но я не понимаю, как это сделать с Laravel. Я думаю, мне нужно передать все мои классы в привязке или теге:

$this->app->tag([CpuReport::class, MemoryReport::class], 'reports');

это означает, что если у меня есть новый класс, реализующий X, я должен добавить его в привязку / тег? Я хочу делать это автоматически.

Спасибо !

У вас должен связывать интерфейс, это действительно просто! Ознакомьтесь с документацией ...

matiaslauriti 05.04.2021 06:50

@matiaslauriti уже прочитал это, но до сих пор не понимаю, как я получу все свои классы?

totoche 05.04.2021 08:39

извините, что вы не понимаете? вы можете дополнить свой вопрос примером? Если вы скажете «все еще не могу понять, как я получу все мои классы», вы потеряли меня там, объясните подробнее.

matiaslauriti 05.04.2021 20:13

@matiaslauriti Я обновил свой пример с помощью symfony. предположим, что у вас есть 3 класса: A, B, C, все реализующие интерфейс X. Я хочу получить все классы, реализующие X в итерируемом / массиве, для foreach в этих классах, в обработчике, команде или чем-то еще. и если я создаю новый класс D, реализующий X, я не хочу добавить новую строку, например $ this-> app-> bind (InterfaceX :: class, ClassD :: class); В основном в моем примере с symfony все мои классы, реализующие интерфейс, помечены, и с помощью DI я отправляю все эти помеченные классы в обработчик

totoche 06.04.2021 01:29

Я все еще не понимаю, извините. Вы говорите, что не хотите делать $this->app->bind(InterfaceX::class, ClassA::class);, а затем ClassB, ClassC, и если у вас есть новый, например ClassD, тоже не делайте этого снова? Если вы ответили «да», вы не сможете сделать даже больше 1, если вы сделаете больше 1 bind, вы замените класс. Идея interface состоит в том, чтобы всегда возвращать один и тот же класс для этого интерфейса. Я думаю, вы можете указать, что в контроллере X вам нужен ClassA, но на контроллере Y вам нужен ClassB (с использованием интерфейсов), но это не нормально для Laravel.

matiaslauriti 06.04.2021 15:14

Вы можете сделать public function __construct(ClassA $class) и на другом контроллере или классе public function __construct(ClassB $class), и он будет автоматически введен Laravel.

matiaslauriti 06.04.2021 15:14

то, что вы делали на Symfony, не имеет смысла, зачем вам интерфейс, но нужно определить, что ему нужно (разные классы на каждом контроллере)? Имеет смысл, чтобы каждый класс реализовывал интерфейс, но когда вы переходите к каждому контроллеру, явно определяйте, что вам нужно, поскольку этот контроллер уникален для маршрута, он не является «многоцелевым» (поэтому не имеет смысла).

matiaslauriti 06.04.2021 16:41

Как вы, возможно, сейчас, если вам требуется Model для каждого маршрута, вам не требуется его интерфейс (не имеет значения, существует он или нет), вам явно требуется модель, которая вам нужна. Сделайте то же самое со своим примером. Идея интерфейса binding состоит в том, чтобы требовать интерфейс везде, где вам нужен единственный связанный класс.

matiaslauriti 06.04.2021 16:42

@matiaslauriti покажи это другим способом, без интерфейсов. я должен отправить товары. У меня есть класс для каждого оператора (ups, fedex ...), чтобы выбрать моего оператора. У меня есть свойство (или несколько свойств) для проверки в модели продукта. я хочу избежать в моем обработчике большого переключателя или, если так: if ($ productModl-> property == '' foo ") {$ carrier = new UpsCarrier ();} elseif () ... так что мне нравится находить способ зацикливаться на всех моих несущих классах, как в моем примере в symfony. для этого мне нужен способ внедрить все эти классы в мой конструктор или каким-либо другим способом их получить.

totoche 06.04.2021 16:56

@matiaslauritii не понял ваш комментарий к моему коду Symfony? Я не использую это в контроллере.

totoche 06.04.2021 17:02

Хорошо, позвольте мне спросить еще раз: где вы пытаетесь использовать этот код? Вижу класс CalculatorBudgetHandler. Где используется этот класс? Можете дать мне больше информации? Он используется в контроллере? Что вы передаете этому классу обработчика? Я думаю, что ваше исправление будет заключаться в том, чтобы понять шаблон, который вы используете, и, возможно, сделать это в стиле Laravel с шаблоном или изменить его на другой, который станет лучше вместе с Laravel.

matiaslauriti 06.04.2021 17:12

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

matiaslauriti 06.04.2021 17:15

@matiaslauriti да в основном. но интерфейс может быть не лучшим способом сделать это. Мне просто нужен способ получить все мои классы-носители, и если создать новый (PostCanadaCarrier.php или что-то еще), он должен быть автоматически в массиве классов. Если это возможно.

totoche 07.04.2021 16:41

Вы можете добиться чего-то подобного, но более сложного, вы можете следить за этим и, когда вам требуется итерация, вернуть массив желаемых классов, но я не уверен на 100%, что это сработает. Никогда так не делал!

matiaslauriti 07.04.2021 22:00
Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Оживление вашего приложения Laravel: Понимание режима обслуживания
Оживление вашего приложения Laravel: Понимание режима обслуживания
Здравствуйте, разработчики! В сегодняшней статье мы рассмотрим важный аспект управления приложениями, который часто упускается из виду в суете...
Коллекции в Laravel более простым способом
Коллекции в Laravel более простым способом
Привет, читатели, сегодня мы узнаем о коллекциях. В Laravel коллекции - это способ манипулировать массивами и играть с массивами данных. Благодаря...
Поиск нового уровня в Laravel с помощью MeiliSearch и Scout
Поиск нового уровня в Laravel с помощью MeiliSearch и Scout
Laravel Scout - это популярный пакет, который предоставляет простой и удобный способ добавить полнотекстовый поиск в ваше приложение Laravel. Он...
Освоение архитектуры микросервисов с Laravel: Лучшие практики, преимущества и советы для разработчиков
Освоение архитектуры микросервисов с Laravel: Лучшие практики, преимущества и советы для разработчиков
В последние годы архитектура микросервисов приобрела популярность как способ построения масштабируемых и гибких приложений. Laravel , популярный PHP...
Как построить CRUD-приложение в Laravel
Как построить CRUD-приложение в Laravel
Laravel - это популярный PHP-фреймворк, который позволяет быстро и легко создавать веб-приложения. Одной из наиболее распространенных задач в...
1
14
28
0

Другие вопросы по теме