Таргетинг контроллера / маршрутизация каталогов

В настоящее время я работаю с моим классом 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».

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"}
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;
}
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
По вопросам рекламы [email protected]