FrankenPHP 不支持 .htaccess,因其基于 Caddy 路由引擎,所有重写规则须提前声明在 Caddyfile 中,如用 redir 或 try_files 替代 RewriteRule,并需显式配置 php_fastcgi 与 try_files 以支持 WordPress 无后缀链接。

FrankenPHP 里没有 .htaccess 文件
因为 FrankenPHP 不走 Apache 的模块加载路径,也不解析 .htaccess —— 它压根不读这个文件。Apache 依赖 mod_rewrite 在请求生命周期中动态加载和执行 .htaccess 规则,而 FrankenPHP 是基于 Caddy 的路由引擎,所有重写逻辑必须提前声明在主配置里,运行时不会回溯查找或热加载目录级配置文件。
Caddyfile 中替代 RewriteRule 的写法
你原来写在 .htaccess 里的 RewriteRule 和 RewriteCond,得手动转成 Caddy 的 handle + rewrite 或 redir 块。比如 WordPress 子目录重定向这种常见需求:
原来 .htaccess(根目录)里这句:
RewriteRule ^(.*)$ https://example.com/fr/$1 [L,R=301]
在 FrankenPHP 的 Caddyfile 里要写成:
立即学习“PHP免费学习笔记(深入)”;
https://example.com {
redir * https://example.com/fr/{http.request.uri.path} 301
}注意几点:
-
{http.request.uri.path}是 Caddy 的变量语法,对应 Apache 的$1,但不能直接用正则捕获组 - 如果要保留查询参数(
?a=1&b=2),Caddy 默认会自动带上,不用额外拼接 - WordPress 根目录下的伪静态规则(如
index.phpfallback)要改用php_fastcgi指令配合try_files行为模拟,例如:try_files {path} /index.php?{query}
WordPress 固定链接失效的真正原因
迁到 FrankenPHP 后点开文章全是 404,大概率不是重写没配,而是 PHP 脚本没被正确转发到 WordPress 入口。FrankenPHP 默认只把匹配 *.php 的请求交给 PHP 运行时,而 WordPress 的固定链接是无后缀路径(如 /hello-world/),需要显式告诉 FrankenPHP:“这类请求也要走 index.php”。
解决方法是在 Caddyfile 的 PHP 处理块里加 try_files:
php_fastcgi * 127.0.0.1:2019 {
try_files {path} /index.php?{query}
}这里 127.0.0.1:2019 是 FrankenPHP 内置 PHP 运行时的默认监听地址;{query} 会原样透传 URL 参数,确保 ?p=123 这类老式链接也能工作。
worker 模式下还要额外注意 autoload
如果你启用了 FrankenPHP 的 worker 模式(即常驻内存),WordPress 的 wp-settings.php 会被加载一次、长期驻留。这时候 .htaccess 曾经承担的部分职责(比如根据 Host 切换环境配置)就彻底失效了——所有逻辑必须进 PHP 代码或通过 FrankenPHP 的环境变量注入。比如多站点子目录模式,不能再靠 RewriteCond %{HTTP_HOST} 分流,得改用 $_SERVER['HTTP_HOST'] 在 wp-config.php 里做判断,否则 worker 初始化时就锁死了入口逻辑。



















