Sina App Engine (SAE) 禁用本地文件寫入,導致 Smarty 編譯緩存無法落盤。官方方案是將 compile_dir、cache_dir 指向 SAE Memcache 協議(saemc://)。本文提供完整配置步驟、代碼示例與避坑指南。
SmartyException: unable to write file ./web/templates_c/wrt4e95555280ef1
原因:SAE 文件系統只讀,Smarty 嘗試寫入編譯緩存失敗。
memcache)。require_once 'Smarty.class.php';
$smarty = new Smarty();
// 關鍵:指向 SAE Memcache 協議
$smarty->compile_dir = 'saemc://smartytpl/';
$smarty->cache_dir = 'saemc://smartytpl/';
// 必須關閉編譯鎖定,因為 saemc 不支援 touch() 操作
$smarty->compile_locking = false;
// 其他常規設置
$smarty->template_dir = __DIR__ . '/templates/';
$smarty->left_delimiter = '{';
$smarty->right_delimiter = '}';
$smarty->caching = true;
$smarty->cache_lifetime = 3600;
smartytpl/ 相關 Key 的讀寫統計。saemc:// 是 SAE 封裝的流封裝協議,底層調用 Memcache API;smartytpl/%s;compile_locking = false 避免 Smarty 嘗試 touch() 更新時間戳(Memcache 不支援文件系統元操作);cache_lifetime 控制,SAE Memcache 也會按 LRU 淘汰。saemc://smartytpl_compile/、saemc://smartytpl_cache/,便於監控;$smarty->fetch(),避免首請求慢;$smarty->clear_compiled_template();{include};if (defined('SAE_TMP_PATH')) {
$smarty->compile_dir = 'saemc://smartytpl/';
$smarty->cache_dir = 'saemc://smartytpl/';
$smarty->compile_locking = false;
} else {
$smarty->compile_dir = __DIR__ . '/templates_c/';
$smarty->cache_dir = __DIR__ . '/cache/';
}
| 現象 | 原因 | 解決 |
|---|---|---|
| 依然報 unable to write | 未開通 Memcache 或配置未生效 | 檢查控制台服務狀態、確認 compile_dir 協議前綴 |
| 模板修改不生效 | compile_locking 未關閉 / 緩存未清 | 設置 false、手動清理 Memcache Key |
| 性能無提升 | 模板極小 / 網絡延遲抵消收益 | 啟用 opcode 緩存、預熱 |
| Key 衝突 | 多應用共用 Memcache | 使用不同前綴命名空間 |
| 方案 | 優點 | 缺點 |
|---|---|---|
| Smarty + saemc | 零代碼改動、成熟穩定 | 序列化開銷、Memcache 容量限制 |
| Blade/Twig + 內存緩存 | 現代語法、性能更好 | 需重寫模板、遷移成本高 |
| 原生 PHP 模板 | 無依賴、極快 | 維護困難、安全風險 |
對於存量 Smarty 專案,saemc:// 方案是遷移成本最低、風險最小的選擇。