В настоящее время я работаю с моим классом 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».
Если ваши сегменты не содержат ..
что может привести к получению файлов снаружи 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"}
мне нравится 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;
}
Очевидно, я не могу протестировать весь ваш код, но будет ли что-то похожее на эту работу? Если мы зациклились, этот код предполагает, что $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));