40

I'm creating an e-commerce site using CodeIgniter.

How should I get the query string?

I am using a Saferpay payment gateway. The gateway response will be like this:

http://www.test.com/registration/success/?DATA=<IDP+MSGTYPE%3D"PayConfirm"+KEYID%3D"1-0"+ID%3D"KI2WSWAn5UG3vAQv80AdAbpplvnb"+TOKEN%3D"(unused)"+VTVERIFY%3D"(obsolete)"+IP%3D" 123.25.37.43"+IPCOUNTRY%3D"IN"+AMOUNT%3D"832200"+CURRENCY%3D"CHF"+PROVIDERID%3D"90"+PROVIDERNAME%3D"Saferpay+Test+Card"+ACCOUNTID%3D"99867-94913159"+ECI%3D"2"+CCCOUNTRY%3D"XX"%2F>&SIGNATURE=bc8e253e2a8c9ee0271fc45daca05eecc43139be6e7d486f0d6f68a356865457a3afad86102a4d49cf2f6a33a8fc6513812e9bff23371432feace0580f55046c

To handle the response I need to get the query string data.


Sorry, I haven't explained the problem clearly. I am getting a 'Page not found' error while getting the response from the payment site after payment.

I have tried enabling with uri_protocol = 'PATH_INFO' and enable_query_strings = 'TRUE' in config.php. While googling I found this won't work if I use htaccess rewrite.

I have already tried changing the config entries, but it doesn't work.

Michael Myers
  • 188,989
  • 46
  • 291
  • 292
Siva
  • 401
  • 1
  • 4
  • 3

12 Answers12

66

You can get it like this:

$this->input->get('some_variable', TRUE);

See this for more info.

Sarfraz
  • 377,238
  • 77
  • 533
  • 578
23

I have been using CodeIgniter for over a year now. For the most part I really like it (I contribute to the forum and use it in every instance that I can) but I HATE the ARROGANCE of that statement in the manual:

Destroys the global GET array. Since CodeIgniter does not utilize GET strings, there is no reason to allow it.

The presumption that you will never need GET in a CodeIgniter application is asinine! Already in just a few days, I've had to deal with post back pages from PayPal and ClickBank (I'm sure there are a million others.) Guess what, they use GET!!!

There are ways to stop this GET squashing, but they are things that tend to screw other things up. What you don't want to hear is that you have to recode all your views because you enabled querystrings and now your links are broken! Read the manual carefully on that option!

One that I like (but didn't work because setting REQUEST_URI in config.php broke my site) is extending the Input class:

class MY_Input extends CI_Input
{
        function _sanitize_globals()
        {
            $this->allow_get_array = TRUE;
            parent::_sanitize_globals();
        }
}

But the best no-nonsense way is to test with print_r($_SERVER) at the URL where you need the GET variables. See which URI Protocol option shows your GET variables and use it.

In my case, I can see what I need in REQUEST_URI

// defeat stupid CI GET squashing!
parse_str($_SERVER['REQUEST_URI'], $_GET);

This places your query string back into the $_GET super global for that page instance (You don't have to use $_GET, it can be any variable.)

EDIT

Since posting this I found that when using REQUEST_URI, you will lose your first query string array key unless you remove everything before the ?. For example, a URL like /controller/method?one=1&two=2 will populate the $_GET array in this example with array('method?one'=>1,'two'=>2). To get around this, I used the following code:

parse_str(substr(strrchr($_SERVER['REQUEST_URI'], "?"), 1), $_GET);

I suppose I should have provided an example, so here goes:

class Pgate extends Controller {
   function postback() {
      parse_str(substr(strrchr($_SERVER['REQUEST_URI'], "?"), 1), $_GET);
      $receipt = $this->input->xss_clean($_GET['receipt']);
   }
}
Bretticus
  • 896
  • 6
  • 11
18

If you want the unparsed query string:

$this->input->server('QUERY_STRING');
Marc Trudel
  • 1,244
  • 1
  • 12
  • 19
6
// 98% functional
parse_str($_SERVER['REQUEST_URI'], $_GET);

This in fact is the best way to handle the lack of support for $_GET query strings in CodeIgniter. I actually came up with this one on my own myself, but soon realized the same thing Bretticus did in that you had to slightly modify the way you treated the first variable:

// 100% functional    
parse_str(substr(strrchr($_SERVER['REQUEST_URI'], "?"), 1), $_GET);

It was only going to be a matter of time before I got to it myself, but using this method is a better one-line solution to everything else out there, including modifying the existing URI library, is isolated to only the controller where it is applicable, and eliminates having to make any changes to the default configuration (config.php)

$config['uri_protocol'] = "AUTO";
$config['enable_query_strings'] = FALSE;

With this, you now have the following at your disposal:

/controller/method?field=value
/controller/method/?field=value

Verify the results:

print_r($_GET); // Array ( [field] => value ) 
Matt Borja
  • 61
  • 1
  • 1
5

Open up application/config/config.php and set the following values:

$config['uri_protocol'] = "PATH_INFO";

$config['enable_query_strings'] = TRUE; 

Now query strings should work fine.

Phil Sturgeon
  • 30,637
  • 12
  • 78
  • 117
2

If you're using mod_rewrite to remove the index.php file, you can use the following code to obtain the GET variables (via $this->input->get()). Assuming the default configuration, name the file MY_Input.php and place it in your application/libraries directory.

Usage: $this->input->get()

class MY_Input extends CI_Input {

    function My_Input()
    {
        parent::CI_Input();

        // allow GET variables if using mod_rewrite to remove index.php
        $CFG =& load_class('Config');
        if ($CFG->item('index_page') === "" && $this->allow_get_array === FALSE)
        {
            $_GET = $this->_get_array();
        }

    }

    /**
     * Fetch an item from the GET array
     * 
     * @param string $index
     * @param bool   $xss_clean
     */
    function get($index = FALSE, $xss_clean = FALSE)
    {
        // get value for supplied key
        if ($index != FALSE)
        {
            if (array_key_exists(strval($index), $_GET))
            {
                // apply xss filtering to value
                return ($xss_clean == TRUE) ? $this->xss_clean($_GET[$index]) : $_GET[$index];
            }
        }
        return FALSE;
    }

    /**
     * Helper function
     * Returns GET array by parsing REQUEST_URI
     * 
     * @return array
     */
    function _get_array()
    {           
        // retrieve request uri
        $request_uri = $this->server('REQUEST_URI');

        // find query string separator (?)
        $separator = strpos($request_uri, '?');
        if ($separator === FALSE)
        {
            return FALSE;
        }

        // extract query string from request uri
        $query_string = substr($request_uri, $separator + 1);

        // parse query string and store variables in array
        $get = array();
        parse_str($query_string, $get);

        // apply xss filtering according to config setting
        if ($this->use_xss_clean === TRUE)
        {
            $get = $this->xss_clean($get);
        }

        // return GET array, FALSE if empty
        return (!empty($get)) ? $get : FALSE;
    }


}
Stradivariuz
  • 2,523
  • 1
  • 18
  • 6
1

Here's a full working example of how to allow querystrings in Codeignitor, like on JROX platform. Simply add this to your config.php file located at:

/system/application/config/config.php 

And then you can simply get the querystrings like normal using $_GET or the class below

$yo = $this->input->get('some_querystring', TRUE);
$yo = $_GET['some_querystring'];

Here's the code to make it all work:

/*
|--------------------------------------------------------------------------
| Enable Full Query Strings (allow querstrings) USE ALL CODES BELOW
|--------------------------------------------------------------------------*/

/*
|----------------------------------------------------------------------
| URI PROTOCOL
|----------------------------------------------------------------------
|
| This item determines which server global should 
| be used to retrieve the URI string.  The default 
| setting of 'AUTO' works for most servers.
| If your links do not seem to work, try one of 
| the other delicious flavors:
|
| 'AUTO'              Default - auto detects
| 'PATH_INFO'         Uses the PATH_INFO
| 'QUERY_STRING'      Uses the QUERY_STRING
| 'REQUEST_URI'   Uses the REQUEST_URI
| 'ORIG_PATH_INFO'    Uses the ORIG_PATH_INFO
|
*/
if (empty($_SERVER['PATH_INFO'])) {
    $pathInfo = $_SERVER['REQUEST_URI'];
    $index = strpos($pathInfo, '?');
    if ($index !== false) {
        $pathInfo = substr($pathInfo, 0, $index);
    }
    $_SERVER['PATH_INFO'] = $pathInfo;
}

$config['uri_protocol'] = 'PATH_INFO'; // allow all characters 

$config['permitted_uri_chars'] = ''; // allow all characters 

$config['enable_query_strings'] = TRUE; // allow all characters 

parse_str(substr(strrchr($_SERVER['REQUEST_URI'], "?"), 1), $_GET);

Enjoy :-)

Rob Vanders
  • 505
  • 1
  • 5
  • 13
1

Thanks to all other posters. This is what hit the spot for me:

    $qs = $_SERVER['QUERY_STRING'];
    $ru = $_SERVER['REQUEST_URI'];
    $pp = substr($ru, strlen($qs)+1);
    parse_str($pp, $_GET);

    echo "<pre>";
    print_r($_GET);
    echo "</pre>";

Meaning, I could now do:

$token = $_GET['token'];

In the .htaccess i had to change:

RewriteRule ^(.*)$ /index.php/$1 [L]

to:

RewriteRule ^(.*)$ /index.php?/$1 [L]
Kinjal Dixit
  • 7,777
  • 2
  • 59
  • 68
1

Set your config file

$config['index_page'] = '';
$config['uri_protocol'] = 'AUTO';
$config['allow_get_array']      = TRUE;
$config['enable_query_strings'] = FALSE;

and .htaccess file (root folder)

<IfModule mod_rewrite.c>
    Options +FollowSymLinks
    Options -Indexes
    RewriteEngine On
    RewriteBase /

    RewriteCond %{REQUEST_FILENAME} !-f
    RewriteCond %{REQUEST_FILENAME} !-d

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


</IfModule>

Now you can use

http://example.com/controller/method/param1/param2/?par1=1&par2=2&par3=x
http://example.com/controller/test/hi/demo/?par1=1&par2=2&par3=X

server side:

public function test($param1,$param2)
{
    var_dump($param1); // hi
    var_dump($param2); // demo
    var_dump($this->input->get('par1')); // 1
    var_dump($this->input->get('par2')); // 2
    var_dump($this->input->get('par3')); // X
}
AldoZumaran
  • 547
  • 5
  • 23
0

You could make a rule in your .htaccess to prevent your MOD_REWRITE from firing on that specific page. That should allow you to use the _GET.

netricate
  • 1,708
  • 2
  • 12
  • 13
0

You can create a pre_system hook. In the hook class you create, you can grab the desired query params and add them to the $_POST for normal CI processing. I did this for a jQuery Ajax helper.

For instance:

(Name this file autocomplete.php or whatever you put as the file name in the hook)

<?php

/*
By Brodie Hodges, Oct. 22, 2009.
*/

if (!defined('BASEPATH')) exit('No direct script access allowed');
/**
*   Make sure this file is placed in your application/hooks/ folder.
*
*   jQuery autocomplete plugin uses query string.  Autocomplete class slightly modified from excellent blog post here:
*   http://czetsuya-tech.blogspot.com/2009/08/allowing-url-query-string-in.html 
*   Ajax autocomplete requires a pre_system hook to function correctly.  Add to your 
*   application/config/hooks.php if not already there:

    $hook['pre_system'][] = array(
        'class'    => 'Autocomplete',
                'function' => 'override_get',
                                'filename' => 'autocomplete.php',
                                'filepath' => 'hooks',
                                'params'   => array()
                                );

*                               
* 
*/

class Autocomplete {
    function override_get() {
        if (strlen($_SERVER['QUERY_STRING']) > 0) {
            $temp = @array();
            parse_str($_SERVER['QUERY_STRING'], $temp);
            if (array_key_exists('q', $temp) && array_key_exists('limit', $temp) && array_key_exists('timestamp', $temp)) {
                $_POST['q'] = $temp['q'];
                $_POST['limit'] = $temp['limit'];
                $_POST['timestamp'] = $temp['timestamp'];
                $_SERVER['QUERY_STRING'] = "";
                $_SERVER['REDIRECT_QUERY_STRING'] = "";
                $_GET = @array();
                $url = strpos($_SERVER['REQUEST_URI'], '?');
                if ($url > -1) {
                    $_SERVER['REQUEST_URI'] = substr($_SERVER['REQUEST_URI'], 0, $url);
                }
            }
        }
    }
}

?>
Josh Lee
  • 171,072
  • 38
  • 269
  • 275
0

Here is how i did it recently. Hope it helps

<?php 
//adapt this code for your own use
                //added example.com to satisfy parse_url
        $url="http://www.example.com".$_SERVER["REQUEST_URI"];
        $url=parse_url($url);
                //I'm expecting variables so if they aren't there send them to the homepage
        if (!array_key_exists('query',$url))
        {
             redirect('/'); exit;
        }
        $query=$url['query'];

        parse_str($query,$_GET); //add to $_GET global array

        var_dump($_GET);
?>

to call : http://www.mydomain.com/mycontroller/myfunction/?somestuff=x&morestuff=y

Josh Lee
  • 171,072
  • 38
  • 269
  • 275
ladieu
  • 127
  • 5
  • 17