2012-10-10 58 views
1

我曾嘗試過幾次開始使用symfony 2,但一直都陷入困境。這次我打算堅持下去!實用工具對象Symfony 2

到目前爲止,我最大的問題是如何在沒有用戶交互的情況下執行任務的對象。

Ex。

我想創建幾個php類,它將處理每天從幾個網站解析一些數據。我希望通過手動或通過cron作業啓動此任務。因此,我只是真的需要模型和控制器。 (控制器解析網站並創建模型,模型來存儲解析的數據並堅持數據庫)。要做到這一點,創建一個只處理這些後臺作業的捆綁軟件是最好的方法。

我想到了以下類:

  • SiteParser

    • Site1Parser擴展SiteParser
    • Site2Parser擴展SiteParser
  • 型號1

  • 模型2

  • 某些類負責編排不同站點的解析並告訴創建的模型保留。

這是否合乎邏輯?如果是的話,我會如何將這個結構放入symfony中?

感謝您的幫助,如果我不清楚或者您有任何問題,請詢問我將提供所需的任何詳細信息!

回答

7

首先,我建議不要在這裏使用控制器。請記住,控制器的目的是在模型和視圖之間進行調解。對於自動化流程,您並不是真的有看法 - 沒有人正在查看或閱讀您的輸出(您可能需要執行一些日誌記錄,但這是另一回事)。

這麼說,我會說,最好的辦法是創建使用的Symfony的內置控制檯命令功能的命令。您可能使用了app/console命令工具來執行諸如生成捆綁包和創建實體映射之類的事情。通過ContainerAwareCommand課程,您實際上可以編寫自己的課程。最好的部分是該命令知道容器......換句話說,您可以使用get()方法直接訪問Doctrine,Monolog,Twig或任何其他服務。

因此,讓我們假設你的應用程序中提取從網站,然後將這些圖片的網址保存到數據庫中。要做到這一點,首先需要創建一個服務類(讓我們把它放在MyBundle \服務命名空間下),並賦予其必要的方法:

namespace MyBundle\Service; 

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

然後,你可以把它註冊爲一個名爲「解析」服務通過app/config/config。yml:

services: 
    parser: 
     class: MyBundle\Service\Parser 

現在,您可以從容器中調用get("parser")。控制器擴展容器,因此在控制器中可以說$this->get("parser"),但在您的控制檯命令中,您必須專門獲取容器:$this->getContainer()->get("parser")

,那麼你可以寫你的SiteParseCommand看起來是這樣的:現在

namespace MyBundle\Command; 

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")訪問它。

希望這會有所幫助!

(有關ContainerAwareCommand類的更多文檔here

+1

非常感謝!真棒回答真的會消除我過去的很多困惑。我會看看你明天寫的更詳細的內容,但我認爲你已經把我放在了正確的軌道上! – Nath5