Codeigniter: Mixing segment-based URL with querystrings
Codeigniter, by default crafts it’s URL in a search engine friendly format. It uses a segment-based approach and does away with the all familiar querystring format that developers have been using for many years to pass parameters via the URL into their applications.
Codeigniter does allow you to turn on the querystring capability, but that would mean you have to use a pure querystring approach, foregoing the segment-based approached.
So, is it possible to mix segments and querystring?
Thankfully, Codeigniter can be configured to mix the segments and querystring, and all it takes are some tweaks in your application/config.php file and perhaps an additional line of code.
Say you would like to have a URL like so:
example.com/product/search/?pname=test&pid=2
By default, Codeigniter would prefer you to craft the equivalent segmented URL, and it would probably look like this.
example.com/product/search/test/2
One of the limitations of this is that the order of the segments becomes important. In your code, you have to remember that the segment after /search/ is the ‘pname’ variable and the segment after that is the ‘pid’ variable. You won’t have this issue if you used a query string.
In most cases, this is not really a show stopper. But there are times when you have no choice but to include querystrings into your URL. For example, a legacy application that interfaces with your application perhaps?
If you follow the (excellent) Codeigniter user guide, and you turn on the querystring capability , Codeigniter will now function with a URL like this:
example.com/?c=product&m=search&pname=test&pid=2
Which is also not the most ideal.
This is what you can do if you need to have a mixed segment and querystring approach. You can enable this either globally for your whole application or just locally within a controller.
Option 1: Mixing Globally
To enable this globally, go to your application/config.php file, and look for $config['uri_protocol'] variable and change it to:
$config['uri_protocol'] = "PATH_INFO";
After that, find the $config['enable_query_strings'] variable and change it to:
$config['enable_query_strings'] = TRUE;
Your application should now accept both segments and querystrings.
Option 2: Mixing Locally
If you don’t want to enable this capability across your whole application, you can restrict it to only the controllers you want.
You can do this by going to the application/config.php file and switching $config['enable_query_strings'] back to ‘FALSE’.
$config['enable_query_strings'] = FALSE;
Leave the $config['uri_protocol'] as PATH_INFO
$config['uri_protocol'] = "PATH_INFO";
and then you can add this line to your controller’s contructor method:
parse_str($_SERVER['QUERY_STRING'],$_GET);
So if you do a test now, only the controller with the above line of code will be able to accept mixed segment and querystring URLs.
- Parsing a URL querystring into variables in PHP
- Cacti: Ubuntu 8.04 Cacti Plugin – Invalid PHP_SELF Path problem
- Codeigniter: Setting up multiple sites on one install
- Review: Professional Codeigniter
- WebPageTest: The little known but great webpage benchmarking tool.












The local solution won’t work because the globals are sanitized before the controller is loaded.
A very hackish solution without enabling query strings that does work is to use a pre_system hook to catch the GET global values in a constant.
hi david
Thanks for the feedback. but I tested using
$config['uri_protocol'] = “PATH_INFO”;
$config['enable_query_strings'] = FALSE;
and within the controller constructor function
parse_str($_SERVER['QUERY_STRING'],$_GET);
it seems to work for my application. maybe my article wasn’t clear that uri_protocol still needs to be set to PATH_INFO.
Are you putting the parse_str($_SERVER[’QUERY_STRING’],$_GET); line in your config? Your article directions are to put it in the constructor.
I had the uri_protocol set to PATH_INFO when i tested it.
I just became aware since my hackish solution uses a constant why not put it in the constants.php file which is a part of the framework since the 1.6.2 version.
define(’MY_GET’,$_GET);
[...] – Design, Style, & make it work with PHP & Ajax | Noupe (tags: Form tutorial css html) Codeigniter: Mixing segment-based URL with querystrings (tags: PHP CodeIgniter) Anonymous Functions and Closures (tags: PHP programming) jQuery Sequential [...]
[...] Ask About PHP blog has a tutorial offering CodeIgniter users an alternative to the “no normal GET variables allowed” [...]
hi david
the reason why parse_str($_SERVER[’QUERY_STRING’],$_GET); only goes into the constructor, is so that it’s only enabled for that particular controller.
this was just to illustrate how to do a segment/querystring mix that works within a particular controller, and not application-wide.
so this not work ?
I’ve tried this, and it works to an extent.
However, with this setup, I need to use the index.php in the URL, even though I have .htaccess setup to rewrite the URLs.
If I don’t use index.php, I am not directed to the correct controller and just get the welcome screen.
Has anyone else noticed this?
hi jeremy, thanks for the observation. I’ll give it a try and let you know if I get the same outcome.
Hi there.
Just posting to say that this solution worked perfectly in my case. The htaccess problem that jeremy sad isn’t appening to me, so it’s all good here.
Thanks alot for your tutorial.
[...] Codeigniter: Mixing segment-based URL with querystrings | Ask About PHP "So, is it possible to mix segments and querystring?" Sort of, maybe, seems to be the answer. (tags: codeigniter php routing url hack ) [...]
What a waste. Use the URI class’ uri_to_assoc method and then you don’t need to worry about the order of key value params.
Hi Colin, thanks for pointing out the uri_to_assoc method in the URI class. Will check it out.
hi, i don’t know why, but my code work fine in my localhost using both query string and segment, but when i put it at server.. it gives me 404 page