2012-10-18 41 views
3

我有一個控制器,我用它來通過cron運行進程列表,我需要它從一個單獨的控制器運行一個方法。CakePHP導入的控制器範圍問題

當從自己的控制器調用該方法時,一切正常,但從cron控制器運行時(即使手動調用),它失敗。

我的代碼目前看起來是這樣的:

class CronController extends AppController 
{ 
    var $uses = array(.., 'EmailTemplate', ..); 
    var $components = array('Email'); 

    //Some stuff 

    function process_for_cron_to_run() { 
     //Some stuff 

     //Run method from imported controller 
     App::import('Controller', 'Imported'); 
     $imported = new ImportedController; 
     $imported->constructClasses(); 
     $imported->method_to_run(); //Dies when running this method 
     exit; 
    } 
} 

... 

class ImportedController extends AppController { 
    var $uses = array(..); 
    var $components = array('Mailer', 'RequestHandler', 'FileHandler', 'Email');    

    //Some stuff 

    function method_to_run() { 
     //Some stuff 

     $this->_sendEmail(..); 
    } 
} 

... 

class AppController extends Controller 
{ 
    var $components = array('Cookie', 'RequestHandler', 'Err', 'Email', 'Sms'); 
    var $uses = array(.., 'EmailTemplate', ..); 

    function _sendEmail(..) { 
     //Some stuff 

     $this->EmailTemplate->find(..); //Dying here (Line 1756) 
    } 
    .. 
} 

這是死亡,出現以下錯誤:

Fatal error: Call to a member function find() on a non-object in /../app/app_controller.php on line 1756 

其中線1756是在AppController的上方。

我嘗試添加EmailTemplate到ImportedController的$uses - 這個工作,但它在AppController中,而不是死了幾行以後調用$this->Email,其中包含在所有三個控制器的$components。對於$this->email錯誤信息,以供參考:

Fatal error: Call to a member function reset() on a non-object in /../app/app_controller.php on line 1645 

我能想到的唯一的另一件事是,我從ImportedController調用該方法是admin_X,所以當我從/流程/ process_for_cron_to_run調用它,由於身份驗證問題它可能會被踢掉?

+1

我已解決此問題;我不得不在process_for_cron_to_run函數中用$ imported - > _ initComponents()調用初始化組件。奇怪的是我必須這麼做,因爲'Email'已經包含在CronController的$ uses中,但它解決了這個問題。一旦我被允許,我會發佈一個適當的答案! –

+0

如果您需要從兩個(或更多)不同的控制器執行某些代碼,那麼請參考[此帖](http://stackoverflow.com/a/12769983/727208) –

+2

,那麼代碼需要在零件。當然,這可能會花費你幾分鐘的時間,但是你的代碼會更乾淨。 – pleasedontbelong

回答

-1

我已經解決了這個問題;我必須採取兩個步驟來修復它:

  1. 將'EmailTemplate'添加到$ uses,以便ImportedController可以引用它。這意味着當試圖調用$ this-> Email時代碼就會死亡。
  2. 更新了process_for_cron_to_run()來initalise組件:

    function process_for_cron_to_run() { 
        //Some stuff 
    
        App::import('Controller', 'Imported'); 
        $imported = new ImportedController; 
        $imported->_initComponents(); //Added this line 
        $imported->constructClasses(); 
        $imported->method_to_run(); 
        exit; 
    } 
    

有人死亡的原因是因爲進口控制器沒有它的組件初始化;當對象在AppController中調用_sendEmail時,沒有附加任何組件,所以它不知道$ this-> Email是什麼。

然而,解決此問題的理想解決方案是將method_to_run邏輯移入模型或組件,而不是導入控制器。