Welcome Guest, Not a member yet? Register   Sign In
A Case for _GET variables
#1

[eluser]octover[/eluser]
I got into a discussion with Derek Jones about a case for GET variables on Twitter. Though the format was limiting, and Derek suggested taking it to the forum.

Here is my case for when I think they are the perfect fit, when searching on more than one parameter. I agree that if I was only searching based on one variable the URI segments would work beautifully and look good. However I have a search form that is basically filtering a list, this particular site is cars, but it works equally well for houses, etc. I don't want to write a natural language parser to figure out 4 bedrooms when I could just have a select box with the options I think work best. The users filter the list down based on criteria they know how they want it and then can browse the results. Using GET variables one, two, or all of the criteria variables can be set or not. I can make a link somewhere else on the site that quickly brings up all the Audi cars easily (without having to have the link become a form submit). Search results can be bookmarked or emailed allowing users to share results.

The problems I've encountered are even if I make so I have all the potential URI segments they won't always work right when parameters are valid as blank. I.e.
Code:
function search($make = '', $model = '') {
  echo $make . "::" . $model;
}

if the URI is /browse/search//Jetta the above will output "Jetta::" the // is skipped or whatever and gets set to the first URI segment variable. Derek suggested an option of /search:me/for:this/ However to me that is merely recreating the wheel or in this case _GET variables while maybe being marginally prettier URIs it is no more secure, and in fact potentially opens you up to security problems since you are now left to implement the details of parsing things yourself.

I get a lot of the reasoning behind CI's destroying the _GET variables, and I think it's good for a lot of people that would use them carelessly, but maybe this is a good case to look at being able to handle better.

I am of course open to suggestions on how to handle this problem, maybe there is an elegant way to handle this already. Basically I have four (though I guess the specific number isn't important, it could be more) fields in my table that I want to filter a query by. Ordinarily I'd check if the _GET variable was set and not blank and then clean the data against SQL injection and the like attacks and use it in my query's where clause.
#2

[eluser]Michael Wales[/eluser]
Are you sure your code doesn't echo '::Jetta' - my thinking is the double-slash is causing a blank $make variable and Jetta is being assigned to $model.

Try this:
Code:
function search($dead_var, $make = '', $model = '') {
  echo $make, '::', $model;
}

or make a custom route and you can eliminate your $dead_var:
Code:
$route['browse/search//([a-zA-Z]+)/([a-zA-Z]+)'] = 'browse/search/$1/$2';
[/code]

Also, and I may be wrong on this completely I never use $_GET variables - but I believe you can turn them on in the config and still use pretty URLs, for a URL like this:
example.com/browse/search?make=Jetta
#3

[eluser]Pascal Kriete[/eluser]
As Michael mentioned, it can be done by setting enable_query_strings to true and then using PATH_INFO or REQUEST_URI for the uri_protocol.

I'm not a fan of them as it tends to blow up the url (most car sites have absolutely unusable urls). To me, this looks like a perfect case for uri->uri_to_assoc:
Code:
function search()
{
    $params = $this->uri->uri_to_assoc(3, array('make', 'model'));
}
#4

[eluser]TheFuzzy0ne[/eluser]
I'm wondering if my [url="http://ellislab.com/forums/viewthread/106502/"]Alternate URI Syntax helper[/url] would help you at all?
#5

[eluser]Colin Williams[/eluser]
But why introduce anything new, FuzzyOne? CI can handle $_GET by changing 2 config settings, but it prefers that you stick to URI segments.
#6

[eluser]octover[/eluser]
It definitely skips setting the first variable to blank and instead sets it to the first segment with something in it. It's easy to see by adding a method to a controller like so. Then going to /controller/test//blah/

Code:
function test($var1 = "", $var2 = "", $var3 = "") {
  echo $var1 . "::" . $var2 . "::" .$var3;
}

I am using version 1.7.1 of the framework. I agree urls get unruly fast, but for me and the client it's important that there be an easy way to see for instance all the Audi vehicles in stock via a link. I was unaware of the uri_to_assoc but given that a blank uri segment is getting eaten somewhere along the way (Apache or somewhere) I think I'll go with my plan. I should've posted this earlier, what I was planning on doing to work around, but it was dinner time and such here in Sweden, so I was just trying to get the post out there and see if I could get some insight tonight.

I am probably just going to create a uri_helper to create urls for me and if a variable is blank have it put a placeholder of '-' then in my code I'll know that just the '-' character means blank, CI is happy and I'm happy.

Or just enable query strings, I don't know why I thought this, but I thought enabling them in config.php would make the whole site use query strings index.php?c=&m= for everything, should've just tried switching it. Would've taken 5 seconds to see that wasn't true and I could go ahead as originally planned.

Thanks for the insights, CI, warts and all is my favorite PHP framework, but I still don't have that in-depth of a knowledge of all the ins and outs since websites in PHP is only part of what I spend my time on these days.
#7

[eluser]xwero[/eluser]
why do you have an empty segment? with uri_to_assoc you can mimic the query string but i think the default array is only a partial solution because you have to do
Code:
$params = $this->uri->uri_to_assoc(3, array('make', 'model'));

if($params['make'] === false){ $params['make'] = 'default make'; }
Where is would be easier to do
Code:
$params = $this->uri->uri_to_assoc(3, array('make'=>'default make', 'model'));

But it works in your situation.
#8

[eluser]octover[/eluser]
Say my two parameters were make and color. It's possible that the user would want to see all the blue cars without caring which make it was, so /browser/search//blue/ would be an example URI. Someone else may want to only see the BMWs of any color so their URI could be /browse/search/bmw without any complications. The problem is the former would set my $make variable to blue cause the // would just act like a single /.
#9

[eluser]Colin Williams[/eluser]
Quote:so /browser/search//blue/ would be an example URI

Why would you have no key? Abandon your /$make/$color convention for a moment. CI is not forcing you to use parameters like that. Consider URIs like /search/color/blue, /search/make/bmw, /search/make/bmw/color/blue, et. al.

And just to summarize for others out there, here are your URI options with CI "out-of-the-box":

Code:
/controller/function/id
#use function args or $this->uri->segment

/controller/function/param1/param2
#use function args or $this->uri->segment

/controller/function/key1/value1/key2/value2/ [and so on]
#use or $this->uri->uri_to_assoc

/controller/function?key1=value1&key2=value2
#enable_query_strings must be TRUE
#and uri_protocol should be either PATH_INFO, REQUEST_URI or an equivalent
#10

[eluser]octover[/eluser]
Ah missed that is what was being talked about. Thanks for the discussion, certainly food for thought in the future.

I'm going to code this up tomorrow, right now the path of least resistance still seems to be a query string. It may not be the prettiest solution, but it'll work with the form and allow me to create links quickly throughout the site to specific filters on the list of cars. This site was budgeted for quick dirty and fast and while I try and avoid such projects that I know I don't want in my portfolio before I start, it was a favor that I couldn't reasonably deny.




Theme © iAndrew 2016 - Forum software by © MyBB