Latte 必须通过 composer require latte/latte 作为项目依赖安装,因其依赖自动加载、运行时上下文(如缓存路径、安全策略实例),全局安装会破坏沙箱机制,导致类找不到、缓存失败、特性失效。

Latte 不能通过 Composer 全局安装,它必须作为项目依赖引入;直接 composer global require latte/latte 不起作用,且会破坏模板沙箱机制。
为什么 composer require latte/latte 是唯一正确方式
Latte 的设计依赖于类自动加载和运行时上下文(比如模板缓存路径、安全策略对象实例),全局安装会导致 Latte\Engine 找不到默认缓存目录、无法正确解析相对模板路径,甚至让 {snippet} 和 n:attributes 等特性失效。
常见错误现象:Class 'Latte\Engine' not found(autoload 未触发)、Unable to write cache file(缓存路径为空或权限错误)。
- 必须在项目根目录下执行
composer require latte/latte - 确保项目已初始化
composer.json(若没有,先composer init或composer install) - 不要用
--global,也不要手动拷贝 vendor/latte/latte 到其他位置
初始化 Latte\Engine 时必须设置缓存目录
Latte 默认尝试写入 sys_get_temp_dir(),但很多共享主机或容器环境禁止写入系统临时目录,导致模板编译失败或每次请求都重新编译(性能骤降)。
立即学习“PHP免费学习笔记(深入)”;
使用场景:Web 请求、CLI 脚本、Swoole 长生命周期应用。
- 显式指定可写的缓存路径:
$engine = new Latte\Engine(); $engine->setTempDirectory(__DIR__ . '/var/cache/latte'); - 确保该目录存在且 PHP 进程有读写权限(
mkdir -p var/cache/latte && chmod 755 var/cache/latte) - 在 CLI 模式下,避免复用 Web 服务器的缓存目录(可能因用户不同导致权限冲突)
Latte\Engine::render() 渲染前要关掉不安全的选项
Latte 默认开启部分“开发友好”行为,但在生产环境可能绕过安全沙箱,比如允许模板中调用任意静态方法({DateTime::createFromFormat(...)})或访问超全局变量({$GLOBALS})。
关键参数差异:$engine->setStrictTypes(true) 和 $engine->addFilter('escape', ...) 不影响基础安全,真正起作用的是禁用不安全调用。
- 禁用动态调用:
$engine->setAllowedFilters(['escape', 'noescape']); $engine->setAutoEscape(true); - 禁用任意静态/实例方法调用:
$engine->setContentType(Latte\Engine::CONTENT_HTML); // 触发默认安全策略 - 如需额外限制,手动覆盖
$engine->getCompiler()->addMacro('php', null);来禁用{php}标签
模板文件后缀和路径解析容易被忽略的细节
Latte 不强制要求 .latte 后缀,但如果你用 .html 或 .tpl,$engine->render('user.html', [...]) 会默认查找 user.html.latte —— 这不是 bug,是 Latte 的“扩展名补全”逻辑。
性能影响:路径解析失败时会静默 fallback,导致模板加载延迟或误用错误文件。
- 统一使用
.latte后缀,避免歧义:$engine->render('templates/user.latte', [...]) - 路径必须相对于当前工作目录(
getcwd()),不是相对于__FILE__;建议用绝对路径:__DIR__ . '/templates/user.latte' - 不要依赖
setLoader()自定义加载器来“修复”路径问题,除非你明确需要动态模板源(如数据库存储)
最常被跳过的一步:没检查 var/cache/latte 是否真的生成了编译后的 PHP 文件。如果没生成,说明初始化或路径配置有硬伤,不是模板语法问题。



















