Symfony控制台与cron或任务计划结合任务运行程序

时间:2018-05-30 23:19:04

标签: php symfony cron

对于我的项目,我必须导入12-15个文件,从CSV,xml到gz不等。由于所有文件都有自己的结构,我必须为每个文件创建1个命令。但这太多了,想要为所有文件创建一般导入。

要求:

  • 导入脚本应该每小时运行一次
  • 导入脚本应该是导入类别+来自导入的产品
  • 导入脚本必须检查我的类别是否与导入的类别匹配,如果是,则应将信息添加到 数据库如果不被忽视。
  • 如果导入在后台导入,则导入不应影响网站。

目前我的命令是什么:

$handle = fopen("https://example.csv",'r');

$output->writeln('Downloading done!');

$categortArray = [];
$categortA = [];
while (($row = fgetcsv($handle, 4096, ";")) !== FALSE)
{
    $categortA [ $row[21]] = $row[23] ;
    $categortArray [] = $row[21];
}

$output->writeln('Updating category list !');
$result = array_unique($categortArray);
$result2 = array_unique($categortA);

$distributor = $distributor->findByName("Name of Distributor");

foreach ($result as $productgroup) {
    $result = $categoryRepository->findByTitle($productgroup);
    if (empty($result)){
        $category = new Category();
        $category->setTitle($productgroup);
        $category->setDescription("Category Description");
        $category->setDistributor($distributor);

        $categoryService->create($category);
    }
}

foreach ($result2 as $key => $productgroup) {
    $result = $categoryRepository->findByTitle($key);

    /** @var $result Category */
    if ($result !== null) {
        $category = new Category();
        $category->setTitle($productgroup);
        $category->setParent($result[0]);
        $category->setDescription("Name of Distributor");
        $category->setDistributor($distributor);

        $categoryService->create($category);
    }
}

while (($row = fgetcsv($handle, 4096, ";")) !== FALSE)
{

    foreach ($child as $c) {
        if ($c->getTitle() === $row['21']) {
            $product = new Product();
            $product->setName($row[1]);
            $product->setCategory($categoryTop);
            $product->setSku($row[14]);
            $product->setEanUpc($categoryTop->getId());
            $this->productService->save($product);
        }
    }
}

我能想到的选项:

  • 在1命令中拉出所有自动导入脚本并运行它 小时。这个选项并不难,但我不认为这是最好的解决方案,因为它会占用我服务器上的大量资源。
  • 与任务运行器一起创建任务调度程序,我们在其中记录下载文件,读取文件,检查是否存在等各个步骤的每个事件,检查类别是否匹配,检查产品是否存在,检查产品库存是否已启动到目前为止,对于这个选项,我想创建自己的调度程序+跑步者,但没有那么多的经验,不知道这是否有助于我的项目。由于每个任务都将设置在队列中,因此可以更轻松地检查某些内容是否失败

对我目前的Symfony命令的建议也表示赞赏。

1 个答案:

答案 0 :(得分:0)

我过去在解决过类似的问题,现在这些建议取决于你需要同步多少数据(我有大约8个来源,每个大约10 000个项目同步,最近15分钟)。

解决方案的架构就像这样

  • 对于您拥有Tranformer的每个源,它下载源文件,并将其解析为一个常见的TransformedDTO,在您的情况下,它可以是一个包含类别的产品或两个不同处理器的两个转换对象
  • 接下来你有处理器 - 这个得到TransformedDTO,现在为了优化我已经计算了数据的校验和,并从产品的最后一次运行的校验和进行了比较。现在只在需要时进行更新。如果只插入产品,则不需要执行此步骤。
  • 您可以这样做,该处理器只检查产品是否更改,如果是,您将更新添加到队列并具有不同的处理器处理。但那只是下一步可能的步骤。

此解决方案的优点:

  • 添加新导入只需编写一个Transformer
  • 您可以在处理器中使用一些缓存/优化逻辑(这通常是瓶颈,因为它需要执行相当多的操作),但由于它是共享的,因此存在空间,一个优化会影响所有操作。

对于日程安排,取决于您的需求 - 我会坚持在不同时间运行不同的日程安排,并检查更新源的间隔时间,并将更新时间与之同步。

示例TransformedDTO。它只不过是数据的占位符,可以作为处理器和输出变换器的输入。

class Product {
    public $sku;
    public $category;
    public $name;
    // Everything else which your processor know how to process
}