ThinkPHP 手冊說明:CLI 模式預設不載入模板引擎。但實務上常需在命令列腳本、排程任務中使用模板:
view = Think::instance('View');
// 4. 賦值變數
$this->view->assign('rows', [
['title' => '測試標題 1'],
['title' => '測試標題 2'],
]);
$this->view->assign('title', '報表標題');
// 5. 取得渲染結果(而非直接輸出)
$content = $this->view->fetch('Index/index.html');
// 6. 後續處理:存檔、寄信、轉 PDF...
file_put_contents(RUNTIME_PATH . 'report_' . date('Ymd') . '.html', $content);
var_dump($content);
}
}
?>
| 步驟 | 說明 |
|---|---|
| import() | 手動載入模板引擎相關類,CLI 不會自動載入 | C('CACHE_PATH') | 指定模板編譯快取目錄,避免權限或路徑錯誤 |
| Think::instance('View') | 取得 View 單例(或 new View()) |
| assign() | 傳遞變數給模板,同 Web 模式 |
| fetch() | 回傳渲染字串,不自動輸出,適合 CLI 後續處理 |
| display() | 直接輸出,CLI 下會印到標準輸出(可用但較少用) |
setName('report:generate')
->setDescription('產生每日報表 PDF');
}
protected function execute(Input $input, Output $output) {
// 1. 準備資料
$data = Db::name('orders')
->whereDate('create_time', date('Y-m-d'))
->select();
// 2. 渲染 HTML 模板
$html = view('report/daily', ['orders' => $data, 'date' => date('Y-m-d')]);
// 3. Dompdf 轉 PDF
$dompdf = new Dompdf();
$dompdf->loadHtml($html);
$dompdf->setPaper('A4', 'portrait');
$dompdf->render();
// 4. 存檔
$filename = 'storage/reports/daily_' . date('Ymd') . '.pdf';
file_put_contents($filename, $dompdf->output());
$output->writeln("報表已生成:$filename ");
}
}
?>
| 問題 | 原因 | 解決 |
|---|---|---|
| 找不到模板檔案 | CLI 當前工作目錄非專案根目錄 | 使用絕對路徑 APP_PATH . 'view/...' 或 chdir(APP_PATH) |
| 快取目錄無寫入權限 | CLI 使用者與 Web 使用者不同 | 設定 C('CACHE_PATH', '/tmp/think_cache') 或 chmod 777 |
| 模板中使用 `url()`、`asset()` 等助手失效 | CLI 無 HTTP 請求上下文 | 手動設定 Config::set('app.url', 'https://domain.com') 或模板改用相對路徑 |
| Session/Cookie 相關功能報錯 | CLI 無 Session | 避免在 CLI 模板中使用 Session 相關邏輯 |
import('Think.Core.View')、Think::instance('View')new \Think\View()、\Think\Template::instance()view() 助手函數、\think\View::instance()view()、facade\View、支援多模板引擎CLI 模式下使用模板引擎的關鍵在於手動載入核心類與正確設定快取路徑。掌握 fetch() 取得字串而非直接輸出,即可靈活應用於 PDF 生成、郵件發送、靜態化等離線渲染場景。