CodeIgniter allow hyphen in url

CodeIgniter

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 entry was posted in Web Development and tagged . Bookmark the permalink.

30 Responses to CodeIgniter allow hyphen in url

  1. Jason says:

    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.

  2. Jason says:

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

  3. ian says:

    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.

  4. Routh says:

    Jason’s method isn’t working, still give me error T_Public.

  5. ian says:

    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.

  6. Routh says:

    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

  7. Routh says:

    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

  8. Routh says:

    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…

  9. ian says:

    Would you like me to post a link to download my MY_Router file?

  10. Routh says:

    Yes, there it is…. just copied your code, paste between …

    My_Router

  11. ian says:

    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

  12. Routh says:

    Yes, it works
    Thanks a lot

  13. Nick says:

    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?

  14. ian says:

    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

  15. Nick says:

    Hi Ian

    I have turned on error reporting on but it doesn’t show any errors for me.

  16. ian says:

    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.

  17. Jaime says:

    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

  18. ian says:

    Hi Jamie,

    Great point. You could use the routes.php file in CodeIgniter or replace the underscores with hyphens in your.htaccess

    Thanks

    Ian

  19. Gavin says:

    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]);

  20. Ratnesh says:

    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.

  21. ian says:

    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

  22. Ratnesh says:

    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

  23. ian says:

    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

  24. Ratnesh says:

    Thanks Ian for the solution it helped me a lot.

  25. Wasim says:

    Hi Ian,

    I am use you my_router file, it’s work good but if I am change http to https it not work.

  26. ian says:

    Hi Wasim,

    That is very strange. So it works fine until you use https?

    Thanks

    Ian

  27. Julian says:

    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.

  28. ian says:

    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

  29. Mann says:

    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

  30. 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.

Leave a Reply

Your email address will not be published. Required fields are marked *