我目前正在使用我的Router类,我有这个函数来分析/解析URI,并以控制器,方法和参数为目标。
在这个函数中,我必须定位可以放在一个目录或一堆子目录中的实际控制器,例如: “其他类别/一些目录/实际Controller.php这样”。
目前,我逐级手动检查它,我必须为每个级别添加一个条件语句。
在这种方法中,可能为实际控制器检查的目录深度仅取决于条件语句的数量。所以我发现这有点凌乱,绝对有限。
我正在考虑并寻找一种更好的方法来检查这一点,我不需要做那些条件语句。如果你能帮助我以更好的方式结束,那将非常感激。
这是我定位控制器段的部分:
$this->target_controller = array_shift($segments);
// check if there's a first-level directory
if(is_dir(CONTROLLERPATH.$this->target_controller)){
$this->dirs[] = $this->target_controller;
$this->target_controller = array_shift($segments);
}
// check if there's a second-level directory
if(isset($this->dirs[0])){
if(is_dir(CONTROLLERPATH.$this->dirs[0]."/".$this->target_controller)){
$this->dirs[] = $this->target_controller;
$this->target_controller = array_shift($segments);
}
}
// check if there's a third-level directory
if(isset($this->dirs[0]) && isset($this->dirs[1])){
if(is_dir(CONTROLLERPATH.$this->dirs[0]."/".$this->dirs[1]."/".$this->target_controller)){
$this->dirs[] = $this->target_controller;
$this->target_controller = array_shift($segments);
}
}
// check if there's a fourth-level directory
if(isset($this->dirs[0]) && isset($this->dirs[1]) && isset($this->dirs[2])){
if(is_dir(CONTROLLERPATH.$this->dirs[0]."/".$this->dirs[1]."/".$this->dirs[2]."/".$this->target_controller)){
$this->dirs[] = $this->target_controller;
$this->target_controller = array_shift($segments);
}
}
上面代码段中的第一行代码将段分配给 target_controller属性。然后是下面的条件语句 将检查实际控制器是否放在目录或 子目录,例如 “其他类别/一些目录/实际Controller.php这样”。
答案 0 :(得分:1)
显然,我无法测试你的整个代码,但这会有什么作用呢?如果我们进行循环,则此代码假定始终会设置$this->dirs[$i]
并且所有父目录也是如此(至少我会这么认为)。
<?php
$this->target_controller = array_shift($segments);
// check if there's a first-level directory
if (is_dir(CONTROLLERPATH . $this->target_controller)){
$this->dirs[] = $this->target_controller;
$this->target_controller = array_shift($segments);
}
for ($i = 0; $i < count($this->dirs); $i++) {
if (is_dir(CONTROLLERPATH . implode("/", $this->dirs) . "/" . $this->target_controller)) {
$this->dirs[] = $this->target_controller;
$this->target_controller = array_shift($segments);
}
}
另一种选择是do while循环
不太确定此选项与前一个示例相比如何优化。
<?php
$this->dirs = array();
$this->target_controller = array_shift($segments);
$counter = -1;
do {
$implodedPath = implode("/", $this->dirs);
if (is_dir(CONTROLLERPATH . $implodedPath . ((empty($implodedPath)) ? "" : "/") . $this->target_controller)) {
$this->dirs[] = $this->target_controller;
$this->target_controller = array_shift($segments);
}
$counter++;
} while ($counter < count($this->dirs));
答案 1 :(得分:1)
我喜欢for
循环:
$this->dirs = array(CONTROLLERPATH);
for($this->target_controller = array_shift($segments);
$this->target_controller !== null && is_dir(implode('/', $this->dirs).'/'.$this->target_controller);
$this->target_controller = array_shift($segments))
{
$this->dirs[] = $this->target_controller;
}
<强>更新强>
$current_path = CONTROLLERPATH;
for($this->target_controller = array_shift($segments);
$this->target_controller !== null && is_dir($current_path.'/'.$this->target_controller);
$this->target_controller = array_shift($segments))
{
$this->dirs[] = $this->target_controller;
$current_path .= '/'.$this->target_controller;
}
答案 2 :(得分:1)
如果您的细分不包含..
可能会导致文件被CONTROLLERPATH
移出,则可以使用以下代码。
$this->dirs = array (CONTROLLERPATH);
while (count($segments) && is_dir(implode('/', $this->dirs).'/'.($element = array_shift($segments))))
{
$this->dirs[] = $element;
}
array_shift($this->dirs);
$this->target_controller = $element;
<?php
define('CONTROLLERPATH', './');
class A
{
public function test()
{
$segments = explode('/', 'a/b/c/d/controller/action/argA/argB');
$this->dirs = array (CONTROLLERPATH);
while (count($segments) && is_dir(implode('/', $this->dirs) . '/' . ($element = array_shift($segments))))
{
$this->dirs[] = $element;
}
array_shift($this->dirs);
$this->target_controller = $element;
}
}
mkdir('./a/b/c/d', 0777, true);
$a = new A();
$a->test();
var_dump($a);
返回:
class A#1 (2) {
public $dirs =>
array(4) {
[0] =>
string(1) "a"
[1] =>
string(1) "b"
[2] =>
string(1) "c"
[3] =>
string(1) "d"
}
public $target_controller =>
string(10) "controller"
}