2

我正在创建一个站点,该站点将需要将大量路由添加到路由文件(800+)中-显然我不想手动将它们一一添加到路由配置文件中。

任何人都可以建议从数据库中自动加载我的路线的最佳做法。是否有合适的库/助手可以执行与 2.x 版一起使用的任务

例如..

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

这些只是我要添加到路线中的几个品牌 - 但是有数百个这样的品牌,所以我希望从数据库中加载而不是手动输入这些品牌。另外 - 这种方法会产生任何影响吗让他们从数据库中加载的现场性能?

我正在使用 Codeigniter v2.1.3

4

4 回答 4

10

如果您要通过文件中的数据库调用不断查询数据库(在每个页面加载时),application/config/routes.php那么我想会对性能产生很大影响。

我建议(以及我之前这样做的方式)是在routes.php文件底部包含以下行,并将所有路由保存到缓存routes.php文件夹中的文件中。

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保持不变,但允许您将新路由写入缓存文件,而不会严重影响站点的性能。

希望有帮助!!

于 2013-06-11T13:44:23.737 回答
5

这是一个老问题,但我最近面临同样的困境,发现这个答案很有用。

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;

在 application/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 ('about', 'pages/about');

或者您可以编写一个小 cms 来控制您的路线,这就是我根据网站上的最后一点所做的

id | slug  | controller  | actions
1  | about | pages/about | edit / delete
于 2014-01-22T04:54:32.987 回答
4

我可能有一个解决方案来管理 CI 应用程序中的自定义 uri。

假设有一个名为“路由”的表

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 helper”(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)

注意您的应用程序必须能够在“应用程序/缓存”中写入文件

<?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);
    }

}

然后在 application/config/routes.php 文件中添加一个 require_once(下例中的第 4 行)

<?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,假设是“超级页面,ROCKS!(真的)' 必须路由到“页面”控制器,“索引”函数,参数为“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

于 2014-01-31T16:50:00.953 回答
0
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';
}

使用新版本的 Codeigniterrequire_once( BASEPATH .'database/DB.php'); 代替require_once( BASEPATH .'database/DB'.EXT);

于 2020-04-26T09:24:28.683 回答