所以我有一个名为Engine的库.php它基本上是运行
example.com/controller/method/value
所以例如,如果我有
example.com/category/images
它运行称为"图像"的方法。但我不想为每个类别添加代码。我希望该方法是一个变量(以便稍后使其与 db 一起使用)。
如何在不更改引擎的情况下实现此目的?问题是 - 有些页面根本没有类别。而且我不想重写引擎本身。
我可以以某种方式在控制器中执行此操作吗?例如:
我正在输入名为"类别"的控制器,如果设置了方法,它会在控制器("类别")中搜索此方法。
这是我的引擎.php的一部分:
if (isset($url_output[1])) {
if (isset($url_output[2])) {
if (method_exists($controller,$url_output[1])) {
$controller->{$url_output[1]}($url_output[2]);
} else {
$this->error();
}
} else {
if (method_exists($controller,$url_output[1])) {
$controller->{$url_output[1]}();
} else {
$this->error();
}
}
}
所以基本上,如您所见:
$controller->{$url_output[1]}();
$url_output[1] = 控制器中名为 $url_output[0] 的方法的名称。
我想要的是:
public function $category() {
echo $category
}
你知道我的意思?
你为什么不做这样的网址
example.com/category/index/images
其中 index 是类别控制器的预定义函数,图像将作为第一个参数传递给索引函数。
第二种选择,绕过 url 中的索引函数。
if (isset($url_output[1])) {
if (method_exists($controller,'index')) {
$controller->index($url_output[1]);
} else {
$this->error();
}
}
class Category
{
function index($category)
{
}
}
像这样使用:example.com/category/images
您可以尝试使用变量。
警告:从安全的角度来看,这是非常危险的,所以如果你这样做,你应该确保你验证你的输入!
if (isset($url_output[1])) {
if (isset($url_output[2])) {
if (method_exists($controller,$url_output[1])) {
$controller->{$url_output[1]}($url_output[2]);
} else {
$this->error();
}
} else {
if (array_search($allowed_categories, $url_output[1]) !== FALSE) {
echo ${$url_output[1]};
} else {
$this->error();
}
}
}
基本上,如果$url_output[1]
是image
,则${$url_output[1]}
转换为$image
,然后输出$image
变量的值。$allowed_categories
变量应该是一个包含要处理的任何类别的数组。这是为了防止恶意用户输入某些将输出敏感变量的类别。
您需要做的是为项目创建一个真正的路由机制。我已经在另外两个答案中涵盖了它:这个和这个。其中一个我已经将您链接到一次。
关键是要创建正则表达式(regexp),您可以匹配传入的URL。如果找到匹配的模式,则可以使用 preg_match()
将其拆分,并在缺少 URL 的非必填部分时分配一些默认值。
您可以自己创建路由机制,也可以从其他项目(简单或复杂)移植它。
此外,还应将应用程序的路由部分与处理调度到控制器的部分分开。检查控制器中是否存在此类方法或是否允许用户访问该方法不是路由过程的一部分。如果将它们混合在一起,您将违反SRP。