PDO prepare/execute the table and append WHERE's - php

I'm trying to do the following:
public function checkResult($table, $appends)
{
$append = null;
foreach ($appends as $key => $val)
$append = " AND `{$key}` = '{$val}'";
$result = $this->fetchObj("
SELECT *
FROM :cms_table
WHERE id :append
", array(
":cms_table" => $table
":append" => $append
));
return ($result ? true : false);
}
But I can't get this working because I don't know how to do this in PDO.
Also when I leave the :append my query isn't working either. It looks like I can't execute a table. When I change :cms_table to the cms_pages (table I need) it works correctly.
I couldn't find a thing about such query's in PDO. Anyone who can help me out?

Don't try to outsmart yourself.
You don't need no checkResult() function, as well as no other function of similar structure.
$sql = "SELECT 1 FROM table WHERE field = ? AND col = ?";
$found = $db->fetchObj($sql, array(1,2));
is all you actually need.

Related

SQL Search query error in Laravel 5.3

I am trying to build a search query. I got following error, It seems syntax error of sql.
SQLSTATE[HY093]: Invalid parameter number (SQL: select * from products
where styles = Abstract , Abstract and subject = ? )
Why this error occurred ?
How to figure it out ?
My code as follows
if (isset($request->search)) {
//GET ALL INPUT FROM THE REQUEST
$query_strings = $request->all();
//PULL OUT ANY EMPTY FIELD FROM THE REQUEST
$filtered_array = array_filter($request->all());
//remove the last item
array_pop($filtered_array);
//BUILD A QUERY
$sql = array();
$values = array();
$x = 1;
foreach ( $filtered_array as $key =>$value ) {
if($x < count($filtered_array)){
$sql[]=" $key = ? and ";
$values[] =" $value , ";
} else {
$sql[]=" $key = ? ";
$values[] =" $value ";
}
$x++;
}
$fields = join(' ', $sql);
$v = join(' ',$values);
dd( \DB::select("select * from products where {$fields} ", [$v]));
}
When you're passing some values, you should add ? placeholder:
\DB::select("select * from products where ?", [$value]));
This is a bit of a stretch and I doubt it will work as is on the first try. But I really suggest you try and make use of the Laravel's query builder.
This code assumes you're passing 'products' table column names as names of GET or POST parameters and values you want to query by as values. For example:
url.com?price=200&size=2
Where 'price' and 'size' are column names of 'products' table.
Code:
// Check if request has 'search' parameter
if($request->has('search')) {
// $filtered_array now has all parameters that were passed to the controller
$filtered_array = $request->all();
// Start a query on table 'products'. Laravel style (more: https://laravel.com/docs/5.3/queries)
$query = \DB::table('products');
// For each parameter passed to the controller, we make "and where products.$key = $value" statement in the query
foreach($filtered_array as $key => $value) {
$query->where($key, '=', $value);
}
// Tell the query builder to get the results and save it to $results variable
$results = $query->get();
}
This will undoubtedly cause a lot of errors as anyone can send anything as GET/POST parameters and query by that (which will throw SQL error that the column doesn't exist).
You should change the $filtered_array = $request->all() to:
$filtered_array = $request->only(['id', 'price', 'size']);
This way you will store only the parameters you specify in the ->only(array) in the $filtered_array and ignore all the others. So you should replace 'id', 'price' and 'size' with all the columns of the 'products' table you wish to query by.

PDO update table with existing value?

I built PHP 2 year ago and now i want to change all about database to PDO,i have some problem with update table. I use this function to update table.
public function update($tabel, $fild = null ,$where = null)
{
$update = 'UPDATE '.$tabel.' SET ';
$set=null; $value=null;
foreach($fild as $key => $values)
{
$set .= ', '.$key. ' = :'.$key;
$value .= ', ":'.$key.'":"'.$values.'"';
}
$update .= substr(trim($set),1);
$json = '{'.substr($value,1).'}';
$param = json_decode($json,true);
if($where != null)
{
$update .= ' WHERE '.$where;
}
$query = parent::prepare($update);
$query->execute($param);
$rowcount = $query->rowCount();
return $rowcount;
}
everything work fine using this
$updatefild = array('count' => 20);
$where = "id = '123'";
echo $db->update("mytable",$updatefild, $where);
but i get problem when i want to update row with existing row, in mysql_query I usually use
mysql_query("update mytable set count=count+1 where id='123'");
how i achieve that use PDO ?
thanks
First, why are you using JSON just to decode it into an array? That is confusing.
Secondly, if you were trying to add a number to an existing field, you don't even need prepare().
You could just do
PDO->query("update mytable set count=count+".intval($int)." where id='123'");
If you were doing prepare, you could do:
$stmt = PDO->prepare("update mytable set count=count+:count where id='123'");
$stmt->execute(array(':count' => 1));
or
$stmt = PDO->prepare("update mytable set count=count+? where id='123'");
$stmt->execute(array(1));
Edit: You wouldn't be able to do it with how your function is written as you can't bind column names. PDO will quote it as a standard string. You would have to find a work around, possibly including the =count in the field somehow.

Creating an SQL query when the values to be used in the query are unknown

I have some search functionality that works with 3 drop down boxes. Based on the criteria chosen, a profile is returned. The 3 drop downs are:
County
Constituency
Gender
Now I am trying to build a query but have just realised that actually a person does not have to choose an option from each drop down and nor do I want them to.
So for instance I do not want to disable the search button until an option is selected from each drop down.
Having chosen a value from any drop down, and possibly having no value selected from any drop down at all, and just clicking the search button, I am trying to understand how I can cope with the unknown combinations.
My first thought was that I could use something like a truth table but I imagine this is simply overkill and in fact this is a very common piece of functionality.
Then I thought maybe I could have something like:
$county = "$_GET['county'];";
$constituency = "$_GET['constituency'];";
$gender = "$_GET['gender'];";
Then I could check to see if they are empty and somehow use this value, e.g.
if($county !== '') {
???SOMEHOW MAKE USE OF THIS IN AN SQL QUERY???
PERHAPS PASS IT TO ANOTHER PARAMETER
$sqlparams = "county = '$county'";
}
SELECT * FROM profile
WHERE {$sqlparams};
I think I'm on the right tracks but could use some guidance.
All help is greatly appreciated.
This should do want you want, I think.
<?php
$tooLookFor = array("county", "constituency", "gender");
foreach($tooLookFor as $key){
if(isset($_GET[$key]) && strlen($_GET[$key])>0){
$queryParams[] = $key.'="'.$_GET[$key].'"';
}
}
$query = "SELECT * FROM profile WHERE ".implode(' AND ', $queryParams);
?>
You could do something like:
$county = $_GET['county'];
$constituency = $_GET['constituency'];
$gender = $_GET['gender'];
$sqlparams = array();
if($county !== '') {
$sqlparams[] = "county = '$county'";
}
if($constituency !== '') {
$sqlparams[] = "constituency = '$constituency'";
}
if($gender !== '') {
$sqlparams[] = "gender = '$gender'";
}
$query = "SELECT * FROM profile";
if (count($sqlparams) > 0) {
$query .= " WHERE " . implode(" AND ", $sqlparams);
}
You can do that with something like this:
$where = array();
//repeat as needed
$where[$column] = $value;
$where2 = array();
foreach($where as $key => $value){
$where2[] = "$key = '$value'";
}
$where_string = implode(' AND ', $where2);
$where_string will have the string to insert after WHERE.
Yes, you are on the right track, you're just not at the right switch yet. ;)
You can't build the query until you know what you have to work with. So first, in your validation, determine (as you are doing) with the key words actually are and what fields they represent. Presumably these map to fields in tables, maybe 3 tables? Point is, your query will need to be dynamically built.

Running PHP search script with empty parameters returns entire MySQL table

When I run the following MySQL query via PHP and all of the elements of $_GET() are empty strings, all the records in the volunteers table are returned (for obvious reasons).
$first = $_GET['FirstName'];
$last = $_GET['LastName'];
$middle = $_GET['MI'];
$query = "SELECT * FROM volunteers WHERE 0=0";
if ($first){
$query .= " AND first like '$first%'";
}
if ($middle){
$query .= " AND mi like '$middle%'";
}
if ($last){
$query .= " AND last like '$last%'";
}
$result = mysql_query($query);
What is the most elegant way of allowing empty parameters to be sent to this script with the result being that an empty $result is returned?
my solution:
$input = Array(
'FirstName' => 'first',
'LastName' => 'last',
'MI' => 'mi'
);
$where = Array();
foreach($input as $key => $column) {
$value = trim(mysql_escape_string($_GET[$key]));
if($value) $where[] = "`$column` like '$value%'";
}
if(count($where)) {
$query = "SELECT * FROM volunteers WHERE ".join(" AND ", $where);
$result = mysql_query($query);
}
There's no point in running a (potentially) expensive query if there's nothing for that query to do. So instead of trying to come up with an alternate query to prevent no-terms being searched, just don't run the search at all if there's no terms:
$where = '';
... add clauses ...
if ($where !== '') {
$sql = "SELECT ... WHERE $where";
... do query ...
} else {
die("You didn't enter any search terms");
}
With your current code, if everything is empty, you will get the WHERE 0=0 SQL which is TRUE for all rows in the table.
All you have to do is remove the if statements...

where clause not displaying data

i am trying to display data based on wether data in a field is new. instead of showing only the data that is new it is showing all data. can someone point out my error. many thanks
<?php
include("../../js/JSON.php");
$json = new Services_JSON();
// Connect to MySQL database
mysql_connect('localhost', 'root', '');
mysql_select_db(sample);
$page = 1; // The current page
$sortname = 'id'; // Sort column
$sortorder = 'asc'; // Sort order
$qtype = ''; // Search column
$query = ''; // Search string
$new = 1;
// Get posted data
if (isset($_POST['page'])) {
$page = mysql_real_escape_string($_POST['page']);
}
if (isset($_POST['sortname'])) {
$sortname = mysql_real_escape_string($_POST['sortname']);
}
if (isset($_POST['sortorder'])) {
$sortorder = mysql_real_escape_string($_POST['sortorder']);
}
if (isset($_POST['qtype'])) {
$qtype = mysql_real_escape_string($_POST['qtype']);
}
if (isset($_POST['query'])) {
$query = mysql_real_escape_string($_POST['query']);
}
if (isset($_POST['rp'])) {
$rp = mysql_real_escape_string($_POST['rp']);
}
// Setup sort and search SQL using posted data
$sortSql = "order by $sortname $sortorder";
$searchSql = ($qtype != '' && $query != '') ? "where ".$qtype." LIKE '%".$query."%' AND new = 1" : '';
// Get total count of records
$sql = "select count(*)
from act
$searchSql";
$result = mysql_query($sql);
$row = mysql_fetch_array($result);
$total = $row[0];
// Setup paging SQL
$pageStart = ($page -1)*$rp;
$limitSql = "limit $pageStart, $rp";
// Return JSON data
$data = array();
$data['page'] = $page;
$data['total'] = $total;
$data['rows'] = array();
$sql = "select *
from act
$searchSql
$sortSql
$limitSql";
$results = mysql_query($sql);
while ($row = mysql_fetch_assoc($results)) {
$data['rows'][] = array(
'id' => $row['id'],
'cell' => array($row['id'], $row['slot'], $row['service'], $row['activity'], $row['department'], $row['company'], $row['address'], $row['user'], $row['item'], $row['filebox'], date('d/m/Y',strtotime($row['date'])), $row['quantity'], $row['type'], $row['new'])
);
}
echo $json->encode($data);
?>
You should debug SQL by looking at the SQL query, not at the PHP code that produces the SQL query. If you echo $sql and look at it, you'll probably see any syntax errors much more easily.
You can also copy & paste that SQL and try to execute it in the MySQL command tool, and see what happens, whether it gives the result you want, you can profile it or use EXPLAIN, etc.
You're using mysql_real_escape_string() for integers, column names, and SQL keywords (ASC, DESC). That escape function is for escaping only string literals or date literals. It's useless for escaping unquoted integers, column names, SQL keywords, or any other SQL syntax.
For integers, use (int) to typecast inputs to an integer.
For column names or SQL keywords, use a whitelist map -- see example in my presentation http://www.slideshare.net/billkarwin/sql-injection-myths-and-fallacies
You're not testing for error statuses returned by any of your functions. Most functions in ext/mysql return false if some error occurs. You should check for that after every call to a mysql function, and report errors if they occur.
You're selecting a database using a constant name sample instead of a quoted string "sample". This might be intentional on your part, I'm just noting it.
Also, this is not related to your errors, but you should really upgrade to PHP 5. PHP 4 has been end-of-lifed for over two years now.
after looking at the code again and all the suggestions i think i should be using an AND clause and not WHERE. for example the code
$searchSql = ($qtype != '' && $query != '') ? "where ".$qtype." LIKE '%".$query."%' AND new = 1" : '';
this is the WHERE clause? which basically translates to:
$sql = "select *
from act
$searchSql
$sortSql
$limitSql"; <- original code
$sql = "select *
from act
WHERE company LIKE '%demo%' AND new = 1
$sortSql
$limitSql";<-updated code
am i on the right track?

Categories