Welcome Guest, Not a member yet? Register   Sign In
Wildcards :num and :any not working in my routes
#1

[eluser]Unknown[/eluser]
I'm having a problem with wildcards in routes. The routing works, if I don't use wildcards or regular expressions.

Code:
$route['item/:num'] = "item/index";

Doesn't work (results in CI 404), while

Code:
$route['item/test'] = "item/index";

does work.

I thought maybe it is because of conflicting .htaccess rules, but with a disabled .htaccess it still doesn't work. Any ideas?
#2

[eluser]BravoAlpha[/eluser]
[quote author="Caspar Chiquet" date="1186852254"]
Code:
$route['item/:num'] = "item/index";
[/quote]
I use this:
Code:
$route['([a-z]+)/([0-9]+)'] = "$1/index/$2";
#3

[eluser]Unknown[/eluser]
Doesn't work either, unfortunately. Strange... I'll have to look at the redirect function I guess. Thanks anyway.
#4

[eluser]dwdaniell[/eluser]
I'm having this same problem - I want to have a URI that looks like this...
Code:
/example/value
... get mapped to my controller class Example, method call as lookup(value) - i.e. call the lookup method on my controller named "Example", passing it the argument "value".

I wrote my routing rule as:
Code:
$route['example/:any'] = "example/lookup";
... and that didn't work. But that's how it says to do it in the documentation... I tried a few other variations and they didn't work either. Any suggestions?
#5

[eluser]dwdaniell[/eluser]
However, when I setup the route like this:
Code:
$route['example/(:any)'] = "example/lookup/$1";
it works just fine. An error in the documentation?
#6

[eluser]BravoAlpha[/eluser]
[quote author="dwdaniell"] wrote my routing rule as:
Code:
$route['example/:any'] = "example/lookup";
... and that didn’t work. [/quote]
I don't think `:any`gets passed to `lookup` with this setup (you use regular expressions for that).
#7

[eluser]_yuri_[/eluser]
Hi,
i had the same problem with routing rules, then i looked in Router.php.
The solution is very simple: you must always insert your rules AFTER the default rules

Code:
$route['default_controller'] = "";
$route['scaffolding_trigger'] = "";

not BEFORE these.
I hope, the next version of Codeigniter is a bit more flexible Smile
#8

[eluser]eggshape[/eluser]
If you write your regexp like this:

Code:
$route['item/:num'] = "item/index";
$route['example/:any'] = "example/lookup";

:num and :any will not be passed as parameters into your methods. First, :num and :any are CI's shorthand for [0-9] and (.+), which are regexp phrases that mean 'match digits' and 'match anything 1 or more'. :num and :any are replaced with their respective regexp phrases in the Route class. After replacement, CI does a preg_replace, **replacing** 'item/[0-9]' with 'item/index' in the uri string (as it is written).

So that is probably why you need to write it like this to pass as parameters:
Code:
$route['item/(:num)'] = "item/index/$1";
$route['example/(:any)'] = "example/lookup/$1";

Which is why bravoalpha's and dwdaniell's version works. When you use parentheses, you are capturing and saving everything in the parentheses. The $1 represents everything between the first set of parentheses. If you had 2 sets of (), the second one is saved as $2, and so on.

Think of it like you're inserting 'index' and 'lookup' between your original uri.

I don't think it matters where you define $route['default_controller'] and $route['scaffolding_trigger']. First $route is an associative array so there's really no order, and the default controller is used in case everything else fails.

Hope this helps.

Edit: I should add, that if the preg_replace doesn't work, then the original url is used. If that leads to nowhere you will get a 404.
#9

[eluser]_yuri_[/eluser]
[quote author="eggshape" date="1200036128"]
I don't think it matters where you define $route['default_controller'] and $route['scaffolding_trigger']. First $route is an associative array so there's really no order, and the default controller is used in case everything else fails.
[/quote]
No, it is. Look at this code in the _parse_routes function of Router.php:

Code:
// Loop through the route array looking for wild-cards
        foreach (array_slice($this->routes, 1) as $key => $val)
        {                        
...

array_slice($this->routes, 1) means that it skips the first element in the $route array. Because $route['default_controller'] is already unset (see _set_route_mapping()) to this moment, it means that the skipped element is
a) $route['scaffolding_trigger'] if you define your rules after that
b) your first rule, if you define your rules before $route['scaffolding_trigger'].

I wonder, why do not use unset($route['scaffolding_trigger']) to avoid the $route['scaffolding_trigger']) is processed as rule ? I hope the next version fix this.
#10

[eluser]eggshape[/eluser]
Hi _yuri_,

You're right about that array_slice. I noticed too that when the Route class is instantiated, the _set_route_mapping() function is called. In this function the $route['default_controller'] is unset after $route['default_controller'] is assigned to $this->class.

I know unset does not pop/shift the array, so the indexes would remain the same. So you're probably right that any additional routes needs to assigned after the two default ones.

Edit: why is array_slice() even used?




Theme © iAndrew 2016 - Forum software by © MyBB