php - 来自重写的基本文件夹的绝对 URL

标签 php .htaccess mod-rewrite relative-path absolute-path

我有一个在 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/并且此 Controller 的构造函数或方法试图将我发送到:

  • 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文件。

所以...这给我带来了几个问题:

  1. 如果我有虚拟主机,我会遇到这个问题吗?
  2. 解决这个问题的最佳方法是什么?
  3. 最好只拥有完整的绝对 URL 吗?
  4. 为什么 HTML 的 srchref属性不共享此行为?

最佳答案

Now the only solution I have found is:

define('BASE_URL','http://localhost/project_name');
header('location: '.BASE_URL.'/another_controller/method/');

But this isn't perfect either because it causes me to have to change this defined constant BASE_URL whenever the domain or folder name changes.

您不需要更改已定义的常量。这些值可以动态找到。

示例:

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);

此外,不必担心是指定绝对 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;
}

最后,正如@HarshSanghani 在评论中提到的,.htaccess 文件中的基本路径应该 与代码中的基本路径相匹配。因此,如果 BASE_PATH(基于上面的示例)输出 /project_name/,那么您的 .htaccess 应该容纳它:

RewriteBase /project_name/

关于php - 来自重写的基本文件夹的绝对 URL,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36979160/

相关文章:

php - sql查询的问题

php - 在 Codeigniter 中查找数据库中实际删除或未删除的数据的方法

.htaccess - 将 http 重定向到 https(不包括子域)

.htaccess - .htaccess 中的多 View 选项到底有什么作用?

.htaccess - URL 重写 blog.domain.com 为 www.domain.com/blog

php - 如何使用 RewriteRule 来执行不可见的搜索查询?

php - CodeIgniter 关闭自动路由?

PHP - 从带有下拉列表的动态列表的每一行捕获多个变量

php - 使用 htaccess 从 URL 中删除 .php

linux - apache 重写的 URL 包含完整的 Linux 路径