Динамическая маршрутизация Codeigniter

Привет, я хочу сделать что-то подобное.

http: // example.com/ – Главный контроллер

http: // example.com/rules/ – главный контроллер, в котором контент получается из базы данных, но если нет, верните страницу 404. (Все в порядке, это не проблема.)

Но если у меня есть вложенная папка в application / controlles / rules / я хочу перенаправить ее в папку Main Contorller at Rules.

Этот следующий код может решить проблему, но я не знаю, как это правильно понять. На routes.php:

$route['default_controller'] = "main"; $route['404_override'] = ''; $dirtest = $route['(:any)']; if (is_dir(APPPATH.'controllers/'.$dirtest)) { $route['(:any)'] = $dirtest.'/$1'; } else { $route['(:any)'] = 'main/index/$1'; } 

Хорошо, что у меня есть:

Контроллеры / main.php

 class Main extends CI_Controller { public function __construct() { parent::__construct(); $this->load->model('main_model'); } public function index($method = null) { if (is_dir(APPPATH.'controllers/'.$method)) { // Need re-rout to the application/controllers/$method/ } else { if ($query = $this->main_model->get_content($method)) { $data['content'] = $query[0]->text; // it shows at views/main.php } else { show_404($method); } } $data['main_content'] = 'main'; $this->load->view('includes/template', $data); } } 

Обновлено снова (routes.php): Итак, похоже, что я ищу (пример работы):

 $route['default_controller'] = "main"; $route['404_override'] = ''; $subfolders = glob(APPPATH.'controllers/*', GLOB_ONLYDIR); foreach ($subfolders as $folder) { $folder = preg_replace('/application\/controllers\//', '', $folder); $route[$folder] = $folder.'/main/index/'; $route[$folder.'/(:any)'] = $folder.'/main/$1'; } $route['(:any)'] = 'main/index/$1'; 

Но совершенно необходимо, чтобы это было так:

http: // example.com/1/2/3/4/5/6 / …

  1. Папка «Контроллеры» имеет подпапку «1»?
  2. ДА: Папка «1» имеет подпапку «2»?
  3. НЕТ: Папка «1» имеет контроллер «2.php»?
  4. НЕТ: Контроллеры "1 / main.php" имеют функцию "2"?
  5. ДА: перенаправить на http: // example.com/1/2/ – где 3,4,5 – параметры ..

Это очень хорошо, когда у вас есть структура вроде:

 http://example.com/blog/ - recent blog's posts http://example.com/blog/2007/ - recent from 2007 year blog's posts http://example.com/blog/2007/06/ - same with month number http://example.com/blog/2007/06/29/ - same with day number http://example.com/blog/web-design/ - recent blog's post's about web design http://example.com/blog/web-design/2007/ - blog' posts about web design from 2007 years. http://example.com/blog/current-post-title/ - current post 

То же самое интересное я нахожу http://codeigniter.com/forums/viewthread/97024/#490613

Я не полностью прочитал ваш вопрос, но это сразу привлекло мое внимание:

 if (is_dir($path . '/' . $folder)) { echo "$route['$folder/(:any)'] = '$folder/index/$1';"; //<---- why echo ??? } 

Честно говоря, я не уверен, почему это не вызвало серьезных проблем для вас, а не для работы.

Вы не хотите echo маршрута здесь, который просто попытается напечатать строку на экране, и это даже не интерпретируется как PHP. Также есть некоторые проблемы с кавычками, которые необходимо устранить, поэтому переменные можно читать как переменные, а не строки. Попробуйте это вместо этого:

 if (is_dir($path . '/' . $folder)) { $route[$folder.'/(:any)'] = $folder.'/index/$1'; } 

Кроме того : я хотел бы предложить некоторые дополнительные ресурсы, которые напрямую не связаны с вашей проблемой, но должны помочь вам, тем не менее, с решением:

Трудно сказать, почему регистрация ваших маршрутов терпит неудачу. Из вашего кода я вижу, что вы не регистрируете маршруты (вы просто эхо их), кроме того, я вижу, что использование переменных в строках используется непоследовательно. Вероятно, вы немного смешали это, документация по кодовым ссылкам о маршрутах также не является точной (в некоторых второстепенных точках их примеры кода на самом деле не являются синтаксически правильными, но в целом это хорошо).

Я предлагаю вам сначала переместить логику, чтобы зарегистрировать ваши динамические маршруты в свою собственную функцию. Это будет держать вещи немного более модульными, и вы можете легко изменить ситуацию, и вы не будете загрязнять глобальное пространство имен переменными.

Исходя из этого, я немного переработал ваш код. Это не означает, что это работает (не проверено), однако это может сделать вещи более ясными, когда вы читаете это:

 function register_dynamic_routes($path, array &$route) { $nodes = scandir($path); if (false === $nodes) { throw new InvalidArgumentException(sprintf('Path parameter invalid. scandir("$path") failed.', $path)); } foreach ($nodes as $node) { if ($node === '.' or $node === '..') continue ; if (!is_dir("{$path}/{$node}") continue ; $routeDef = "{$folder}/(:any)"; $routeResolve = "{$folder}/index/\$1"; $route[$routeDef] = $routeResolve; # FIXME debug output echo "\$route['{$routeDef}'] = '{$routeResolve}';"; } } $path = APPPATH.'controllers/'; register_dynamic_routes($path, $route); $route['(:any)'] = 'main/index/$1'; 

Рядом с этим вы, возможно, не захотите перекладывать все на действие index , а вместо этого – на dynamic . Кроме того, вы можете захотеть иметь базовый контроллер, который делегирует все в субконтроллеры вместо добавления маршрутов на контроллер. Но это зависит от вас. Приведенный выше пример основан на подходе к каталогу, который вы указали в своем вопросе.

Изменить: дополнительная информация доступна в разделе « Контроллеры» рядом с разделом «Маршрутизация URI»

Все это кажется сложным.

Кроме того, если у вас есть сотни (или тысячи или более?) Возможных маршрутов в базе данных, вы можете не захотеть загружать их все в массив «$ routes» каждый раз, когда любая страница загружается в ваше приложение.

Вместо этого, почему бы просто не сделать это?

последняя строка маршрутов.php:

 $route['404_override'] = 'vanity'; 

Файл контроллера: Vanity.php:

 <?php defined('BASEPATH') OR exit('No direct script access allowed'); class Vanity extends MY_Controller { /** * Vanity Page controller. * */ public function __construct() { parent::__construct(); } public function index() { $url = $_SERVER['PHP_SELF']; $url = str_replace("/index.php/", "", $url); // you could check here if $url is valid. If not, then load 404 via: // // show_404(); // // or, if it is valid then load the appropriate view, redirect, or // whatever else it is you needed to do! echo "Hello from page " . $url; exit; } } ?>