Safe dynamic PHP SQL WHERE clause - php

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);

Related

Passing PHP variables into sql query

I would like to create a filter, and pass both category and the value into the sql query in the WHERE clause.
If i set manually the category, it gets the values and filters the results. But when I want to pass the category, it gives me this error.
Here is the code I use:
$('#filterEvents').click(function () {
document.location.href = 'events.php?filter=' + $('#eventFilterOption').val() + '&filterValue=' + $('#eventFilterInput').val();
});
And the PHP processing:
$category = $_GET['filter'];
$searchValue = $_GET['filterValue'];
$sql = "SELECT EV_Date, EV_KKZ, EV_CardNr, TE_Name, EV_Name, EV_SurName, EV_EventTyp FROM events1
INNER JOIN terminal1 ON terminal1.TE_IDX = events1.EV_FK_TermIDX
WHERE ".$category." = '" . $searchValue . "'
ORDER BY EV_Date DESC
LIMIT 2000";
print_r($sql);
$query = $DB->prepare($sql);
$query->execute();
$data = $query->fetchAll(PDO::FETCH_ASSOC);
You have a problem with getting the variables - the PHP script is not getting the values - so I believe you have a bug in your Javascript.
More importantly, this is not a safe way to run queries. Your PHP is taking variables passed by the user and inserting them directly into SQL - with no validation. It would be very easy to abuse this functionality to extract information or modify your database.
You should use the value of $category to select a known column and then use bind parameters to set $searchValue.
If you change the functionality a little you will be able to use the prepared query with bound params.
so say you have filters for colour and size at the moment looks like you would call urls like
events.php?filter=Colour&filterValue=Red
events.php?filter=Size&filterValue=Large
you could change to pass filter[name]=value
events.php?filterColour=Red
events.php?filterSize=Large
Javascript would look something like this
$('#filterEvents').click(function () {
document.location.href = 'events.php?filter' + $('#eventFilterOption').val() + '=' + $('#eventFilterInput').val();
});
The query could be rewritten as follows (assuming columns of Size and Colour)
$sql = "SELECT EV_Date, ....
WHERE
( '' = :colour OR Colour = :colour ) AND
( '' = :size OR Size = :size )
ORDER BY ....
and a call to bind the actual params added
$query = $DB->prepare($sql);
$query->bindParam(':colour', $_GET['filterColour'], PDO::PARAM_STR, 12);
$query->bindParam(':size', $_GET['filterSize'], PDO::PARAM_STR, 12);
$query->execute();
This allows you to use prepared queries and avoid risk of SQL injection
As a bonus (or bug) it could support multiple filter options at the same time
events.php?filterSize=Large&filterColour=Red
You have empty values here:
$category = $_GET['filter'];
$searchValue = $_GET['filterValue'];
You should debug the method how you are getting them in js.
BTW you will always see that error when open this page /events.php. Because these variables will be empty by default.

PHP with SQL Server (No MySQL please) - Select Statement with LIKE in the WHERE clause

I hate PHP, but I have to do this. I have spent the last 2 days searching for a simple way to write a SQL Select with a LIKE clause where the parameter is passed from the lname input text on the form. Now, it has to be SQL Server, NOT MYSQL
So here is what I've done so far.
function getActorDetailsLnameOnly($lname) {
// the SQL query to be executed on the database
$query = "select NameFirst, NameLast, Age, Gender from actor where NameLast like '%$lname%'";
return executeQuery($query);
}
on the index.php, I wrote the following:
if ((!empty($_REQUEST['lname'])) and ( empty($_REQUEST['age']) and ( empty($_REQUEST['gender'])))) {
$lname = (string) $_GET['lname'];
$sql = getActorDetailsLnameOnly($lname);
foreach ($sql as ...) {
extract(...);
...
The code returns a value, but it's nowhere near correct. It's like requesting A in the select statement and it's returning Z. I can't figure it out.
You check form input values through $_REQUEST['lname'] and then assign a variable $lname = (string) $_GET['lname'];. If form method is POST then $_REQUEST['lname'] would have the value and $_GET['lname'] would be empty. As the result like pattern would be '%%', which is effectively everything but NULL.
Basically, $_GET is for GET, $_POST is for POST and $_REQUEST is for any.
Try using $lname = (string) $_REQUEST['lname'];.

Unassigned php variable in WHERE clause of mysql query

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','')";

Creating a json array using concat with MySql

I'm creating a json array from MySql data using concat like this:
$id = '5705';
$sql = 'select concat("{""type:""colName"",""id"":""$id""}") as myJson from table where etc.;
$stmt = $conn->prepare($sql);
What's happening is, instead of getting data from colName from the table and the value of $id, I'm getting the result as it is in $sql. How do I break out of it and get colName and $id's value?
Current Result
{""type:""colName"",""id"":""$id""}
Desired Result
{""type:""novice"",""id"":""5705""}
//Here novice is data from colName, and 5705 is the value of $id
Please DON'T DO THAT. Trying to format data into JSON in your SQL will be fragile as encoding things into JSON is subtly more tricky that you would expect and you will inevitably get it wrong.
You should use the json_encode function in PHP. It will work reliably whereas your code will almost certainly break.
$dataArray = array();
while($statement->fetch()){
$data = array();
$data['type'] = $typeColumn;
$data['id'] = $id;
$dataArray[] = $data;
}
json_encode($dataArray, JSON_HEX_QUOT);
Also, formatting data to send to a client really shouldn't be part of an SQL query.
You need a better concatenation either in query and php
'select concat("{""type:"",colName,"",""id"":""'.$id.'""}")
Despite it is not really needed you could surround column name with backticks `
Your variables inside your string are not substituted with their values, as you got single quotes. Double quoted strings will expand variables with their values
Thus, you could invert your quotes, like this, in order to get the actual values of your variables:
$sql = "select concat('...')"

Trying to write a PHP function for mysql, SELECT SUM()

I am trying to write a PHP function which gets the sum of values in 1 column of a table. MY SQL statement works just fine. However, when I write my function and attempt to echo the variable into my HTML code, it returns '0'.
Here is my function:
function get_asset_value($org_ID) {
global $db;
$query = "SELECT SUM(asset_value) FROM assets
WHERE org_ID = '$org_ID'";
$asset_sum = $db->query($query);
$asset_sum = $asset_sum->fetch();
return $asset_sum;
In my HTML, I have the following:
<?php echo $asset_sum; ?>
I'm not sure if this has to do with the "fetch" portion of my function. I really don't know what fetch does but I tried copying/modifying this piece of code from a working function (which doesn't return the sum, but it is a select statement).
Thank you!
In addition to
SELECT SUM(asset_value) AS the_sum FROM assets WHERE ord_ID = '$ord_ID';
...
return $asset_sum['the_sum']
by Brad,
you better do
$safer = mysql_real_escape_string($org_ID);
then do,
SELECT SUM(asset_value) AS the_sum FROM assets WHERE ord_ID = '$safer';
...
return $asset_sum['the_sum']
SELECT SUM(asset_value) AS the_sum FROM assets WHERE ord_ID = '$ord_ID';
...
return $asset_sum['the_sum'];
The issue is, you are returning an entire record, rather than just the field you want.
Also, judging by the way you are inserting that ID in your query, I suspect you are open to SQL injection. You should really learn to do prepared queries with PDO.

Categories