структура папок для очистки в Laravel, используя Goutte - PullRequest
0 голосов
/ 07 ноября 2019

Я немного озадачен структурой папок для очищающего кода. Использование console/commands, а не controller. Итак, в handle function я пишу весь код очистки. Но я должен предположить, чтобы сделать это? Или ... каков наилучший подход для этого?

ОБНОВЛЕНО

Если я правильно понял ответ ниже. Это должно выглядеть прямо сейчас.

услуги вызова

class siteControl extends Command
{

    protected $signature = 'bot:scrape {website_id}';

    protected $description = 'target a portal site and scrape';

    public function __construct()
    {
        parent::__construct();
    }

    public function handle()
    {
        $website_id = $this->argument("website_id");
        if ($website_id == 1) {
            $portal = "App\Services\Site1";
        }

        $crawler = new $portal;
        $crawler->run();

    }
}

в методе управления

class Site1 extends Utility 
{

    public function __construct()
    {
        parent::__construct();
    }

    public function run()
    {        
        echo "method runs";
    }
}

аннотация:

use Goutte\Client;

abstract class Utility implements SiteInterfaces
{

    protected $client;

    public function __construct()
    {
        $this->client = new Client();
    }

} 

интерфейсы:

namespace App\Services;

interface SiteInterfaces
{
    public function run();
}

и наконец, я должен написать весь очищающий код внутри метода run ()? Пожалуйста, поправьте меня. Если я ошибаюсь по этому поводу ... Я ищу лучшее решение.

1 Ответ

1 голос
/ 08 ноября 2019

Рекомендуется вызывать отдельную службу из вашего метода handle(). Таким образом, вы можете использовать эту же службу в контроллере, например.

Техническая версия:

  1. Вашему приложению дается конкретная вещь, которую нужно сделать (команда, если хотите). Эта команда поступает извне вашего приложения, которое может быть чем угодно, от веб-контроллера до контроллера API или приложения CLI. С точки зрения гексагональной архитектуры это называется port .
  2. После того, как приложение получит такую ​​команду, его не должно волновать, с какого порта оно пришло. Обрабатывая все подобные команды в одном месте (обработчик команд), он не должен беспокоиться о происхождении команды.

Итак, чтобы дать вам краткий обзор:

[Web request]  [CLI command]       <-- these are ports
       \           /
        \         /
         \       /
         [Command]                <--- this is a method call to your service
             |
             |
             |
     [Command handler]            <--- this is the service doing the actual work

Обновил мой ответ

На основе предоставленного вами кода я реализовал то, что упомянул выше, так:

app / Console / Command / BotScrapeCommand.php

Этокоманда CLI, о которой я упоминал выше. Все, что должен сделать этот класс, это: 1. Собрать входные аргументы;(website_id) в этом случае 2. Оберните эти аргументы в команду 3. Запустите команду, используя обработчик команды

namespace App\Console\Commands;

use App\Command\ScrapePortalSiteCommand;
use CommandHandler\ScrapePortalSiteCommandHandler;

class BotScrapeCommand extends Command
{
    protected $signature = 'bot:scrape {website_id}';

    protected $description = 'target a portal site and scrape';

    public function handle(ScrapePortalSiteCommandHandler $handler)
    {
        $portalSiteId = $this->argument("website_id");
        $command = new ScrapePortalSiteCommand($portalSiteId);
        $handler->handle($command);
    }
}

app / Command / ScapePortalSiteCommand.php

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

namespace App\Command;


class ScrapePortalSiteCommand
{
    /**
     * @var int
     */
    private $portalSiteId;

    public function __construct(int $portalSiteId)
    {
        $this->portalSiteId = $portalSiteId;
    }

    public function getPortalSiteId(): int
    {
        return $this->portalSiteId;
    }
}

app / CommandHandler / ScrapePortalSiteCommandHandler.php

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

namespace App\CommandHandler;

use App\Command\ScrapePortalSiteCommand;
use App\Crawler\PortalSite1Crawler;
use App\Crawler\PortalSiteCrawlerInterface;
use InvalidArgumentException;

class ScrapePortalSiteCommandHandler
{
    public function handle(ScrapePortalSiteCommand $command): void
    {
        $crawler = $this->getCrawlerForPortalSite($command->getPortalSiteId());
        $crawler->crawl();
    }

    private function getCrawlerForPortalSite(int $portalSiteId): PortalSiteCrawlerInterface {
        switch ($portalSiteId) {
            case 1:
                return new PortalSite1Crawler();
            default:
                throw new InvalidArgumentException(
                    sprintf('No crawler configured for portal site with id "%s"', $portalSiteId)
                );
        }
    }
}

app / Crawler / PortalSiteCrawlerInterface.php

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

namespace App\Crawler;


interface PortalSiteCrawlerInterface
{
    public function crawl(): void;

}

app / Crawler / PortalSite1Crawler.php

Это то, к чему относится реализация фактического извлечения.

namespace App\Crawler;


class PortalSite1Crawler implements PortalSiteCrawlerInterface
{
    public function crawl(): void
    {
        // Crawl your site here
    }
}

Другое обновление

Поскольку у вас было дополнительных вопросов Я обновил свой ответ еще раз.

:void

Использование : voidв объявлении метода означает, что метод не будет ничего возвращать. Точно так же public function getPortalSiteId(): int означает, что этот метод всегда будет возвращать целое число. Использование возвращаемых шрифтов было добавлено в PHP 7 и не относится к Laravel. Дополнительную информацию о возвращаемых типах можно найти в документации PHP .

Команды и обработчики

Использование команд и обработчиков команд - это лучшая практика, которая является частьюшаблон командного автобуса. Этот шаблон описывает универсальный способ работы с пользовательским вводом (команда). Этот пост предлагает хорошее объяснение команд и обработчиков. Кроме того, в этом блоге более подробно описывается, что такое командная шина, как она используется и каковы ее преимущества. Обратите внимание, что в приведенном мною коде сама реализация шины пропущена. На мой взгляд, вам это не нужно само по себе, но в некоторых случаях оно действительно повышает ценность.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...