Codeigniter Dynamic Routing - PullRequest
       14

Codeigniter Dynamic Routing

2 голосов
/ 07 августа 2011

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

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

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

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

Этот следующий код можетрешить проблему, но я не знаю, как это правильно реализовать.По адресу rout.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';
}

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

controllers / 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);
    }

}

ОбновленоОпять же (rout.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. NO: папка "1" имеет контроллер "2.php"?
  4. NO: контроллер "controllers / 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

Ответы [ 3 ]

3 голосов
/ 08 августа 2011

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

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';
}

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

1 голос
/ 07 августа 2011

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

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

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

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Маршрутная секция

0 голосов
/ 10 ноября 2015

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

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

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

последняя строка маршрутов .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;



}


}


?>
...