使用RewriteRule进行URL路由

时间:2013-05-04 08:02:46

标签: php mod-rewrite url-routing

我正在尝试创建自己的PHP MVC框架以用于学习目的。我有以下目录结构:

本地主机/ MVC:

.htaccess
index.php
application
controller
model
view
config/
    routes.php
error/
    error.php

在application / config / routes.php中我有以下代码:

$route['default_controller'] = "MyController";

现在我想要实现的是当任何用户使用浏览器访问我的根目录时我希望从route.php文件中获取$route['default_controller']的值并在文件夹controller中加载php类与值匹配。

如果有任何用户试图使用这样的网址localhost/mvc/cars尝试访问我的应用程序,我想在我的控制器文件夹中搜索类名cars并加载它。如果没有名为cars的类,那么我想将用户带到error/error.php

我想要实现上述目标,我必须使用根目录中的.htaccess文件。你能告诉我在那里编码吗?如果有任何其他方法可以实现这一点,请建议我。

我曾尝试使用here中的.htaccess代码,但它不适用于我

1 个答案:

答案 0 :(得分:4)

从流行语的角度来看,这一切听起来都很好,但对我来说这有点令人困惑,因为我已经将PHP的模型视为MVC模型了。它为您提供API编程并将您的内容提供给您的Web服务器Apache和您的数据库(类似于MySQL)。它将您的代码(模型)转换为HTML(视图)...前提是您的意图,并且您提供代码作为用户输入(控件)。如果你把一个人带到不熟悉你的约定的人那里进行合作,那么过于局限于术语就会让人分心,并且会导致混乱。 (这可能永远不会在生产环境中用于付费演出。)

我可以告诉你,在你引用的页面上,他们的.htaccess文件需要一些工作。 [L]标志告诉mod_rewrite这是规则返回true时要处理的最后一个命令。所以你要么需要这样做:

<IfModule mod_rewrite.c>
    RewriteEngine on
    RewriteRule    ^(.*)$    public/$1    [L]
 </IfModule>

或者以下......但他正在使用passthru标志,这意味着他暗示在最后一条规则之前还有其他事情可以处理(例如可能是rewrite_basealias),但他的.htaccess文件实际上并非如此,因为它有点裸露。所以这段代码的工作方式类似于上面的代码,但不完全相同。它们不能一起使用,实际上不需要:

<IfModule mod_rewrite.c>
    RewriteEngine on
    RewriteCond %{REQUEST_FILENAME} !-f
    RewriteCond %{REQUEST_FILENAME} !-d
    RewriteRule ^(.*) index.php?url=$1
 </IfModule>

区别在于它的处理方式。在第一个.htaccess示例中,您将任何文件传递给index.php,无论它是否存在。您可以[意外]重写具有真实文件的路径,以便永远不会使用此方法访问真实文件。例如,您有一个名为site.css的文件无法访问,因为它被重定向回index.php

在第二个规则集中,他至少要检查服务器是否没有所请求名称的文件或目录,然后他们将index.php转发给$_GET RewriteEngine On RewriteCond %{HTTP_HOST} ^mydomain.com RewriteRule (.*) http://www.mydomain.com/$1 [R=301,L] RewriteCond %{SCRIPT_FILENAME} !-f RewriteCond %{SCRIPT_FILENAME} !-d RewriteRule .* index.php 变量(看起来有点无意义)。

我通常写这些的方式(因为我知道mod_rewrite已经在配置中加载)就是这样:

$_SERVER['REQUEST_URI']

在我的PHP代码中,我拉出<?php $intended_path = $_SERVER['REQUEST_URI']; if(in_array($intended_path,$uris_from_database)){ //show the page. } else { $search_phrase = preg_replace('!/!',' ',$intended_path); $search_phrase = mysqli_real_escape_string($search_phrase); $sql = "SELECT * FROM pages WHERE MATCH (title,content) AGAINST ('$search_phrase');" } 并将其与数据库中的URI列表进行匹配。如果有匹配,那么我知道它是一个真实的页面(或者至少在某个时间点存在记录)。如果没有匹配,那么我会使用FULLTEXT搜索来爆炸request_uri并强制它通过数据库,以查看网站上可能匹配的内容。

注意:如果您盲目信任request_uri并直接查询数据库而不清除它,则会冒着SQL注入的风险。你不想成为pwnd

{{1}}

很抱歉,如果这听起来有点迂腐,但我有管理几百万美元(刮刮)网站构建的经验,这些网站构建的障碍与不遵守标准惯例的人(或至少是商定的团队共识) )。