文件夹结构,用于在Laravel中使用痛风刮削
我有点困惑我的文件夹结构的刮代码。使用文件夹结构,用于在Laravel中使用痛风刮削,laravel,Laravel,我有点困惑我的文件夹结构的刮代码。使用控制台/命令,而不是控制器。因此,在句柄函数中我编写了整个刮码。但是我应该这样做吗?或最好的方法是什么 更新 如果我正确理解下面的答案。现在应该是这样的 呼叫服务 class siteControl extends Command { protected $signature = 'bot:scrape {website_id}'; protected $description = 'target a portal site and sc
控制台/命令
,而不是控制器
。因此,在句柄函数中
我编写了整个刮码。但是我应该这样做吗?或最好的方法是什么
更新
如果我正确理解下面的答案。现在应该是这样的
呼叫服务
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()方法中编写整个刮片代码?请纠正我,如果这个错误。。。我正在寻找最好的解决办法 最佳做法是从命令
handle()
方法调用一个单独的服务。这样,您可以在控制器中重用相同的服务
技术版本:
[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/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/scrapportalsitecommandhandler.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
,意味着该方法不会返回任何内容。同样地,公共函数getportalsteid():int
意味着此方法将始终返回一个整数。返回类型提示的使用被添加到PHP7中,并且不是特定于Laravel的。有关返回类型提示的更多信息,请参阅
命令和处理程序
命令和命令处理程序的使用是一种最佳实践,它是命令总线模式的一部分。此模式描述了处理用户输入(命令)的通用方法。对命令和处理程序提供了很好的解释。此外,还详细介绍了什么是命令总线、如何使用命令总线以及命令总线的优点。请注意,在我提供的代码中,总线实现本身被跳过。在我看来,您本身并不需要它,但在某些情况下,它确实会增加价值。是的…………我试图将我从您的答案中理解的内容编码。但我不确定我做得对还是错。你能检查一下这个问题吗。我更新了它。嗨,泰特,我看到你在实施我提供的理论方面做出了很大的努力。我已经用我认为你的代码应该是什么样子更新了我的原始答案。如果你还有任何问题,请告诉我。你好,PtrTon,我真的很感谢你更新的答案。这让事情变得更清楚了。我知道如何设置文件夹结构,但最后我有两个问题。我知道这是因为我缺乏拉威尔的经验。所以1)什么是
:void
做什么。这段代码里到底是什么?2)我认为这是面向对象的东西,但我们真的应该创建ScapePortalSiteCommand.php
和scrapportalsitecommandHandler.php
还是由你决定?因为我在问题的siteControl.php
中做了类似的事情。我想知道有没有好的理由?再次感谢你,真的!我试图通过更详细地更新我的答案来澄清你的问题。
namespace App\Crawler;
class PortalSite1Crawler implements PortalSiteCrawlerInterface
{
public function crawl(): void
{
// Crawl your site here
}
}