Database driven routes (no caching, MySQL version)

February 1st, 2011

If you need database driven routes then you may consider this simple solution.

You need to create following table.

1
2
3
4
5
6
7
8
9
10
CREATE TABLE `ci_routes` (
   `id` INT(11) UNSIGNED NOT NULL AUTO_INCREMENT,
   `src` VARCHAR(255) NOT NULL,
   `dest` VARCHAR(255) NOT NULL,
   PRIMARY KEY (`id`,`src`),
   UNIQUE KEY `src` (`src`)
) ENGINE=InnoDB
 
INSERT INTO `routes` (`id`, `src`, `dest`) VALUES(0, 'default_controller', 'welcome');
INSERT INTO `routes` (`id`, `src`, `dest`) VALUES(1, '404_override', '');

And just put MY_Router.php to your /application/core folder.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
<?php
 
class MY_Router extends CI_Router{
 
	var $routes_table	= 'ci_routes'; // mysql routes table name
	var $config;
	var $routes			= array();
	var $error_routes	= array();
	var $class			= '';
	var $method			= 'index';
	var $directory		= '';
	var $default_controller;
 
	function __construct()
	{
		$this->config =& load_class('Config', 'core');
		$this->uri =& load_class('URI', 'core');
		log_message('debug', "Router Class Initialized");
	}
 
	/*
	   CREATE TABLE `routes` (
	   `id` int(11) unsigned NOT NULL AUTO_INCREMENT,
	   `src` varchar(255) NOT NULL,
	   `dest` varchar(255) NOT NULL,
	   PRIMARY KEY (`id`,`src`),
	   UNIQUE KEY `src` (`src`)
	   ) ENGINE=InnoDB
	*/
 
	function get_db_routes()
	{
		//connect to database
		include(APPPATH.'config/database'.EXT);
		$conn = mysql_connect($db['default']['hostname'],$db['default']['username'],$db['default']['password']);
		mysql_select_db($db['default']['database'],$conn);
 
		// get saved routes
		$sql = "SELECT * FROM `{$this->routes_table}`";
		$query = mysql_query($sql);
		mysql_close($conn);
 
		while ($row = mysql_fetch_assoc($query)) {
			$routes[$row['src']] = $row['dest'];
		}
 
		if(count($routes)>0){
			return $routes;
		}
		return FALSE;
	}
 
	function _set_routing()
	{
		$segments = array();
		if ($this->config->item('enable_query_strings') === TRUE AND isset($_GET[$this->config->item('controller_trigger')]))
		{
			if (isset($_GET[$this->config->item('directory_trigger')]))
			{
				$this->set_directory(trim($this->uri->_filter_uri($_GET[$this->config->item('directory_trigger')])));
				$segments[] = $this->fetch_directory();
			}
 
			if (isset($_GET[$this->config->item('controller_trigger')]))
			{
				$this->set_class(trim($this->uri->_filter_uri($_GET[$this->config->item('controller_trigger')])));
				$segments[] = $this->fetch_class();
			}
 
			if (isset($_GET[$this->config->item('function_trigger')]))
			{
				$this->set_method(trim($this->uri->_filter_uri($_GET[$this->config->item('function_trigger')])));
				$segments[] = $this->fetch_method();
			}
		}
 
		// load routes from DB
		$this->routes_db = $this->get_db_routes();
 
		// Load the routes.php file.
		@include(APPPATH.'config/routes'.EXT);
		$this->routes = ( ! isset($route) OR ! is_array($route)) ? array() : $route;
		unset($route);
 
		// what to load first
		if (@$route_override) { // this is setup in
			$this->routes = array_merge($this->routes_db, $this->routes);
		} else {
			$this->routes = array_merge($this->routes, $this->routes_db);
		}
 
		$this->default_controller = ( ! isset($this->routes['default_controller']) OR $this->routes['default_controller'] == '') ? FALSE : strtolower($this->routes['default_controller']);
 
		if (count($segments) > 0)
		{
			return $this->_validate_request($segments);
		}
 
		$this->uri->_fetch_uri_string();
 
		if ($this->uri->uri_string == '')
		{
			return $this->_set_default_controller();
		}
 
		$this->uri->_remove_url_suffix();
		$this->uri->_explode_segments();
		$this->_parse_routes();
		$this->uri->_reindex_segments();
	}
 
}

If you want to have control what is loaded first you need to put this var to /config/route.php

// file route.php WILL OVERRIDE DB routes setting if TRUE
// (db settings will be loaded first)
$route_override = TRUE;

Comments are closed.