Derek Jones | 8ede1a2 | 2011-10-05 13:34:52 -0500 | [diff] [blame] | 1 | ########### |
| 2 | URI Routing |
| 3 | ########### |
| 4 | |
| 5 | Typically there is a one-to-one relationship between a URL string and |
| 6 | its corresponding controller class/method. The segments in a URI |
| 7 | normally follow this pattern:: |
| 8 | |
| 9 | example.com/class/function/id/ |
| 10 | |
| 11 | In some instances, however, you may want to remap this relationship so |
Andrey Andreev | 16a704c | 2012-11-09 17:25:00 +0200 | [diff] [blame] | 12 | that a different class/method can be called instead of the one |
Derek Jones | 8ede1a2 | 2011-10-05 13:34:52 -0500 | [diff] [blame] | 13 | corresponding to the URL. |
| 14 | |
vlakoff | 3567246 | 2013-02-15 01:36:04 +0100 | [diff] [blame] | 15 | For example, let's say you want your URLs to have this prototype:: |
Derek Jones | 8ede1a2 | 2011-10-05 13:34:52 -0500 | [diff] [blame] | 16 | |
Andrey Andreev | 16a704c | 2012-11-09 17:25:00 +0200 | [diff] [blame] | 17 | example.com/product/1/ |
| 18 | example.com/product/2/ |
| 19 | example.com/product/3/ |
| 20 | example.com/product/4/ |
Derek Jones | 8ede1a2 | 2011-10-05 13:34:52 -0500 | [diff] [blame] | 21 | |
Andrey Andreev | 16a704c | 2012-11-09 17:25:00 +0200 | [diff] [blame] | 22 | Normally the second segment of the URL is reserved for the method |
| 23 | name, but in the example above it instead has a product ID. To |
| 24 | overcome this, CodeIgniter allows you to remap the URI handler. |
Derek Jones | 8ede1a2 | 2011-10-05 13:34:52 -0500 | [diff] [blame] | 25 | |
| 26 | Setting your own routing rules |
| 27 | ============================== |
| 28 | |
Andrey Andreev | 16a704c | 2012-11-09 17:25:00 +0200 | [diff] [blame] | 29 | Routing rules are defined in your *application/config/routes.php* file. |
| 30 | In it you'll see an array called ``$route`` that permits you to specify |
| 31 | your own routing criteria. Routes can either be specified using wildcards |
| 32 | or Regular Expressions. |
Derek Jones | 8ede1a2 | 2011-10-05 13:34:52 -0500 | [diff] [blame] | 33 | |
| 34 | Wildcards |
| 35 | ========= |
| 36 | |
| 37 | A typical wildcard route might look something like this:: |
| 38 | |
Andrey Andreev | 16a704c | 2012-11-09 17:25:00 +0200 | [diff] [blame] | 39 | $route['product/:num'] = 'catalog/product_lookup'; |
Derek Jones | 8ede1a2 | 2011-10-05 13:34:52 -0500 | [diff] [blame] | 40 | |
| 41 | In a route, the array key contains the URI to be matched, while the |
| 42 | array value contains the destination it should be re-routed to. In the |
| 43 | above example, if the literal word "product" is found in the first |
| 44 | segment of the URL, and a number is found in the second segment, the |
| 45 | "catalog" class and the "product_lookup" method are instead used. |
| 46 | |
| 47 | You can match literal values or you can use two wildcard types: |
| 48 | |
| 49 | **(:num)** will match a segment containing only numbers. |
Andrey Andreev | 7676c2d | 2012-10-30 13:42:01 +0200 | [diff] [blame] | 50 | **(:any)** will match a segment containing any character (except for '/', which is the segment delimiter). |
| 51 | |
| 52 | .. note:: Wildcards are actually aliases for regular expressions, with |
| 53 | **:any** being translated to **[^/]+** and **:num** to **[0-9]+**, |
| 54 | respectively. |
Derek Jones | 8ede1a2 | 2011-10-05 13:34:52 -0500 | [diff] [blame] | 55 | |
| 56 | .. note:: Routes will run in the order they are defined. Higher routes |
| 57 | will always take precedence over lower ones. |
| 58 | |
Andrey Andreev | a9d98ce | 2012-10-23 10:05:31 +0300 | [diff] [blame] | 59 | .. note:: Route rules are not filters! Setting a rule of e.g. |
| 60 | 'foo/bar/(:num)' will not prevent controller *Foo* and method |
| 61 | *bar* to be called with a non-numeric value if that is a valid |
| 62 | route. |
| 63 | |
Derek Jones | 8ede1a2 | 2011-10-05 13:34:52 -0500 | [diff] [blame] | 64 | Examples |
| 65 | ======== |
| 66 | |
| 67 | Here are a few routing examples:: |
| 68 | |
Andrey Andreev | 16a704c | 2012-11-09 17:25:00 +0200 | [diff] [blame] | 69 | $route['journals'] = 'blogs'; |
Derek Jones | 8ede1a2 | 2011-10-05 13:34:52 -0500 | [diff] [blame] | 70 | |
| 71 | A URL containing the word "journals" in the first segment will be |
| 72 | remapped to the "blogs" class. |
| 73 | |
| 74 | :: |
| 75 | |
Andrey Andreev | 16a704c | 2012-11-09 17:25:00 +0200 | [diff] [blame] | 76 | $route['blog/joe'] = 'blogs/users/34'; |
Derek Jones | 8ede1a2 | 2011-10-05 13:34:52 -0500 | [diff] [blame] | 77 | |
| 78 | A URL containing the segments blog/joe will be remapped to the "blogs" |
| 79 | class and the "users" method. The ID will be set to "34". |
| 80 | |
| 81 | :: |
| 82 | |
Andrey Andreev | 16a704c | 2012-11-09 17:25:00 +0200 | [diff] [blame] | 83 | $route['product/(:any)'] = 'catalog/product_lookup'; |
Derek Jones | 8ede1a2 | 2011-10-05 13:34:52 -0500 | [diff] [blame] | 84 | |
| 85 | A URL with "product" as the first segment, and anything in the second |
| 86 | will be remapped to the "catalog" class and the "product_lookup" |
| 87 | method. |
| 88 | |
| 89 | :: |
| 90 | |
Andrey Andreev | 16a704c | 2012-11-09 17:25:00 +0200 | [diff] [blame] | 91 | $route['product/(:num)'] = 'catalog/product_lookup_by_id/$1'; |
Derek Jones | 8ede1a2 | 2011-10-05 13:34:52 -0500 | [diff] [blame] | 92 | |
| 93 | A URL with "product" as the first segment, and a number in the second |
| 94 | will be remapped to the "catalog" class and the |
| 95 | "product_lookup_by_id" method passing in the match as a variable to |
Andrey Andreev | 16a704c | 2012-11-09 17:25:00 +0200 | [diff] [blame] | 96 | the method. |
Derek Jones | 8ede1a2 | 2011-10-05 13:34:52 -0500 | [diff] [blame] | 97 | |
| 98 | .. important:: Do not use leading/trailing slashes. |
| 99 | |
| 100 | Regular Expressions |
| 101 | =================== |
| 102 | |
| 103 | If you prefer you can use regular expressions to define your routing |
| 104 | rules. Any valid regular expression is allowed, as are back-references. |
| 105 | |
| 106 | .. note:: If you use back-references you must use the dollar syntax |
| 107 | rather than the double backslash syntax. |
| 108 | |
| 109 | A typical RegEx route might look something like this:: |
| 110 | |
Andrey Andreev | 7676c2d | 2012-10-30 13:42:01 +0200 | [diff] [blame] | 111 | $route['products/([a-z]+)/(\d+)'] = '$1/id_$2'; |
Derek Jones | 8ede1a2 | 2011-10-05 13:34:52 -0500 | [diff] [blame] | 112 | |
| 113 | In the above example, a URI similar to products/shirts/123 would instead |
Andrey Andreev | 16a704c | 2012-11-09 17:25:00 +0200 | [diff] [blame] | 114 | call the "shirts" controller class and the "id_123" method. |
Derek Jones | 8ede1a2 | 2011-10-05 13:34:52 -0500 | [diff] [blame] | 115 | |
Andrey Andreev | 7676c2d | 2012-10-30 13:42:01 +0200 | [diff] [blame] | 116 | With regular expressions, you can also catch a segment containing a |
| 117 | forward slash ('/'), which would usually represent the delimiter between |
| 118 | multiple segments. |
| 119 | For example, if a user accesses a password protected area of your web |
| 120 | application and you wish to be able to redirect them back to the same |
| 121 | page after they log in, you may find this example useful:: |
| 122 | |
| 123 | $route['login/(.+)'] = 'auth/login/$1'; |
| 124 | |
Andrey Andreev | 16a704c | 2012-11-09 17:25:00 +0200 | [diff] [blame] | 125 | That will call the "auth" controller class and its ``login()`` method, |
Andrey Andreev | 7676c2d | 2012-10-30 13:42:01 +0200 | [diff] [blame] | 126 | passing everything contained in the URI after *login/* as a parameter. |
| 127 | |
| 128 | For those of you who don't know regular expressions and want to learn |
| 129 | more about them, `regular-expressions.info <http://www.regular-expressions.info/>` |
| 130 | might be a good starting point. |
| 131 | |
vlakoff | 0c1e163 | 2013-01-28 21:24:36 +0100 | [diff] [blame] | 132 | .. note:: You can also mix and match wildcards with regular expressions. |
Derek Jones | 8ede1a2 | 2011-10-05 13:34:52 -0500 | [diff] [blame] | 133 | |
Jonatas Miguel | cf16830 | 2012-08-06 17:10:17 +0100 | [diff] [blame] | 134 | Callbacks |
| 135 | ========= |
| 136 | |
Andrey Andreev | 16a704c | 2012-11-09 17:25:00 +0200 | [diff] [blame] | 137 | If you are using PHP >= 5.3 you can use callbacks in place of the normal |
| 138 | routing rules to process the back-references. Example:: |
Jonatas Miguel | cf16830 | 2012-08-06 17:10:17 +0100 | [diff] [blame] | 139 | |
vlakoff | 0c1e163 | 2013-01-28 21:24:36 +0100 | [diff] [blame] | 140 | $route['products/([a-zA-Z]+)/edit/(\d+)'] = function ($product_type, $id) |
Jonatas Miguel | 8f1cdd1 | 2012-08-30 13:57:54 +0200 | [diff] [blame] | 141 | { |
Andrey Andreev | 16a704c | 2012-11-09 17:25:00 +0200 | [diff] [blame] | 142 | return 'catalog/product_edit/' . strtolower($product_type) . '/' . $id; |
Jonatas Miguel | cf16830 | 2012-08-06 17:10:17 +0100 | [diff] [blame] | 143 | }; |
| 144 | |
Derek Jones | 8ede1a2 | 2011-10-05 13:34:52 -0500 | [diff] [blame] | 145 | Reserved Routes |
| 146 | =============== |
| 147 | |
Andrey Andreev | 08fec7b | 2013-07-19 16:25:51 +0300 | [diff] [blame] | 148 | There are three reserved routes:: |
Derek Jones | 8ede1a2 | 2011-10-05 13:34:52 -0500 | [diff] [blame] | 149 | |
| 150 | $route['default_controller'] = 'welcome'; |
| 151 | |
| 152 | This route indicates which controller class should be loaded if the URI |
| 153 | contains no data, which will be the case when people load your root URL. |
| 154 | In the above example, the "welcome" class would be loaded. You are |
| 155 | encouraged to always have a default route otherwise a 404 page will |
| 156 | appear by default. |
| 157 | |
| 158 | :: |
| 159 | |
| 160 | $route['404_override'] = ''; |
| 161 | |
| 162 | This route indicates which controller class should be loaded if the |
| 163 | requested controller is not found. It will override the default 404 |
Andrey Andreev | 16a704c | 2012-11-09 17:25:00 +0200 | [diff] [blame] | 164 | error page. It won't affect to the ``show_404()`` function, which will |
Andrey Andreev | d1097a1 | 2012-11-01 19:55:42 +0200 | [diff] [blame] | 165 | continue loading the default *error_404.php* file at |
vlakoff | 52301c7 | 2013-03-29 14:23:34 +0100 | [diff] [blame] | 166 | *application/views/errors/error_404.php*. |
Derek Jones | 8ede1a2 | 2011-10-05 13:34:52 -0500 | [diff] [blame] | 167 | |
Andrey Andreev | 08fec7b | 2013-07-19 16:25:51 +0300 | [diff] [blame] | 168 | |
| 169 | :: |
| 170 | |
| 171 | $route['translate_uri_dashes'] = FALSE; |
| 172 | |
| 173 | As evident by the boolean value, this is not exactly a route. This |
| 174 | option enables you to automatically replace dashes ('-') with |
| 175 | underscores in the controller and method URI segments, thus saving you |
| 176 | additional route entries if you need to do that. |
| 177 | This is required, because the dash isn't a valid class or method name |
| 178 | character and would cause a fatal error if you try to use it. |
| 179 | |
Derek Jones | 8ede1a2 | 2011-10-05 13:34:52 -0500 | [diff] [blame] | 180 | .. important:: The reserved routes must come before any wildcard or |
Andrey Andreev | d1097a1 | 2012-11-01 19:55:42 +0200 | [diff] [blame] | 181 | regular expression routes. |