我有一个在WampServer上运行本地的项目。这是一个类似MVC的结构;它将URL重写为index.php?url=$1
。完整.htaccess
:
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-l
RewriteRule ^(.+)$ index.php?url=$1 [QSA,L]
当我想使用PHP location: <location>
将用户发送到另一个页面时,由于重写,所以它没有正确执行此操作(尽管我在技术上始终位于index.php
中)。
例如,如果我在http://localhost/project_name/controller/method/
并且此控制器的构造函数或方法试图将我发送到:
header('location: another_controller/method');
送我去
http://localhost/project_name/controller/method/another_controller/method/
header('location: /another_controller/method');
送我去
http://localhost/another_controller/method/
但我希望它像这样发送给我:
header('location: /another_controller/method');
送我去
http://localhost/project_name/another_controller/method/
现在我找到的唯一解决方案是:
define('BASE_URL','http://localhost/project_name');
header('location: '.BASE_URL.'/another_controller/method/');
但这并不完美,因为只要域名或文件夹名称发生变化,我就必须更改此定义的常量BASE_URL
。我还可以在我的BaseController
中创建一个创建绝对URL的方法,但这种方法基本上也只是BASE_URL
的前缀。
注意: HTML的src
和href
属性不会出现同样的问题,这些属性可以使用相对路径(路径中没有project_name
文件夹) 。但是,我不明白为什么。因为如果标头location
导致浏览器将相对URL附加到当前位置,那么在查找.css
或.js
文件时,为什么它不具有相同的行为。< / p>
所以...... 这为我提出了几个问题:
src
和href
属性不会共享此行为?答案 0 :(得分:4)
现在我找到的唯一解决方案是:
if ($_SERVER['DOCUMENT_ROOT'] == dirname($_SERVER['SCRIPT_FILENAME'])) { define('BASE_PATH', '/'); } else { define('BASE_PATH', dirname($_SERVER['SCRIPT_NAME']) . '/'); } $protocol = isset($_SERVER['HTTPS']) ? 'https://' : 'http://'; define('BASE_URL', $protocol . $_SERVER['SERVER_NAME'] . BASE_PATH);
但这并不完美,因为它导致我必须改变 每当域或文件夹名称时,这定义了常量BASE_URL 变化。
您不需要更改已定义的常量。这些值可以动态找到。
示例:强>
function redirect($path = null) {
if (isset($path)) {
if (filter_var($path, FILTER_VALIDATE_URL)) {
header('Location: ' . $path);
} else {
header('Location: ' . BASE_URL . $path);
}
} else {
header('Location: ' . BASE_URL);
}
exit;
}
此外,您可以将重定向包装到可以同时处理这两者的函数中,而不是担心是指定绝对URL还是路径:
.htaccess
最后,正如@HarshSanghani在评论中提到的,BASE_PATH
文件中的基本路径应与代码中的基本路径匹配。因此,如果/project_name/
(基于上面的示例)输出.htaccess
,那么您的RewriteBase /project_name/
应该适应它:
{{1}}
答案 1 :(得分:2)
回答你的问题:
$baseUrl = dirname($_SERVER['SCRIPT_NAME']);
。这样,如果您的文件夹或域名发生更改,则无需更改任何代码。src
和href
由您的浏览器解释,其中考虑了网页的<base>
标记。带有<base>
标记的网页上的所有路径都会相应地由您的浏览器更改。您从服务器发送的HTTP标头(用于重定向)与您发送的html页面无关,因此不会更新。
答案 2 :(得分:2)
$baseUri
某种方式。答案 3 :(得分:2)
您应该在htaccess文件中指定RewriteBase。在链接中使用相对路径,您不需要任何其他路径。
RewriteBase /project_name/
RewriteEngine on
RewriteCond $1 !\.(gif|jpe?g|png)$ [NC]
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-l
RewriteRule ^(.+)$ index.php?url=$1 [QSA,L]