I’ve done some reading about hyphens vs underscores in urls and personally I prefer hyphens. I find it seems to keep the words separate where as a underscores seem to join them together in my eyes.
PHP functions don’t allow hyphens in their name so I have to use underscores.
To solve this in CodeIgniter, so the correct function name is found from the uri segment, only one simple change needs to be made.
In system/libraries/Router.php find line 153 and change this line
$segments = $this->_validate_request($segments);
to
$segments = $this->_validate_request(str_replace(“-“, “_”, $segments));
All we need to do is do a string replacement so hyphens become underscores.
This is a good solution, however it requires modification of the source files.
A better solution is to create a MY_Router.php file in your /application/core directory. In that file you can have the following code:
<?php
public function _set_request($segments){
// Fix only the first 2 segments
for($i = 0; $i
This is a nicer solution, as it doesn’t alter any segments beyond the controller and method, which is generally what people are after.
Hope this helps.
Sorry, the code didn’t post correctly:
public function _set_request($segments){
// Fix only the first 2 segments
for($i = 0; $i < 2; ++$i){
if(isset($segments[$i])){
$segments[$i] = str_replace('-', '_', $segments[$i]);
}
}
// Run the original _set_request method, passing it our updated segments.
parent::_set_request($segments);
}
Hi Jason,
Thanks for your solution.
I like your idea of leaving the core files alone. That would be more helpful if the project involved more than one developer or it was passed onto another developer. They are more liking to look at the MY_Router file than start digging in the core files to look for modifications.
Jason’s method isn’t working, still give me error T_Public.
Hi Routh,
Is the MY_Router file definitely being loaded?
Also are you using the latest version of CodeIgniter?
And finally do you have more of an error message to look at please.
Hi,
Yes, MY_Router file is loaded correctly and I am using version 2.0.3
I tried your method and it works properly, however Jason’s method might work better.
Also I tried solve this problem, read some forums and still get solves like “closing }” or old PHP version below 5 but my version is 5.2.17-0.
I thing there is undefined superior Class and its the reason of my problem.
error:
Parse error: syntax error, unexpected T_PUBLIC in /home/domeny/routh.cz/web/subdomeny/divis/application/core/MY_Router.php on line 2
Thanks for your interest
Hi,
Yes, MY_Router file is loaded correctly and I am using version 2.0.3
I tried your method and it works properly, however Jason’s method might work better.
Also I tried solve this problem, read some forums and still get solves like \"closing }\" or old PHP version below 5 but my version is 5.2.17-0.
I thing there is undefined superior Class and its the reason of my problem.
error:
<code>Parse error: syntax error, unexpected T_PUBLIC in /home/domeny/routh.cz/web/subdomeny/divis/application/core/MY_Router.php on line 2</code>
Thanks for your interest
Oops, sorry for twice reply, but it seems there is a bug in JS or Captcha. It showed me invalid security code, so i refreshed with button and send again… then it showed twice…
Would you like me to post a link to download my MY_Router file?
Yes, there it is…. just copied your code, paste between …
My_Router
The MY_Router.php file needs to contain a class called MY_Router that extends CI_Router
Here is my version. If you download that and replace your MY_Router file I’m sure it will solve your problem.
MY Router file
Yes, it works
Thanks a lot
Hi Ian, i tried he code in your attachment. It doesn’t seems to working for me. I don’t get any errors, but nothing happens. Any reason why?
Hi Nick,
Do you have display errors turned on? If not it would be worth doing that and trying again. This may help show what is going wrong.
Thanks
Ian
Hi Ian
I have turned on error reporting on but it doesn’t show any errors for me.
Have you installed CodeIgniter in a sub directory of your site?
The MY_Router.php file only handles the first three segments as it is.
So if you’re site was like this
http://example.com/codeigniter/controller/function-with-hyphens
The hyphens in the function name would not be converted to underscores.
Hi, Ian, the code worked for me! But in my case the both URLS are accessible:
http://example.com/codeigniter/controller/function-with-hyphens
http://example.com/codeigniter/controller/function_with_hyphens
That may cause duplicated content for Google. How can we show an error page for the second url?
Thanks
Hi Jamie,
Great point. You could use the routes.php file in CodeIgniter or replace the underscores with hyphens in your.htaccess
Thanks
Ian
To prevent underscores in URLs, try this code in your MY_Router class:
// convert underscores to bars to invoke 404
$segments[$i] = str_replace(\’_\’, \’|\’, $segments[$i]);
// convert dashes to underscores
$segments[$i] = str_replace(\’-\’, \’_\’, $segments[$i]);
Hi ian,
I have integrated you file MY_Router.php in my application/core directory it worked for me.
But when I am changing my function name i.e from about_us to about-us it gives the following error.
Parse error: syntax error, unexpected ‘-‘, expecting ‘(‘ in C:\xampp\htdocs\onlinetestb\application\controllers\cli.php on line 951
Please help me out with this problem.
Hi Ratnesh,
PHP does not allow hyphens in function names. This is actually the reason for the MY_Router.php file. It basically replaces the hyphens in the URL with underscores so it correctly maps to the function name in your controller.
Thanks
Ian
Hi Ian,
Thank you very much man for your help.
There is one more thing I am stuck in is that the url is accessible through (_) underscores as well as through (-) dashes.
But how to allow users to access the url only through (-)dashes not through (_) underscores .
Because it will cause a duplicacy in google search engines.
Thanks
Hi Ratnesh,
Gavin in an earlier comment suggested a solution to this.
http://ianluckraft.co.uk/2011/01/codeigniter-allow-hyphen-in-url/comment-page-1/#comment-12368
Thanks
Ian
Thanks Ian for the solution it helped me a lot.
Hi Ian,
I am use you my_router file, it’s work good but if I am change http to https it not work.
Hi Wasim,
That is very strange. So it works fine until you use https?
Thanks
Ian
Hi Ian and the rest of guys,
i’ve tried the solution explained by Gavin about allowing users to access the url only through (-)dashes not through (_) underscores, but without success. I’ve put the Gavin’s lines of code …
// convert underscores to bars to invoke 404
$segments[$i] = str_replace(‘\’_\”, ‘\’|\”, $segments[$i]);
// convert dashes to underscores
$segments[$i] = str_replace(‘\’-\”, ‘\’_\”, $segments[$i]);
… instead of Ian’s original code …
$segments[$i] = str_replace(‘-‘, ‘_’, $segments[$i]);
… but the URLs with “_” are still available to access. What’s wrong with the code??
Thanks everyone in advance for your support!
Because it will cause a duplicacy in google search engines.
Hi Julian,
In system/core/Router.php on line 227 we have
$segments = $this->_validate_request($segments);
We need to replace this line with the following
// Convert undersocres to bars so requests with underscores in the URL will 404
$segments = $this->_validate_request(str_replace('_', '|', $segments));
// Convert hyphens to underscores so requests with hypens in the URL will validate
$segments = $this->_validate_request(str_replace('-', '_', $segments));
Hope that helps you out.
Thanks
Ian
Hi Guys,
I have downloaded and tried the MY_Router.php file. That file worked for me very well but a warning i am receiving i.e as below. Please give me a solution. thanks.
Severity: Runtime Notice
Message: Declaration of MY_Router::_set_request() should be compatible with CI_Router::_set_request($segments = Array)
Filename: core/MY_Router.php
Line Number: 28
Backtrace:
File: C:\wamp\www\futurewebs\index.php
Line: 292
Function: require_once
In your router file under application in CI 3 all you need to do is do this
$route[‘test/red-wine’] =’test/redwine’; Where test is controller and redwine is class
That will work for sure.