0

Say you have a search form like so:

<form action="<?php $_PHP_SELF ?>" method="GET">
Some filter:
<select name="filter">
<option value="">Any value</option>
<option value="1">value is 1</option>
etc...
</select>
<input type="submit" value="Search">
</form>

and your index page looks like this:

<?php 
if($_GET['filter']){

$sql = 'SELECT * FROM table WHERE value=' . $_GET['filter'];
/* prepare, execute blah blah blah etc etc etc */

include 'results.php';
exit();
}
include 'searchform.php';
?>

Which would work perfectly well if a filter is set. But if not I'd like it to show all results, instead it just keeps the page on the searchform. If I change it to if($_GET['filiter'] or $_GET['filter'] == ""){ it (logically) just gets all the results unfiltered and ignores the searchform. Any solutions?

NOTE: I know that I could set a hidden input type like <input type="hidden" name="hidden" value="true"> and instead of checking the filter using if($_GET['hidden'] == 'true'){ but then it would be visible in the URL and I don't want that. Nor do I want to just use POST because then the filter won't be visible, and I'd prefer that if someone wants to just change the filter in the URL they can instead of going back to the searchform.

NOTE 2 I use PDO to prepare and execute, however that has nothing to do with the issue, hence why I haven't provided it

cameronjonesweb
  • 2,435
  • 3
  • 25
  • 37
  • 2
    Your code is vulnerable to SQL Injection. see http://stackoverflow.com/questions/60174/how-can-i-prevent-sql-injection-in-php – haim770 Sep 17 '13 at 06:18
  • @haim770 1. nothing to do with the question 2. I haven't even given you the code – cameronjonesweb Sep 17 '13 at 06:21
  • 1
    1. "nothing"? maybe. that's why i didn't post an answer. 2. i really am not familiar with your actual code, but the php code you pasted here is vulnerable. – haim770 Sep 17 '13 at 06:23
  • @user1672694: Using PDO without using parametrized variables **defeats the purpose of using PDO**: your code is no safer than code based on mysql_* functions at the moment from what I can see. – Steven Liao Sep 17 '13 at 06:37
  • This is only a dumbed down version of the actual thing I'm working on, genericised so that others would understand it better. Hence why I left out the pdo as it has nothing to do with the actual issue – cameronjonesweb Sep 17 '13 at 06:44

7 Answers7

1
<?php 
if(isset($_GET['filter'])){

$sql = 'SELECT * FROM table';
if ($_GET['filter'] != "") { $sql .= ' WHERE value=' . $_GET['filter'];
/* prepare, execute blah blah blah etc etc etc */

include 'results.php';
exit();
}
include 'searchform.php';
?>
hex4
  • 695
  • 2
  • 9
  • 23
1

Change your form to (Add all for Any value)

<form action="<?php $_PHP_SELF ?>" method="GET">
Some filter:
<select name="filter">
<option value="all">Any value</option>
<option value="1">value is 1</option>
etc...
</select>
</form>

And in PHP

<?php 
if(isset($_GET['filter'])){

if($_GET['filter'] == 'all'){
 $sql = "SELECT * FROM table";
}else{
 //make sure the input is safe
 $value = intval($_GET['filter']);
 if($value < 1){
   die("SQL injection");
 }
 $sql = "SELECT * FROM table WHERE value=$value";
}

/* prepare, execute blah blah blah etc etc etc */

include 'results.php';
exit();
}
include 'searchform.php';
?>
Jason OOO
  • 3,567
  • 2
  • 25
  • 31
1

Steven Liao's solution is perfect for you. and yes take care of sql injection by escaping $_GET['filter'] in query. like

$condition = isset($_GET['filter']) ? 'WHERE value='.mysql_real_escape_string($_GET['filter']) : ''; 
sharafatalee
  • 134
  • 3
0

As per your requirement i.e:

"work perfectly well if a filter is set. But if not I'd like it to show all results"

  if(isset($_GET['filter'])){

$sql = 'SELECT * FROM table WHERE value=' . $_GET['filter'];
/* prepare, execute blah blah blah etc etc etc */

}else {
$sql = 'SELECT * FROM table';
}
Moeed Farooqui
  • 3,604
  • 1
  • 18
  • 23
0

Simple, unsafe solution.

$condition = isset($_GET['filter']) ? ' WHERE value='.$_GET['filter'] : ''; // assuming $_GET['filter'] is safe
$sql = 'SELECT * FROM table'.$condition.';';

Note that the above solution (and most of the other solutions provided in this thread) is vulnerable to SQL injections and that you should be using PDO instead.

Here is the safe solution using PDO:

$pdo_obj = new PDO(/*connection parameters*/);
$condition = isset($_GET['filter']) ? ' WHERE value=:filter' : ''; // no need for assumptions
$sql = 'SELECT * FROM table'.$condition.';';
$sth = $pdo_obj->prepare($sql);
$sth->bindParam(':filter', $_GET['filter']);
$sth->execute();
$result = $sth->fetchAll();

?>

Community
  • 1
  • 1
Steven Liao
  • 3,577
  • 3
  • 19
  • 25
0
<?php 
$sql = 'SELECT * FROM table';
if($_GET['filter']!="")
$sql.=' WHERE value=' . $_GET['filter'];

// prepare, execute blah blah blah etc etc etc

include 'results.php';
exit();
}
include 'searchform.php';
?>
0

Try something like:

$sql = 'SELECT * FROM table';

if(!empty($_GET['filter']))
     $sql .= ' WHERE value=' . (int) $_GET['filter']; //at the very least, cast this as int.

/* prepare, execute blah blah blah etc etc etc */

include 'results.php';

You're wide open to SQL injection if you don't sanitise the user input in some way.

calcinai
  • 2,567
  • 14
  • 25