PHP链接控制系统

时间:2012-02-17 21:40:06

标签: php .htaccess hyperlink

我对PHP中的“链接控制系统”有疑问。我们的想法是创建可以创建与原始链接不同的脚本 - 例如与.htaccess的友好链接。在.htaccess中制定规则将所有流量重定向到脚本文件 - 例如linkprocessor.php然后在这个文件中应该是一些条件,mysql连接和来自数据库的模式抓取器(friendlyurl和originalurl列)。因此,如果我们写完整地址 - example.com/defined-address它会将我们(但不是更改地址)重定向到linkprocessor.php然后脚本检查/ defined-address是否在数据库中,如果它将包含某些(基于在friendlyurl)originalurl文件。这个脚本会是最佳的吗?该脚本可以防止“黑客”。

示例:

example.com/defined-address - > linkprocessor.php - >表格中的SELECT originalurl WHERE friendlyurl = / defined-address - >包括originalurl

=>可以写成语无伦次,但很难准确地解释

2 个答案:

答案 0 :(得分:2)

您正在寻找的是前端控制器设计模式。

您描述了解决此问题的基本方法,即将所有传入请求(减去静态内容请求,如图像,CSS文件和JS文件)重定向到单个文件。通常,此文件是站点根目录中的index.php文件,但可以是任何文件。

您可以使用Apache服务器上的.htaccess或IIS服务器上的web.config完成此重定向。对于.htaccess,您可以google mod_rewrite并获取大量有助于您的信息。

将所有请求定向到前端控制器后,您需要确定请求的要求。您可以检查PHP的$_SERVER['REQUEST_URI']以查看请求是什么,并相应地处理它。

我见过的这个问题的最具扩展性的解决方案依赖于位于特定位置的控制器(类)和位于不同位置的“静态”文件。通过执行以下操作,可以轻松扩展您的网站将响应的请求:

/** 
   I am assuming at this point that the variable $request is an array 
   representing the current request.  For example, if the request is for: 
   http://www.example.com/dir/page, $request will contain two entries, 
   'dir' and 'page'
 **/

if(file_exists('/controllers/' . $request[0] . '.php')) {
    require_once '/controllers/' . $request[0] . '.php';
    $controller = new $request[0]();
    $controller->dispatch($request);
} else if(file_exists( '/static/'.$request[0] . '.php')) {
    require_once '/static/' . $request[0] . '.php';
} else 
    throw new Exception('404', 404);

以上是比实际代码更多的伪代码,我不保证它会实际运行但是这个想法就在那里。

要在系统中添加另一个控制器,您只需编写一个类,确保它具有dispatch方法,并将其放在正确的位置。

答案 1 :(得分:2)

您在这里询问的是前端控制器模式http://en.wikipedia.org/wiki/Front_controller

有多种方法可以实现它,使用sql数据库将URI字符串映射到要包含的文件是一种有效的方法,但可能有点过分。相同的信息可能在php数组中进行硬编码。

防止黑客的标准方法是仅允许列入白名单文件。在您的情况下,您使用显式地图来确定要包含的页面,因此这不是问题。

一些代码可以帮助您入门:

<?php

$map = array('/home' => 'included_1', '/details' => 'included_2' ... )

if (array_key_exists($_SERVER['REQUEST_URI'], $map)) {
    include $map[$_SERVER['REQUEST_URI']]
}
else {
    // Send a 404 response
}