Part of the EllisLab Network
   
2 of 2
2
Support for $_GET
Posted: 14 August 2007 05:37 PM   [ Ignore ]   [ # 16 ]  
Summer Student
Total Posts:  1
Joined  08-14-2007

Hi all. I downloaded CodeIgniter yesterday for a trial and, after a three or four hours of use, I have already come across this $_GET issue. First of all, many thanks to Al James for his solution, which seems to work well for me after a quick check.

I would like to try to throw some light on why some of us feel it an important feature to add or, rather, never to have been removed. My opinion, in short, is that clean URLs are desiderable in every web app, but they have a limit.

I think the perfect example to illustrate my point is a search engine. Say you have a form where you can enter a series of arguments and, after clicking “Search”, you will be shown a series of results. For usability’s sake, it’s expected that this search can be reproduced by just copying&pasting;the results’ URL to another browser.

In the web apps world, there are two ways of doing this: the one used by this forum, and the one I prefer smile

The first way is: make a POST request with the arguments, and then redirect to a page where these are somewhat encoded into the clean URL. In the case of searches within this specific forum, it seems a sort of hash is generated, linked to the search arguments, stored both on the DB, and then inserted as a URL segment. This URL with the hash on it can be later used again… or not, because I just realised I cannot use it on a different browser. I guess it’s stored on the session variable instead of the DB, but let’s assume it works and can be reused, as it’s fixable thing. The URL will look something like:

http://codeigniter.com/forums/search_results/9a708abce50301c47e3212cbea9b13d1/

The second way is: use a GET request. (<form action="search" method="get">). In this case, the URL would (hypothetically) look something like:

http://codeigniter.com/forums/do_search/?XID=07662a5ac1dd86bff27997d1a6e554c0c5f44ef7&board_id=2&site_id=3&keywords=get&search_in=all&search_criteria=all&forum;_id&#x5B;&#x5D;=all&member;_name=&member;_group&#x5B;&#x5D;=all&date=30&date_order=newer&order_by=date&sort_order=desc

In the first approach:

- The process to execute the search is a bit more complex (involves a redirection and, in the case of the specific example above, storing the parameters along with the hash on the DB).
- The URL is not really that clean, as the hash has no semantic value.
- The redirection puts the results one request farther. This is undesiderable both in terms of user time and bandwidth use.

In the second approach:

- The URL is very long and ugly.
- The URL is self-explanatory, for both users and machines.
- The URL is a natural permalink.
- The results are only one request away.

In my opinion, the advantages of the second option overcome the drawback of the ugly URL for this specific case.

Additionally, on the documentation, security is named as a reason for this obliteration of the GET parameters. This strikes me as a weak reason, as POST parameters may be forged the same was GET parameters are. Not as easily as GET parameters, sure, but still, assuming that ones are safer than others sounds to me like a false sensation of security. I think GET arguments should be treated as equals of POST arguments, and be given a similar function to access them.

I hope I have been clear. Please excuse my imperfect English, and thanks for reading this far! wink

Profile
 
 
Posted: 16 August 2007 11:38 AM   [ Ignore ]   [ # 17 ]  
Summer Student
Avatar
Total Posts:  9
Joined  09-15-2006
Al James - 14 July 2007 03:11 PM

I have recently added $_GET support to my CI project. (..) That works for me anyway. Does it work for you?

Al James, Thank you very much, your tip is a life saver!

Profile
 
 
Posted: 16 August 2007 11:53 AM   [ Ignore ]   [ # 18 ]  
Summer Student
Avatar
Total Posts:  9
Joined  09-15-2006
Al James - 14 July 2007 03:11 PM

I have recently added $_GET support to my CI project. (..) That works for me anyway. Does it work for you?

There is even more interesting trick.

I have a My_Controller class which extends Controller and which is a mother of all my Controller classes.

In this class I have the following code:

class My_Controller extends Controller {

   
var $get_vars;
   var
$url_level = 3;

   function
My_Controller()
    
{
        parent
::Controller();
    
        
# Get GET vars
        
$this->get_vars = $this->uri->ruri_to_assoc($this->url_level);
    
}
}

Everywhere in my controller I have access to $this->get_vars, which contain every variable that is used within segments. For instance, if I have URL /main/index/page/1, I can fetch the page variable by

$this->get_vars['page']

Now, with Al James code you can also have access to query string type of variables, which you get by

$this->input->get('session_id')

Now, if you have URL /main/index/page/1/?session_id=wh2at3ver, you have have your page variable by

$this->get_vars['page']

and session_id variable by

$this->input->get('session_id')

Even more interesting, if you have URL /main/index/page/1/?page=2 - these both page variables are separated, since

echo "{$this->get_vars['page']} {$this->input->get('page')}";

will output “1 2”

Thus, you can have static variables “engraved” as segmented variables and session or any other variable which have no permanent value van be placed as ? vars.

Hope this helps.

Profile
 
 
Posted: 19 August 2007 12:26 PM   [ Ignore ]   [ # 19 ]  
Summer Student
Avatar
Total Posts:  12
Joined  08-14-2007

Hi,

I’ve just recently started with CI in the last week, and have been having fun browsing around the code and getting a feel for it. This $_GET ‘issue’ got me, too. I like the ‘friendly’ URLs, and am using them in a refactoring of a site I maintain. Now, the old site used query strings to direct people to the right pages (it was almost MVC, completely by accident as I’d never even heard of it before!) and so naturally, old links to the site won’t work anymore.

So, after browsing the forums and reading the user guide, I thought a pre_system hook with a redirect was probably the way to go. And it works! I have a small hook that simply tests for the presence of a $_GET query string, checks to see if it follows the ‘old’ link style, and then rewrites it into the equivalent URI segments for my CI version (well, only for ‘view’ actions, it ignores everything else like ‘postcomment’ etc).

I couldn’t believe how easy it was. I love this framework!

Following is my code, which is probably lame since I’m not a professional coder. I’d appreciate it if you guys could tell me if there are any concerns with my approach, or if my code is terrible or anything. I’m willing to accept any criticism!

function check_get()
{
    
if (isset($_GET['page']))
    
{
        $g_page
= $_GET['page'];

        if (isset(
$_GET['id']))
        
{
            $g_id
= '/view/' . $_GET['id'];
        
}
        
else
        
{
            $g_id
= '';
        
}

        $location
= 'http://localhost/hw2_ci/' . $g_page . $g_id;

        
header('Location: ' . $location);
        exit;
    
}
}

Now this approach might be (read: probably is) terrible, but couldn’t some of the other people who are having troubles with this use a similar method? I mean, couldn’t you take $_GET data, retrieved with the hook, cleanse it of impurities, and store it in a global variable or something? Please enlighten me if this is bad practice, I’m eager to learn as much as I can about secure/robust/professional coding style/techinques.

Many thanks in advance, and keep up the great community!

- Nillian

EDITED: Copy/pasted code that didn’t work. Should’ve checked I was copying from the right file!

 Signature 

Nillian - Newbie CI coder

Profile
 
 
Posted: 20 August 2008 10:03 PM   [ Ignore ]   [ # 20 ]  
Summer Student
Total Posts:  4
Joined  05-07-2008

Thanks Al James for the tip, but I recently have trouble using it with the config[’uri_protocol’] = “PATH_INFO”. I change it to “ORIG_PATH_INFO” out of curiosity and it works! :D Hope this helps if someone else are having the same problem.

Profile
 
 
Posted: 20 August 2008 11:59 PM   [ Ignore ]   [ # 21 ]  
Research Assistant
Avatar
RankRankRank
Total Posts:  870
Joined  07-27-2006

Here’s a simple solution that works only if you don’t have an existing script that extensively tries to access $_GET directly. In your front controller, typically index.php, do this:

if (count($_GET))
{
   
foreach ($_GET as $k => $v)
   
{
      $_POST[
'_get_'. $k] = $v;
   
}
}

Then access the get vars with:

$this->input->post('_get_query');

 Signature 

Check out the Template Library

Profile
 
 
   
2 of 2
2
 
Post Marker Legend
New Topic New posts Hot Topic Hot Topic with new posts New Poll New Poll Moved Topic Moved Topic Sticky Topic Sticky topic
Old Topic No new posts Hot Old Topic Hot Topic with no new posts Old Poll Old Poll Closed Topic Closed Topic Announcement Announcements
Theme
Change Theme
Visitor Statistics
The most visitors ever was 719, on June 06, 2008 10:16 AM
Total Registered Members: 61048 Total Logged-in Users: 17
Total Topics: 73851 Total Anonymous Users: 0
Total Replies: 398361 Total Guests: 324
Total Posts: 472212    
Members ( View Memberlist )