Маршрутизация на основе базы данных в CodeIgniter 2.x

Я создаю сайт, на котором будет много маршрутов, которые нужно будет добавить в файл маршрутов (800+) — очевидно, я не хочу вручную добавлять их один за другим в файл конфигурации маршрутов.

Может ли кто-нибудь предложить наилучшую практику автоматической загрузки моих маршрутов из базы данных. Есть ли подходящая библиотека/помощник, который выполнит эту задачу, которая работает с версией 2.x?

Например..

$route['apple'] = 'brands/index';
$route['blackberry'] = 'brands/index';
$route['htc'] = 'brands/index';
$route['samsung'] = 'brands/index';

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

Я использую Codeigniter v2.1.3


person Zabs    schedule 11.06.2013    source источник
comment
У меня была аналогичная проблема, я решил ее, создав страницу "routes" после запроса администратора. например, я делаю некоторые изменения в своей базе данных (маршруты), чем я создал файл my_routes.php (имя не имеет большого значения) и включил его в исходный routes.php. О влиянии на сайт понятия не имею. Никогда не тестировал 800+ маршрутов. У меня всего около 20, но пользователь/администратор может добавлять новые через php-скрипт.   -  person Kyslik    schedule 11.06.2013


Ответы (4)


Если бы вы постоянно запрашивали базу данных (при каждой загрузке страницы) через вызов БД в файле application/config/routes.php, я полагаю, что это сильно повлияло бы на производительность.

Что бы я предложил (и способ, которым я сделал это ранее), это включить следующую строку в конец вашего файла routes.php и сохранить все ваши маршруты в файл routes.php в папке cache.

require_once APPPATH . 'cache/routes.php';

Затем вы можете записать все свои результаты в файл кеша (используя помощник файла CI) с помощью функции, аналогичной приведенной ниже:

public function save_routes() {
        $routes = $this->routes_model->get_all_routes();

        $data = array();

        if (!empty($routes )) {
            $data[] = '<?php if ( ! defined(\'BASEPATH\')) exit(\'No direct script access allowed\');';

            foreach ($routes as $route) {
                $data[] = '$route[\'' . $route['uri'] . '\'] = \'' . $route['controller'] . '/' . $route['action'] . '\';';
            }
            $output = implode("\n", $data);

            write_file(APPPATH . 'cache/routes.php', $output);
        }
    }

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

Этот метод сохраняет ваши маршруты в application/config/routes.php нетронутыми, но позволяет вам записывать новые маршруты в файл кеша без существенного влияния на производительность сайта.

Надеюсь, это поможет!!

person MY_Mark    schedule 11.06.2013
comment
Вау .. это выглядит потрясающе, Марк, спасибо за это, я обязательно скоро попробую :) - person Zabs; 11.06.2013
comment
еще не пробовал, но похоже, что это лучшее решение, спасибо, Марк - person Zabs; 14.06.2013
comment
@ MY_Mark , это сильно повлияет на производительность. Не могли бы вы перевести это утверждение в цифры? Что вы считаете «большим влиянием» в этом случае? 0,00001 секунды? - person Andrew; 14.02.2014
comment
@Andrew, использование кеша определенно лучше - person vasilenicusor; 10.12.2015
comment
Это просто потрясающе! - person Fahad; 15.06.2016

Это старый вопрос, но недавно я столкнулся с той же дилеммой и нашел этот ответ полезным.

http://osvaldas.info/smart-database-driven-routing-in-codeigniter

Создайте таблицу, в которую вы поместите все свои маршруты

CREATE TABLE IF NOT EXISTS `app_routes` (
  `id` bigint(20) NOT NULL auto_increment,
  `slug` varchar(192) collate utf8_unicode_ci NOT NULL,
  `controller` varchar(64) collate utf8_unicode_ci NOT NULL,
  PRIMARY KEY  (`id`),
  KEY `slug` (`slug`)
) ENGINE=MyISAM  DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci AUTO_INCREMENT=1;

Внутри приложения/config/routes.php

//два верхних — это оригиналы внутри маршрутов

$route[ 'default_controller' ]  = 'main';
$route[ '404_override' ]        = 'error404';

//новые выпуски

require_once( BASEPATH .'database/DB'. EXT );
$db =& DB();
$query = $db->get( 'app_routes' );
$result = $query->result();
foreach( $result as $row )
{
$route[ $row->slug ]                 = $row->controller;
$route[ $row->slug.'/:any' ]         = $row->controller;
$route[ $row->controller ]           = 'error404';
$route[ $row->controller.'/:any' ]   = 'error404';
}

пример я работал с INSERT INTO app_routes (slug, controller) VALUES ('о', 'страницы/о');

или вы можете написать небольшую cms для управления вашими маршрутами, что я и сделал в соответствии с последними битами на веб-сайте.

id | slug  | controller  | actions
1  | about | pages/about | edit / delete
person joemisika    schedule 22.01.2014
comment
Спасибо! я только что получил то, что искал, это также то, как получить доступ к DB lib в CI из файла маршрутов. - person hi0001234d; 10.09.2015

У меня может быть решение для управления пользовательским uri в приложении CI.

Скажем, есть таблица с именем «маршруты».

CREATE TABLE IF NOT EXISTS `routes` (
    `alias` VARCHAR(255) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL,
    `uri` VARCHAR(255) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL,
    PRIMARY KEY (`alias`),
    UNIQUE(`alias`)

) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_general_ci;

Затем пользовательский «помощник по URL» (application/helper/MY_url_helper.php)

// function that produces a safe uri
if( ! function_exists('safe_uri'))
{
    function safe_uri($str, $replace=array(), $delimiter='-') {
        if( !empty($replace) ) {
            $str = str_replace((array)$replace, ' ', $str);
        }

        $clean = iconv('UTF-8', 'ASCII//TRANSLIT', $str);
        $clean = preg_replace("/[^a-zA-Z0-9\/_|+ -]/", '', $clean);
        $clean = strtolower(trim($clean, '-'));
        $clean = preg_replace("/[\/_|+ -]+/", $delimiter, $clean);

        return $clean;
    }
}
// overriden function that checks if the uri exists in the routing table. If so, use this uri instead
if ( ! function_exists('site_url'))
{
    function site_url($uri = '')
    {
        $CI =& get_instance();
        if(in_array($uri, $CI->router->routes)){
            $key = array_search($uri, $CI->router->routes);
            if($key)$uri=$key;
        }
        return $CI->config->site_url($uri);
    }
}

Затем я назвал библиотеку route_manager, которая создает/изменяет маршрут и генерирует пользовательский файл route.php (application/libraries/route_manager.php, создает application/cache/routes.php)

Примечание. Ваше приложение должно иметь возможность записывать файлы в 'application/cache'

<?php  if ( ! defined('BASEPATH')) exit('No direct script access allowed');

class route_manager{

    public function set_alias($full_text, $uri){
        $this->load->helper('url');
        $sql = 'INSERT INTO `routes` (`alias`, `uri`) VALUES(?,?)
                ON DUPLICATE KEY UPDATE
                uri=VALUES(uri)';
        $this->db->query($sql, array(safe_uri($full_text), $uri));
    }

    public function create_routes_file(){
        $res = $this->db->get('routes');
        $output = '<' . '?' . 'php ' . 'if ( ! defined(\'BASEPATH\')) exit(\'No direct script access allowed\');' . CRLF . CRLF;
        foreach($res->result_array() as $rs){
            $output .= '$' . 'route[\'' . $rs['alias'] . '\'] = "' . $rs['uri'] . '";'. CRLF;
        }
        // unsure the file won't generate errors
        $route = array();
        eval('?> '.$output);
        // if error detected, the script will stop here (and won't bug the entire CI app). Otherwize it will generate the cache/route.php file
        $this->load->helper('file');
        write_file(APPPATH . 'cache/routes.php', $output);
    }

}

Затем добавьте require_once (4-я строка в примере ниже) в ваш файл application/config/routes.php.

<?php  if ( ! defined('BASEPATH')) exit('No direct script access allowed');

// require custom routes (if the file exists)
if(file_exists(APPPATH . 'cache/routes.php'))require_once(APPPATH . 'cache/routes.php');

$route['default_controller'] = "welcome";
$route['404_override'] = '';

Все будет работать, используя хороший uri!

Пример для создания пользовательского дьявольского uri, скажем, «супер-страница, которая ПОТРЯСАЕТ!» (действительно)» должен быть направлен на контроллер «страницы», функцию «индекс» с параметром «23»:

$this->load->library('route_manager');
$this->route_manager->set_alias('super page that ROCKS! (really)', 'page/index/23');
$this->route_manager->create_route_file();

Пример использования этого пользовательского uri

echo site_url('page/index/23');

Этот пример создаст дружественный и работающий URL-адрес, подобный этому:

http://www.yourwebsite.com/index.php/super-page-that-rocks-really

person Simmoniz    schedule 31.01.2014

require_once( BASEPATH .'database/DB.php');
$db =& DB();
$query = $db->get( 'app_routes' );
$result = $query->result();
foreach( $result as $row )
{
$route[ $row->slug ]                 = $row->controller;
$route[ $row->slug.'/:any' ]         = $row->controller;
$route[ $row->controller ]           = 'error404';
$route[ $row->controller.'/:any' ]   = 'error404';
}

В новой версии Codeigniter используется require_once( BASEPATH .'database/DB.php'); вместо require_once( BASEPATH .'database/DB'.EXT);

person Onur ÇİÇEK    schedule 26.04.2020