Unassigned php variable in WHERE clause of mysql query - php

I have a query with php variables in WHERE clause. But it does not return results if the variables are unassigned.
$customer = isset($_REQUEST['customer'])?$_REQUEST['customer']:'';
$territory = isset($_REQUEST['territory'])?$_REQUEST['territory']:'';
$status = isset($_REQUEST['status'])?$_REQUEST['status']:'';
$getOrder = "SELECT * FROM order WHERE Customer = '$customer' AND Territory = '$territory' AND Status = '$status'";
$getOrderQuery = mysql_query($getOrder);
while($iRow = mysql_fetch_array($getOrderQuery))
{ .... }
If the three variables are assigned, it returns results. What do I need to do so that the query will return results even the variables are empty?

I can't comment on your post but I can leave an answer.
Try to echo $getOrder;
make sure the variables have what you expect and then take the query and execute it directly on the database using MySQL client or phpMyAdmin.
Also, you should escape your variables as you are valuable to a SQL injection attack. I like to use PDO API.
you can also try this based on the comment below
SELECT * FROM order
WHERE IFNULL(Customer, '') IN('$customer', '') AND IFNULL(Territory,'') IN('$territory','') AND IFNULL(Status, '') IN('$status','')";

Related

Php search Splitting criteria type

I have a php search form with two fields. One for $code another for '$name'.The user uses one or the other, not both.
The submit sends via $_POST.
In the receiving php file I have:
SELECT * FROM list WHERE code = '$code' OR name = '$name' ORDER BY code"
Everything works fine, however I would like that $code is an exact search while $name is wild.
When I try:
SELECT * FROM list WHERE code = '$code' OR name = '%$name%' ORDER BY code
Only $code works while $name gives nothing. I have tried multiple ways. Changing = to LIKE, putting in parentheses etc. But only one way or the other works.
Is there a way I can do this? Or do I have to take another approach?
Thanks
If you only want to accept one or the other, then only add the one you want to test.
Also, when making wild card searches in MySQL, you use LIKE instead of =. We also don't want to add that condition if the value is empty since it would become LIKE '%%', which would match everything.
You should also use parameterized prepared statements instead of injection data directly into your queries.
I've used PDO in my example since it's the easiest database API to use and you didn't mention which you're using. The same can be done with mysqli with some tweaks.
I'm using $pdo as if it contains the PDO instance (database connection) in the below code:
// This will contain the where condition to use
$condition = '';
// This is where we add the values we're matching against
// (this is specifically so we can use prepared statements)
$params = [];
if (!empty($_POST['code'])) {
// We have a value, let's match with code then
$condition = "code = ?";
$params[] = $_POST['code'];
} else if (!empty($_POST['name'])){
// We have a value, let's match with name then
$condition = "name LIKE ?";
// We need to add the wild cards to the value
$params[] = '%' . $_POST['name'] . '%';
}
// Variable to store the results in, if we get any
$results = [];
if ($condition != '') {
// We have a condition, let's prepare the query
$stmt = $pdo->prepare("SELECT * FROM list WHERE " . $condition);
// Let's execute the prepared statement and send in the value:
$stmt->execute($params);
// Get the results as associative arrays
$results = $stmt->fetchAll(PDO::FETCH_ASSOC);
}
The variable $results will now contain the values based on the conditions, or an empty array if no values were passed.
Notice
I haven't tested this exact code IRL, but the logic should be sound.

PHP posting a variable in a variable using mysql

I need to use the number of the district to be the tail end of my variable. Example $publish_page_ADD THE DISTRICT NUMBER
I am grabbing the $district_num from my url which I've verified with echo
Here is what I've tried
$district_num = $_REQUEST['district_num']; // from url and works
$publish_page_.''.$district_num = $district_var['publish_page_'.$district_num.'']; //this does not work
$publish_page_.''.$district_num = addslashes($_POST['publish_page_'.$district_num.'']); //this does not work
$sql = "UPDATE districts SET
publish_page_$district_num = '$publish_page_$district_num' //this does not work and throws error "can not find publish_page_ in field list
WHERE district_num ='$district_num'"; //this works when the above code is removed
Follow up on corrected code... Thank You #cale_b and #Bill Karwin
$district_num = (int) $_REQUEST['district_num'];
$$publish_page = "publish_page_{$district_num}";
$$publish_page = $district_var[ "publish_page_{$district_num}"];
if (isset($_POST['submitok'])):
$$publish_page = addslashes($_POST[$publish_page]);
$sql = "UPDATE districts SET
publish_page_{$district_num} = '$publish_page'
WHERE district_num ='$district_num'";
If you want to learn about PHP's variable variables, it's in the manual (I linked to it). But you actually don't need it in your case.
Be careful about SQL injection. Your code is vulnerable to it.
Since you're using input to form a SQL column name, you can't use SQL query parameters to solve it. But you can cast the input to an integer, which will protect against SQL injection in this case.
$district_num = (int) $_REQUEST['district_num'];
$publish_page_col = "publish_page_{$district_num}";
The above is safe because the (int) casting makes sure the num variable is only numeric. It isn't possible for it to contain any characters like ' or \ that could cause an SQL injection vulnerability.
For the other dynamic values, use query parameters.
$publish_page_value = $_REQUEST["publish_page_4{$district_num}"];
$sql = "UPDATE districts SET
`$publish_page_col` = ?
WHERE district_num = ?";
$stmt = $pdo->prepare($sql);
$stmt->execute([ $publish_page_value, $district_num ]);
As #cale_b comments below, you should understand that in PHP, variables can be expanded inside double-quoted strings. See http://php.net/manual/en/language.types.string.php#language.types.string.parsing for details on that.

Why isn't num_rows returning any value?

I have the following PHP code where I want to return the number of rows based on the previous SQL statement, however, $num doesn't doesn't seem to be returning anything.
$ipAddress = $_SERVER['REMOTE_ADDR'];
if ($result = $mysqli->query("SELECT * FROM whovisit WHERE ipAddress = ".$ipAddress."")) {
$num = $result->num_rows;
}
echo $num; // <-- not showing up on my page
if ($num > 0) {
$sqlupdate = $mysqli->query("UPDATE whovisit SET visitCount = visitCount + 1 WHERE ipAddress = ".$ipaddress."");
}
else {
$sqlupdate = $mysqli->query("INSERT INTO whovisit values ('".$_SERVER['REMOTE_ADDR']."', '1')");
}
Any ideas? Thanks
Ensure that you have a $ infront of ipaddress
$ipaddress = $_SERVER['REMOTE_ADDR'];
As the IP address is a string it should be put in single quotes.
if ($result = $mysqli->query("SELECT * FROM whovisit WHERE ipAddress = '".$ipAddress."';")) {
$num = $result->num_rows;
}
If you are unsure if the query is running correctly you could also add an else to the above if statment and output any mysql error messages.
}else{
echo "QueryError: ".$mysqli->error
}
Similar post:
php switching to mysqli: num_rows issue
In PHP v 5.2 mysqli::num_rows is not set before fetching data rows from the query result.
If you get nothing on the page, this means $num must not be being set. Given the code you have, that would mean the if block is not being executed - i.e. $result is a falsey value. Which means your query is failing.
And unfortunately this one's pretty easy if you examine the generated query. Following what happens step-by-step, we see you're injecting the contents of the server variable REMOTE_ADDR, which is presumably going to be an IPv4 address in a dotted-decimal format, into the query string. So you'll have a SQL statement like, which fails to parse at the second .:
SELECT * FROM whovisit WHERE ipAddress = 127.0.0.94
Oops.
Since the IP address is a string, you need to enclose it in single quotes:
"SELECT * FROM whovisit WHERE ipAddress = '".$ipAddress."'"
Which will result in the queries in the following form:
SELECT * FROM whovisit WHERE ipAddress = '127.0.0.94'
Or better yet, use a parameterized query and you don't have to worry about quoting and escaping. $_SERVER['REMOTE_ADDR'] is probably relatively safe as far as SQL injection attacks go, but 1)it's easier to use parameters than a concatenated string, and 2)you never truly can trust a value you didn't generate yourself.

Safe dynamic PHP SQL WHERE clause

What would be a safe way (eg bindParam, prepare()) to insert a dynamic where clause. This is sent to PHP via ajax. So something comes from ajax form with
.php?where=name&what=bob
or maybe
.php?where=type$what=clothes
Then in PHP after everything is set to variables eg
if(isset($_POST['where'])){
$where = $_POST['where'];
}
if(isset($_POST['what'])){
$what= $_POST['what'];
}
Then a function is run to retrieve data
function retrieveData($db, $where, $what){
$getData = $db->prepare("SELECT name, type, stuff FROM tbl WHERE :where = :what");
$getData->bindParam(':what',$what);
$getData->bindParam(':where',$where);
$getData->execute();
..............
}
When I run a query like this i always get the SQL error about
'WHERE name = bob"
So the values are passed but I guess the SQL is not valid?
Any help appreciated. Thanks.
I think the string should be quoted
...WHERE name = 'bob'....
so try like this
$getData->bindParam(':what',$what,PDO::PARAM_STR, 15);
$getData->bindParam(':where',$where,PDO::PARAM_STR, 15);

Building interactive WHERE clause for Postgresql queries from PHP

I'm using Postgresql 9.2 and PHP 5.5 on Linux. I have a database with "patient" records in it, and I'm displaying the records on a web page. That works fine, but now I need to add interactive filters so it will display only certain types of records depending on what filters the user engages, something like having 10 checkboxes from which I build an ad-hoc WHERE clause based off of that information and then rerun the query in realtime. I'm a bit unclear how to do that.
How would one approach this using PHP?
All you need to do is recieve all the data of your user's selected filters with $_POST or $_GET and then make a small function with a loop to concatenate everything the way your query needs it.
Something like this... IN THE CASE you have only ONE field in your DB to match with. It's a simple scenario and with more fields you'll need to make it so that you add the field you really need in each case, nothing too complex.
<?php
//recieve all the filters and save them in array
$keys[] = isset($_POST['filter1'])?'$_POST['filter1']':''; //this sends empty if the filter is not set.
$keys[] = isset($_POST['filter2'])?'$_POST['filter2']':'';
$keys[] = isset($_POST['filter3'])?'$_POST['filter3']':'';
//Go through the array and concatenate the string you need. Of course, you might need AND instead of OR, depending on what your needs are.
foreach ($keys as $id => $value) {
if($id > 0){
$filters.=" OR ";
}
$filters.=" your_field = '".$value."' ";
}
//at this point $filters has a string with all your
//Then make the connection and send the query. Notice how the select concatenates the $filters variable
$host = "localhost";
$user = "user";
$pass = "pass";
$db = "database";
$con = pg_connect("host=$host dbname=$db user=$user password=$pass")
or die ("Could not connect to server\n");
$query = "SELECT * FROM table WHERE ".$filters;
$rs = pg_query($con, $query) or die("Cannot execute query: $query\n");
while ($row = pg_fetch_row($rs)) {
echo "$row[0] $row[1] $row[2]\n";
//or whatever way you want to print it...
}
pg_close($con);
?>
The above code will get variables from a form that sent 3 variables (assuming all of them correspond to the SAME field in your DB, and makes a string to use as your WHERE clause.
If you have more than one field of your db to filter through, all you need to do is be careful on how you match the user input with your fields.
NOTE: I did not add it here for practical reasons... but please, please sanitize user input.. ALWAYS sanitize user input before using user controlled data in your queries.
Good luck.
Don't do string concatenation. Once you have the values just pass them to the constant query string:
$query = "
select a, b
from patient
where
($x is not null and x = $x)
or
('$y' != '' and y = '$y')
";
If the value was not informed by the user pass it as null or empty. In the above query the x = $x condition will be ignored if $x is null and the y = '$y' condition will be ignored if $y is empty.
With that said, a check box will always be either true or false. What is the exact problem you are facing?
Always sanitize the user input or use a driver to do it for you!
I have created a Where clause builder exactly for that purpose. It comes with the Pomm project but you can use it stand alone.
<?php
$where = Pomm\Query\Where::create("birthdate > ?", array($date->format('Y-m-d')))
->andWhere('gender = ?', array('M'));
$where2 = Pomm\Query\Where::createWhereIn('something_id', array(1, 15, 43, 104))
->orWhere($where);
$sql = sprintf("SELECT * FROM my_table WHERE %s", $where2);
$statement = $pdo->prepare($sql);
$statement->bind($where2->getValues());
$results = $statement->execute();
This way, your values are escaped and you can build dynamically your where clause. You will find more information in Pomm's documentation.

Categories