Apache 特定的重写是如何工作的?

Apache 特定的重写是如何工作的?,apache,mod-rewrite,yii,url-rewriting,apache2,Apache,Mod Rewrite,Yii,Url Rewriting,Apache2,Yii框架使用的路径形式为http://foo.bar/index.php/foo/bar/baz 有一个函数告诉我们如何使用mod_rewrite RewriteEngine on # if a directory or a file exists, use it directly RewriteCond %{REQUEST_FILENAME} !-f RewriteCond %{REQUEST_FILENAME} !-d # otherwise forward it to index.p

Yii框架使用的路径形式为
http://foo.bar/index.php/foo/bar/baz

有一个函数告诉我们如何使用
mod_rewrite

RewriteEngine on

# if a directory or a file exists, use it directly
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d

# otherwise forward it to index.php
RewriteRule . index.php
问题是,我不明白重写
http://foo.bar/foo/bar/baz

  • 重写引擎接收
    foo/bar/baz

  • 匹配
    foo/bar/baz

  • 由于
    2
    为真,因此也会检查这两个条件,并且它们是匹配的

  • foo/bar/baz
    替换为
    index.php

  • 重写的下一次迭代不会更改路径,因为文件实际上存在,并且第一个条件不匹配

  • 执行内部重定向到
    index.php


  • 我不能得到的是为什么我能看到
    http://foo.bar/index.php/foo/bar/baz
    重定向到
    http://foo.bar/index.php

    好的,原因很简单。如果您重写到一个新位置,整个url路径和所有查询部分都将相对于新文件位置进行设置。因此,在第一次迭代期间,该文件不存在,因此整个路径是相对于index.php设置的

    具体来说,重写可以做两件事:

  • 将url映射到文件
  • 重定向到一个全新的url
  • 第一个是重新映射,因此没有新的请求。这就是我们在这里使用的。旧请求被映射到index.php,因此您的答案是:否,使用相同的请求。 如果我们重定向到一个url(无论是否在同一台服务器上),就会触发一个新的请求。请参见此处的介绍文字:

    然后调用index.php(前端控制器模式),yii使用路径和查询参数来定位相应的控制器和操作。这样做很容易:

    <?php
    //remove slashes
    $str = trim($_SERVER['REQUEST_URI'], '/');
    //remove index
    $str = trim($str, 'index.php');
    //remove slashes
    $str = trim($str, '/');
    
    //get parts
    $urlParts = explode('/', $str);
    
    //fill vars
    $module     = count($urlParts) == 2 ? $urlParts[0] : null;
    $controller = count($urlParts) == 2 ? $urlParts[0] : $urlParts[1];
    $action     = count($urlParts) == 2 ? $urlParts[1] : $urlParts[2];
    
    //call controller / action via reflection HERE
    

    对代码进行了一点改进……这真的只是想让您知道如何做到这一点!当然,您会担心零件数量错误等,但这不是本答案的主题。希望能有帮助:)!Apache是否向'` while internal redirect'发出新的HTTP请求?如果是,
    index.php
    如何知道原始路径
    foo/bar/baz
    ?我对执行php脚本之前实际发生的情况感兴趣。Apache是在内部发出新的HTTP请求,还是保留原始请求中的所有HTTP头并将其传递到新文件?据我所知,Apache只是重定向它并使用修改的参数保留请求(我必须承认这是一个很深的问题)。第二部分我可以回答你。如果创建的php脚本只包含以下内容:
    echo'req url:'$_服务器['REQUEST_URI']
    并使用myscript.php/bla/test/调用它,然后
    /bla/test/
    将成为它的一部分。在index.php中,您可以像这样获取请求的url,并对其执行任何操作。有很多$\u服务器变量非常有用,因为它们包含所有请求内容!现在,当我们知道Apache在
    内部重写期间将原始HTTP请求“映射”到不同的文件时,Yii从HTTP头检索原始请求路径的方式就非常明显了。我的错误是,我过去认为一个带有新头的新HTTP请求是由Apache内部执行的。谢谢,问题解决了。