控制器定位/目录路由

时间:2014-10-13 06:45:13

标签: php loops url-routing directory-structure

我目前正在使用我的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这样”。

3 个答案:

答案 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"
}