实用工具对象Symfony 2



我试过几次使用symfony 2,但一直都被卡住了。这次我打算坚持下去!

到目前为止,我最大的问题是将在没有用户交互的情况下执行任务的对象放在哪里。

Ex。

我想创建一些php类,每天左右处理从几个网站解析一些数据。我希望手动或通过cron作业启动此任务。因此,我真的只需要模型和控制器。(用于解析站点并创建模型的控制器,用于存储解析数据并持久化到数据库的模型)。最好的方法是创建一个只处理这些背景工作的捆绑包。

我正在考虑以下课程:

  • SiteParser

    • Site1Parser扩展SiteParser
    • Site2Parser扩展SiteParser
  • 型号1

  • 型号2

  • 一些类负责协调不同站点的解析,并告诉创建的模型保持不变。

这看起来合乎逻辑吗?如果是这样的话,我该如何将这种结构放入symfony?

感谢您的任何帮助,如果我还不清楚,或者您有问题,请问我,我会提供所需的任何细节!

首先,我建议不要在这里使用控制器。请记住,控制器的目的是在模型和视图之间进行中介。对于自动化流程,您并没有真正的视图——没有人查看或读取您的输出(您可能想要实现一些日志记录,但这是另一回事)。

也就是说,我想说,你最好的选择是使用Symfony内置的控制台命令功能创建一个命令。您可能已经使用app/console命令工具来执行诸如生成bundle和创建实体映射之类的操作。使用ContainerAwareCommand类,您实际上可以编写自己的。最棒的是命令知道容器。。。换句话说,您可以使用get()方法直接访问Doctrine、Monolog、Twig或任何其他服务。

因此,假设您的应用程序从网站中提取图像,然后将这些图像的URL保存到数据库中。要做到这一点,您首先需要创建一个服务类(让我们将其放在MyBundle\service命名空间下),并为其提供必要的方法:

namespace MyBundleService;
class Parser
{    
public function extractImageUrls($siteUrl)
{
// Do whatever here, and return an array of URLs
}
}

然后您可以通过app/config/config.yml:将其注册为名为"解析器"的服务

services:
parser:
class: MyBundleServiceParser

现在,您可以从容器中调用get("parser")。控制器扩展了容器,因此在控制器中您可以说$this->get("parser"),但在控制台命令中您必须特别获得容器:$this->getContainer()->get("parser")

因此,您可以编写SiteParseCommand,使其看起来像这样:

namespace MyBundleCommand;
class SiteParseCommand extends ContainerAwareCommand {
protected function configure()
{
$this->setName("site:parse");
$this->addArgument("site", InputArgument::REQUIRED);
}
protected function execute(InputInterface $input, OutputInterface $output)
{
$parser = $this->getContainer()->get("parser");
$doctrine = $this->getContainer()->get("doctrine");
$em = $doctrine->getEntityManager();
$imageRepository = $em->getRepository("MyBundle:Image");
$site = $input->getArgument("site");
$images = $parser->getImageUrls($site);
// Add each image to the database as you normally would, using your entity manager
}
}

现在,从命令行,您可以调用:

app/console site:parse "http://url.com"

把它添加到crontab中,我认为你就可以开始了。

同样,由于没有视图,你将无法轻易判断一切是否正常。所以我会实现一些日志记录,让你知道发生了什么。由于Monolog也是一项服务,控制台命令也可以通过$this->getContainer()->get("logger")访问它。

希望这能有所帮助!

(点击此处查看ContainerwareCommand类的更多文档)

最新更新