2008-11-16 67 views
4

PHP提供了一種機制來註冊關閉功能:在PHP中完成HTTP請求後執行代碼?

register_shutdown_function('shutdown_func'); 

的問題是,在最近的版本的PHP中,此功能仍然在請求期間執行。

我有一個平臺(在Zend框架中,如果有的話)整個請求中的任何一段代碼都可以註冊一個條目來登錄到數據庫。整個請求中並沒有大量的單個插入語句,而是減慢了頁面的速度,我將它們排隊以便在請求結束時插入。我希望在用戶完成HTTP請求後能夠做到這一點,因此記錄或執行任何其他清理任務的時間長度不會影響用戶感知的頁面加載時間。

在PHP中是否有內置的方法來做到這一點?或者是否需要配置某種與外部進程共享的內存空間方案,並指示進程執行日誌記錄?

+0

瘋狂 - 我今天早些時候會問這個問題! – 2008-11-16 03:21:34

+0

得愛的計算器! – 2008-11-16 03:33:04

回答

4

如果你真的關心MySQL的插入時間,你可能是在解決症狀而不是原因。例如,如果您的PHP/Apache進程在用戶獲取HTML之後執行,您的PHP/Apache進程仍然被鎖定到該請求中。由於它很忙,如果有另一個請求出現,Apache必須分叉另一個線程,爲它提供更多內存,打開其他數據庫連接等。

如果遇到性能問題,您需要刪除繁重的你的PHP/Apache執行。如果你有很多清理任務正在進行,那麼你正在燒製寶貴的Apache進程。

我會考慮將您的條目記錄到文件中,並讓crontab將這些條目加載到數據庫帶外。如果您有其他繁重任務,請使用排隊/作業處理系統進行帶外工作。

1

除了register_shutdown_function(),還沒有內建確定腳本何時退出的方法。然而,Zend Framework在調度過程的特定點上有幾個鉤子來運行代碼。 爲了您的要求,最相關的將是動作控制器的post-dispatch hook,該動作控制器在發送動作後立即發生,並且dispatchLoopShutdown event用於控制器插件代理。

您應該閱讀手冊以確定哪種更適合您。

編輯:我想我完全不明白。從這些鉤子中,您可以以某種形式或其他形式分離當前進程。 PHP有幾種分叉處理方式,您可以在program execution下的手冊中閱讀。我會建議通過pcntl擴展 - 讀this blog post來查看分支子進程在後臺運行的示例。

+0

這些鉤子都不能自己解決我的問題。這些掛鉤仍在HTTP請求中運行。就瀏覽器而言,該頁面仍在加載。例如,假設日誌記錄耗時5秒,瀏覽器將會看到5秒以上的加載時間。 – 2008-11-16 03:20:46

0

關於this random guy's blog的評論聽起來和你想要的相似。如果該頭部技巧不起作用,那麼如果您的Web主機的配置允許這樣的事情,則該博客上的其中一條評論建議exec()將單獨的PHP腳本在後臺運行。

0

這可能對你的口味有點駭人聽聞,但這將是一個有效和簡單的解決方法。

您可以創建一個由您選擇的數據庫管理的「隊列」,首先將請求存儲在數據庫的隊列表中,然後輸出一個iframe,導致腳本觸發與之匹配的指令數據庫中的queue_id。

例如:

<?php 
mysql_query('INSERT INTO queue ('instructions') VALUES ('something would go here'); 
echo('<iframe src="/yourapp/execute_queue/id?' . mysql_insert_id() . '" />'); 
?> 

和框架會做類似

例如:

<?php 
$result = mysql_query('SELECT instructions FROM queue WHERE id = ' . $_GET['id']); 
// From here, simply execute some instruction based on the "instructions" field, then delete the instruction from the database. 
?> 

就像我說的,我看你怎麼可以考慮這個的hackish,但框架將獨立於其父頁面加載,所以它會實現你想要的,而不需要在後臺運行其他應用程序。

希望這至少能指引您朝着正確的方向發展。

乾杯!

相關問題