在本地主机上,我正在运行我的 php(MVC)应用程序,.htaccess
文件中有以下规则:
Options -Indexes
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond $1 !^(config|core|css|js|fonts|images|robots\.txt)
RewriteRule ^(.+)$ index.php/$1 [L]
例如localhost/myapp/register/login
将加载登录页面。但在实时服务器上,我遇到了问题。我遇到的第一个问题是No input file specified
。阅读这个答案我将此行更改RewriteRule ^(.+)$ index.php/$1 [L]
为RewriteRule ^(.*)$ index.php?/$1 [L]
。这解决了第一个问题,但产生了另一个问题,现在无论 URL 是什么,它总是加载相同/默认的视图和控制器。
我的index.php有以下几行代码:
$url = isset($_SERVER['PATH_INFO']) ? explode('/', ltrim($_SERVER['PATH_INFO'], '/')) : [];
// Route the request
Router::route($url);
因此,我检查了 $_SERVER['PATH_INFO'] 值,发现它是空的。现在我的问题是它为什么是空的,以及如何实现 URL 的正常行为。
答案1
最后我终于让它工作了。我的新方法
RewriteRule
是。我在 中RewriteRule ^(.*)$ index.php?/$1 [L,QSA]
使用$_SERVER['REQUEST_URI']
而不是。$_SERVER['PATH_INFO']
index.php
如果你在 PHP 代码中使用$_SERVER['REQUEST_URI']
,那么你可能不应该将查询字符串(包含 URL 路径)附加到RewriteRule
代换(至少你不会需要至),即。只需使用RewriteRule . index.php [L]
即可。
PHP$_SERVER['REQUEST_URI']
超全局变量仅包含请求的 URL 路径,而不管您的RewriteRule
指令是什么。它还包含一个潜在的查询字符串(严格来说,您可能应该在 PHP 代码中拆分它)。(与仅包含 URL 路径的同名 Apache 服务器变量不同。)
如果您选择传递查询字符串,如“changed”中所示RewriteRule
,则似乎不需要添加斜线前缀(因为您在 PHP 代码中将其删除)。例如:
RewriteRule (.*) index.php?$1 [QSA,L]
然后,index.php
你将拥有:
$url = !empty($_SERVER['QUERY_STRING']) ? explode('/',$_SERVER['QUERY_STRING']) : [];
请$_SERVER['QUERY_STRING']
注意总是设置,因此需要检查!empty()
,而不是isset()
。