我认为一切都很好,直到我想缩短一些URL的我认为这将是一块蛋糕。
我已经开发了自己的MVC结构,其中所有页面都通过index.php,并根据url的相关控制器和模型被加载在飞行。这给了我漂亮和干净的url,使应用程序更容易开发,因为它变得更大。
在我的Htaccess文件中有如下内容:
RewriteRule ^(.+)$ index.php?url=$1 [QSA,L]
和在我的index.php中,我计算url的长度并加载所需的控制器等…
$length = count($url);
if($length > 5)
{
$this->Error->index();
return FALSE;
}
switch ($length)
{
case 5:
$controller_name->{$url[1]}($url[2], $url[3], $url[4]);
break;
case 4:
$controller_name->{$url[1]}($url[2], $url[3]);
break;
case 3:
$controller_name->{$url[1]}($url[2]);
break;
case 2:
$controller_name->{$url[1]}();
break;
default:
$controller_name->index();
break;
}
这一切都工作得很好,所以这是我的问题,我有一个url www.thepage.com/accounts/general_users/profile/[account_name]
所以我想通过删去'accounts/general_users/'来缩短这个url。我在我的htaccess中添加了以下内容:
RewriteRule ^profile/april.lee$ accounts/general_users/profile/april.lee [QSA,L]
但这似乎不想玩得很好与我的初始RewriteRule,如果它的位置低于第一个RewriteRule它只是不渲染,如果它在上面它似乎打破了应用程序。
我对该做什么很困惑,希望能得到一点指导/建议。我真的很想想出一个解决方案,而不必重新制作整个应用程序。
更新以演示如何加载控制器和模型:
1-我得到并清理URL:
// Get Clean URL
$url = isset($_GET['url']) ? $_GET['url'] : NULL;
$url = rtrim($url, '/');
$url = filter_var($url, FILTER_SANITIZE_URL);
$url = explode('/', $url);
// Start Session
session_start();
// Create Application Core
require_once(APP_PATH . "core/core.php");
$AC = new Application_Core($config);
2-检查是否为空
if(empty($url[0]))
{
// Load and Instantiate Model
require(APP_PATH."models/m_index.php");
$this->Model = new m_index();
// Load and Instantiate Controller
require(APP_PATH."controllers/index.php");
$controller = new index();
$controller->index();
}
else
{
// Load and Instantiate Model
$model_file = APP_PATH."models/m_".$url[0].".php";
if(file_exists($model_file))
{
include($model_file);
$model_name = "m_".$url[0];
$this->Model = new $model_name();
}
else
{
echo $url[0];
$this->Template->render_error($this->error_page, $this->error_message);
return FALSE;
}
// Load and Instantiate Controller
$controller_file = APP_PATH."controllers/".$url[0].".php";
if(file_exists($controller_file))
{
require(APP_PATH."controllers/".$url[0].".php");
$controller_name = $url[0];
$controller_name = new $controller_name();
}
else
{
$this->Template->render_error($this->error_page, $this->error_message);
return FALSE;
}
$length = count($url);
// Check Method Exists
if ($length > 1) {
if (!method_exists($controller_name, $url[1])) {
$this->Template->render_error($this->error_page, $this->error_message);
return FALSE;
}
}
if($length > 5)
{
$this->Error->index();
return FALSE;
}
switch ($length)
{
case 5:
$controller_name->{$url[1]}($url[2], $url[3], $url[4]);
break;
case 4:
$controller_name->{$url[1]}($url[2], $url[3]);
break;
case 3:
$controller_name->{$url[1]}($url[2]);
break;
case 2:
$controller_name->{$url[1]}();
break;
default:
$controller_name->index();
break;
}
3 -检查长度并加载适当的控制器和模型,如果方法不存在,则将用户重定向到错误页面
似乎不通过URL的长度来控制它可能会处理得更好。如果有人在最短链接的末尾输入额外的变量,看看会发生什么?如果他们从你的网站上得到的行为是针对其他用户的,这可能是不好的。
你可以使用htaccess来做你的交换机正在做的所有事情,而不那么令人头疼。
RewriteCond %{http_host} ^mysite.com/ [nc]
RewriteRule ^(.*)$ http://www.mysite.com/$1 [nc]
RewriteRule ^profile/(.*)$ accounts/general_users/profile/$1 [QSA, L]
RewriteRule ^url_for_control1/match$ index.php?controller=1&%{QUERY_STRING}
编辑:
要使您的index.php文件工作取决于它做什么,如果您的控制函数将用户重定向到另一个页面,您可以让htaccess为您做这件事。
例如,下面的…
RewriteCond %{http_host} ^mysite.com/ [nc]
RewriteRule ^(.*)$ http://www.mysite.com/$1 [nc]
RewriteRule ^employees/(.*)/(.*)$ index.php?first=$1&last=$2&%{QUERY_STRING}
将请求重定向到:
http://www.mysite.com/employees/john/doe
:
http://www.mysite.com/index.php?first=john&去年= doe&任何其他= variables_sent
…根据请求页面的方式使用GET或POST变量。
了解了这一点,您可以创建更干净的url,这些url对搜索引擎友好,并且更容易被人类阅读和理解。您可以继续向index.php发送请求,方法是搜索url中的特定特征,并通过一个变量告诉index.php页面要使用哪个控制函数。
仅仅根据URL中的字符数量来决定页面的操作并不是一个好主意,原因有很多,包括制作一个易于更改和升级的网站。
Net Tuts也有一个不错的初学者教程。