有點忘記了,好像在 CodeIgntier 3 (CI3) 建置 Command line 運行的任務時,可以很即時看到運算的輸出結果(預設是 testing mdoe?),但在 CI 4 時,卻必須等到所有任務都做完了,才會一次輸出結果。這對於在 Jenkins 系統運行時,無法時看到運行過程是很不方便的。
追蹤 CI 4 的架構,起因是 system/CodeIgniter.php:run 中,運行時呼叫了 Events::trigger('pre_system'); ,在 app/Config/Events.php 可以看到定義了 pre_system 的工作內容,大意就是當 ENVIRONMENT 不是 testing 時,就會開啟 ob_start 使用機制。
在 CI 架構上,使用 ob_start 也有個好處,那就是寫一些網頁服務時,有時是內容產出跟 header 送出夾雜在一起。當在 PHP 使用 header 送出資料時,是不允許前面已經輸出過資料的。這時靠 ob_start / ob_end_flush 應用,就可以完美排除這種問題。
回過頭來,面對 command line 的任務,若想要排除 ob_start 的影響,可以試著包裝一個輸出訊息的函式,並在裡頭輸出完資料後,再靠這兩段補強輸出資料,如:
function debug($message) {echo "[DEBUG] $message\n";while (\ob_get_level() > 0)\ob_end_flush();}
或是乾脆在負責 Command line 任務的建構子中,直接靠 ob_get_level 和 ob_end_flush 清掉輸出緩衝的設計:
public function __construct() {while (\ob_get_level() > 0)\ob_end_flush();}
如此就可以得到即時的輸出資料了
沒有留言:
張貼留言