views:

208

answers:

5

I am having difficulty with code igniter routing.

http://www.mysite.com goes to the right controller and does the right thing. However, http://www.mysite.com/?ref=p&t2=455 causes a 404 error. Also http://www.mysite.com/mycontroller/mymethod/?ref=p&t2=455 works fine.

I changed the uri_protocol in the config.php file and tried different values. Auto seems to work the best.

My theory is that code igniter is using the query parameters to do the routing. The problem is that these query parameter have nothing to do with routing.

How do I tell code igniter to ignore query parameters for the default controller?

Note, I followed the instructions online to remove the index.php from the URL. I dont think its causing a problem, but here is my .htaccess file just in case:

RewriteEngine On
RewriteBase /~trifecta/prod/

#Removes access to the system folder by users.
#Additionally this will allow you to create a System.php controller,
#previously this would not have been possible.
#'system' can be replaced if you have renamed your system folder.
RewriteCond %{REQUEST_URI} ^system.*
RewriteRule ^(.*)$ /index.php?/$1 [L]
#Checks to see if the user is attempting to access a valid file,
#such as an image or css document, if this isn't true it sends the
#request to index.php
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
#This last condition enables access to the images and css folders, and the robots.txt file
#Submitted by Michael Radlmaier (mradlmaier)
RewriteCond $1 !^(index\.php|images|robots\.txt|css)
RewriteRule ^(.*)$ index.php?/$1 [L]
A: 

It seems to be a limitation in the way CodeIgniter is designed, not as a result of your routing and/or .htaccess. Someone filed a bug report here. However, instead of using this and adding your mymethod code into your index method of your default controller, you could use the _remap() function like so:

function _remap($method)
{
    if ($method == 'index' && count($_GET) > 0)
    {
        $this->mymethod();
    }
    else
    {
        $this->index();
    }
}
stormdrain
ebynum
Also, unless he's doing something particularly special, CI empties out $_GET, so it's always empty.
ebynum
stormdrain
A: 

With the following configuration it works fine for me. http://www.site.com/?x=y gets routed to the index method of the default controller.

.htaccess

RewriteEngine on
RewriteCond $1 !^(index\.php)
RewriteRule ^(.*)$ index.php/$1 [L]

system/application/config/config.php

$config['base_url'] = "http://www.site.com/";
$config['index_page'] = "";
$config['uri_protocol'] = "PATH_INFO";
$config['permitted_uri_chars'] = 'a-z 0-9~%.:_\-?';

Remember to add ? to the list of permitted characters in the URL. Perhaps this is causing a problem. I just tried this setup with a clean installation of CodeIgniter and it worked fine. These were the only changes I needed to do.

Stephen Curran
+3  A: 

With that rewrite rule RewriteRule ^(.*)$ /index.php?/$1, here are some examples of rewrites that are occuring:

http://www.mysite.com =>
http://www.mysite.com/index.php?/ (actually, this might not be being rewritten at all)

http://www.mysite.com/mycontroller/mymethod/?ref=p&t2=455 =>
http://www.mysite.com/index.php?/mycontroller/mymethod/?ref=p&t2=455

http://www.mysite.com/?ref=p&ts=455 =>
http://www.mysite.com/index.php?/?ref=p&t2=455

The first one will work whether it is being rewritten or not. CodeIgniter is processing either an empty query string (which is easy) or a query string of simply "/".

The second one (which also works) is being rewritten, but CodeIgniter is able to process its query string, which is /mycontroller/mymethod/?ref=p&t2=455. CI turns that into an array of segments as

[0] => mycontroller
[1] => mymethod
[2] => ?ref=p&t2=455

Array index 2 ultimately gets ignored by anything you're doing.

The third one (which does not work is being rewritten, and CodeIgniter can't process its query string at all. Its query string is rewritten to: /?ref=p&t2=455. That makes for an array of segments that looks like this:

[0] => ?ref=p&t2=455

which doesn't match any controller on your site.

Probably, you'll fix the whole thing by modifying the RewriteRule from
RewriteRule ^(.*)$ /index.php?/$1 to
RewriteRule ^(.*)$ /index.php/$1
at which point you'd probably want to change the uri_protocol config back to PATH_INFO.

ebynum
I agree completely. That rewrite rule looks a bit funky.
Stephen Curran
There are _some_ occasions where you need to pass everything in a query string, but that's never going to work well with another query string being passed. If the query string is ONLY being used client-side, you can eliminate the original query string in the rewrite by putting a ? at the end of the rewrite string.
ebynum
I had to do two things: change the rewrite rules like you mentioned but also change the uri_protocol to ORIG_PATH_INFO. Doing both solved the problem
Tihom
A: 

Here is how I got around it: 1. I have a standard rewrite in .htaccess:

RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)$ index.php?/$1 [QSA,L]

This is likely unrelated but...

  1. in index.php the file outside the application folder I added:

$pattern = "/\?.*$/"; $replacement = ''; $_SERVER['REQUEST_URI'] =preg_replace($pattern, $replacement, $_SERVER['REQUEST_URI']);

this stops codeigniter from trying to use the querystring in the request. Now did you actually need the $_GET variables? They need to be parsed out of $_SERVER['REDIRECT_QUERY_STRING'] which will be set if you used mod_rewrite as above.

Tsalmark
A: 

Try the CodeIgniter Super .htaccess file

Xeoncross