2012-06-29 45 views
6

幾個月前我開始使用CakePHP(1.2)爲公司的應用程序添加小功能,我對此不太熟悉。Cakephp cron作業調用控制器的動作

我們在合併到生產服務器之前先在開發服務器上進行本地測試。

我想要一個控制器動作,每小時調用一次我認爲是通過我的研究,一個cron工作來完成這個任務的最佳方式。


嘗試1

看完這些之後,

http://bakery.cakephp.org/articles/mathew_attlee/2006/12/05/calling-controller-actions-from-cron-and-the-command-line

http://book.cakephp.org/1.2/en/view/110/Creating-Shells-Tasks

我可以實現沒有錯誤的東西,但不執行該操作。

基於這些例子中,我添加了一個名爲cron_dispatcher.php文件在我的應用程序目錄(而不是應用程序/ Web根目錄),然後從應用程序目錄

PHP cron_dispatcher.php /控制器/動作做這個命令/參數

仍然沒有發生,但它通過網址調用它時,完美。


嘗試2

我試圖創建一個殼(email.php),將調用/應用/銷售商/殼動作/。

<?php 

class EmailShell extends Shell { 

    public function main() { 
     $this->out('Test'); 
    } 

} 
?> 

這成功地輸出測試使用

蛋糕電子郵件主要

控制檯但我找不到如何調用控制器的動作。我試過

$ this-> requestAction('/ controller/action');

我也嘗試使用與shell中的main函數不同的函數進行調用。

我曾嘗試以包括$控制器使用變量,我會一個模型,但沒有工作(和它沒有任何意義,我認爲)

我不認爲創建任務是解決方案,因爲我不想複製sendEmails函數,因此我正在尋找一種方法來從shell或其他任何地方調用控制器的操作!

有可能是一些理論我很想念,感謝


解決方案

我感動從控制器的一些方法,模型和我能夠從shell調用它們。

App::import('Component', 'Email'); 

class SendMemosShell extends Shell { 

    var $uses = array(
     'Memo', 
    ); 

    public function main() { 

    } 

    public function sendEmails() { 
     $this->Email =& new EmailComponent(null); 
     $memoList = $this->Memo->getMemos(); 
     //... 
    } 
} 

此鏈接幫助 http://book.cakephp.org/2.0/en/console-and-shells/cron-jobs.html


編輯:澄清了一些信息和添加的解決方案

回答

3

它實際上是一個相當普遍的問題,碰到了也。

控制器正在決定如何處理請求並開始該任務。在這種情況下,您不需要控制器,因爲您有一個shell任務,任務已經清除。

知道了,調用控制器方法沒有任何意義。

所以重新考慮你的選擇,是的這是一個相當困難的選擇。例如,您可能會決定發送電子郵件是業務邏輯步驟,因此應該在模型中。另一種選擇是完全分開它(這就是我們最喜歡的)。

在這種情況下,您將不得不創建一個隊列,在其中放入所有要發送的電子郵件。這是一個很好的設計,因爲您知道控制器中的邏輯數量已經減少,並且它是分開的。這樣你就可以獲得電子郵件服務。

例如,您可以要求服務發送「新用戶」郵件。然後你將User對象添加到它,它應該處理它自己。這樣,你甚至可以擴展,因爲你的服務可以例如外包,你可以在服務等

編輯擴大多臺服務器:

好的問題。

採取的步驟:

  1. 第一集中的 「發送電子郵件」 的過程。所以選擇一個位置放置它。您可以決定:添加將電子郵件發送到隊列或直接調用服務。例如,您可以添加shell任務來發送電子郵件。

  2. 調用shell:現在你有問題來調用shell。一般你不想。爲什麼不?因爲shell(任務)可能會運行很長時間。所以這就是我們之間使用隊列的原因。所以你可以詢問隊列或讓隊列消息告訴你已經完成了一些事情。例如,想想一個關閉的郵件服務器。您必須重試等。這不應該在Web請求中,因爲用戶正在等待響應。

  3. 第三步是從你的cron調用shell,現在很容易,因爲你已經在命令行上,所以你可以使用標準調用。

無論如何,有一些選項可以直接從控制器進行調用,但不應該這樣做。這篇文章給出了一些非常有趣的見解: CakePHP: Run shell job from controller

編輯31/08/'13:見CakePHP的事件系統也爲一些例子:http://book.cakephp.org/2.0/en/core-libraries/events.html

+0

我還需要手動調用此操作(例如,通過單擊視圖中的按鈕)。你是否建議我創建一個任務而不是控制器動作,並調用它(自動使用cron作業並手動點擊)?是一個你稱之爲完全與邏輯分離的shell還是你在談論隊列?有時我需要一次發送多封電子郵件(當它自動檢查時),但不應該太頻繁發生,所以我想知道隊列是否有點太複雜,無法滿足我的需求!感謝您的回答 – Catherine

+0

也回答了他們,一般來說,您應該考慮應用的大小和設計。我回答你的問題的方式是它應該完成的方式之一。這並不意味着這是對商業有利的方式。如果您只是發送郵件,則不值得爲它創建一個完整且更復雜的設置。 –

+1

再次感謝您的詳細解答。我們同意不需要手動發送電子郵件,所以我創建了一個發送電子郵件的shell。這也迫使我將更多的方法從控制器轉移到模型上,如果我理解得好,模型更合適。然後我按照這個過程設置了cron作業:http://book.cakephp.org/2.0/en/console-and-shells/cron-jobs.html我決定不使用隊列,即使這看起來很有趣,因爲它在這種情況下不值得! – Catherine

0

根據什麼需要做的事情,我經常把這些方法在我的控制器操作中。在操作的頂部,我檢查$ _SERVER ['REMOTE_ADDR'] == $ _SERVER ['SERVER_ADDR']以確保只有網站可以調用該操作。然後在cron中我會捲曲或wget這個地址。

它有它的好處 - 在開發過程中更容易在本地運行(只需在瀏覽器中輸入url),再加上運行cli版本的php和apache版本以及請求變量(例如蛋糕無法通過cli獲取網站域名/地址,就像您可以作爲apache模塊運行一樣,所以使用html helper的網站絕對鏈接不起作用)。

+0

我已經試過只是爲了忘記地址,它似乎沒有按照我想要的方式執行操作,我可能做錯了。儘管我還沒有嘗試將它放在crontab中,但我猜測我應該在未來做更多的嘗試。謝謝對不起,我不能評價你,我還是新來的網站。 – Catherine