【问题标题】:Apache/PHP url parse issueApache/PHP url 解析问题
【发布时间】:2012-07-07 07:09:06
【问题描述】:

所以,我正在使用我正在构建的 PHP 应用程序玩一些 url。

我正在使用 .htaccess 使用 mod_rewrite。看起来是这样的:

<IfModule mod_rewrite.c>
    RewriteEngine On
    RewriteBase /

    RewriteCond %{REQUEST_FILENAME} !-f
    RewriteCond %{REQUEST_FILENAME} !-d
    RewriteRule (.*) index.php/$1
</IfModule>

我想如果一个 URL 是这样写的:

http://localdomain.com/controller

我希望作为 $_SERVER['PATH_INFO'] 的一部分的“控制器”结束时不会出现问题。但是,在运行 Apache 2.2.22 的 Ubuntu 12.04 上,我得到了 404 Not Found 错误:

NOT FOUND
The requested URL /index.php/controller was not found on this server.

似乎在 index.php 后面的斜杠后正确处理了“控制器”,但是有谁知道为什么我得到的是 404 而不是预期的响应?

最终,我试图捕获“控制器”以在我正在构建的 MVC 框架中使用。

在这种情况下,我有一个非常简单的 index.php,只有以下内容:

<?php
echo $_SERVER['PATH_INFO'];

然而,我仍然收到 404 错误,而不是预期的路径信息。

注意:仅使用 http://localdomain.com/http://localdomain.com/index.php 即可完美运行。 mod_rewrite 已打开且正在工作,并且 AllowOverride 设置为 All。

【问题讨论】:

    标签: php apache mod-rewrite


    【解决方案1】:

    这是我为我的 MVC 创建并使用的 .htaccess:

    # Mod Rewrite
    <IfModule mod_rewrite.c>
        RewriteEngine On
    
        RewriteCond %{REQUEST_FILENAME} !-f
        RewriteCond %{REQUEST_FILENAME} !-d
    
        RewriteRule ^(.*)$          /root/index.php/$1 [PT,L]
    </IfModule>
    

    尝试添加^$ + [PT,L]

    【讨论】:

    • 这似乎没有帮助。我仍然得到相同的 404。好像 Apache 根本不允许重写工作,但我已经测试过了。
    • 您在httpd.conf 中有命令AllowOverride All 吗?你安装了mod_rewrite 吗?这不是.htaccess 文件的错,因为我知道我的工作正常。那么问题出在 Apache2 或那里的某个地方,而不是文件。
    • 这很奇怪,所以这就是我在这里发布问题的原因。是的,AllowOverride 设置为 All 并且 mod_rewrite 也已安装。我在开发环境中安装了许多其他站点,用于运行 CakePHP 或 Zend Framework 的问题,它们都运行良好。我知道我一定错过了什么。
    • @AdamCulp 是的,我同意这一定是个愚蠢的理由。检查 mod_rewrite 的日志。
    【解决方案2】:

    如果您希望在没有 index.php 的情况下重写 URL,那么只需使用:

    RewriteRule ^(.*)$ index.php [NC,L]
    

    【讨论】:

      【解决方案3】:

      如果您运行的是 apache 2.2.22,那么您的 PHP 代码现在负责在找到控制器函数时指定 200 响应。

      与 2.2.14 相比,Apache 2.2.22 似乎采用了不同的重写理念。说来话长,但很有道理。它假设如果您正在重写像 CodeIgniter 这样的前端控制器,那么 PHP 代码负责决定是否找到了请求的 URI。 Apache 等待 PHP 代码发送 header('HTTP/1.1 200 OK'),如果没有,则发送 header('HTTP/1.1 404 Not Found')。

      有趣的是,来自控制器的实际内容也可能在响应正文中发送。但是如果响应代码是 404(如 MSIE、wget 等),许多 HTTP 客户端会忽略这一点

      简短的版本是 apache 2.2.14(铂金版)是乐观的,假设 200 除非 PHP 另有规定,而 apache 2.2.22 是悲观的,假设 404 除非 PHP 另有规定。

      所以在你的代码中的某个地方,你必须放置:

      header('HTTP/1.1 200 OK');
      

      这应该放在前端控制器确定 URI 有效并且存在并且可以为此 URI 调用的类和方法之后,但在实际调用类和方法之前。

      在 CodeIgniter 2.1.3 中,它看起来像这样:

      // Added this line for Apache 2.2.22
      header('HTTP/1.0 200 OK');
      // Call the requested method.
      // Any URI segments present (besides the class/function) will be passed to the method for convenience
      call_user_func_array(array(&$CI, $method), array_slice($URI->rsegments, 2));
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2011-10-03
        • 1970-01-01
        • 2011-08-02
        • 2011-05-29
        • 2013-05-20
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多