PDOException thrown in PHP - php

I'm getting the error "SQLSTATE[HY093]: Invalid parameter number: number of bound variables does not match number of tokens" when I try to run the below function:
public function find_products($string = '', $fields = array(), $sort_by = '', $sort_dir = 'ASC') {
$fields = empty($fields) ? '*' : ('' . implode(',', $fields) . '?');
$bindings = array('%' . $string . '%','%' . $string . '%','%' . $string . '%');
$and_where_checks = array('series','material');
$AND = '';
// Loop through the POST variables to see what is safe to play with
$allowed = array();
foreach ($and_where_checks as $awc)
if ( ! empty($_POST[$awc]))
$allowed = $awc;
if ( ! empty($allowed)) {
$tmp = array();
foreach ($allowed as $v)
$tmp = '' . $v . ' IN (' . str_pad('', count($v) * 2 - 1, '?,') . ')';
$AND = 'AND (' . implode(' AND ', $tmp) . ') ';
foreach ($allowed as $k)
foreach ($_POST[$k] as $v)
$bindings = $v;
}
$query =
"SELECT " . $fields . " FROM " . $this->product_table . " " .
"WHERE (" . $this->primary_key . " LIKE ? " .
$AND .
"ORDER BY " . $sort_by . " " . $sort_dir;
$sth = $this->$dbh->prepare($query);
$sth->execute($bindings);
return $sth->fetchAll(PDO::FETCH_ASSOC);
}
The $POST[$awc] variables are filled by checkboxes on this page http://ladd-dev.bitstormweb.com/products/interactive-product-finder/. When I choose one of each checkbox group (e.g. 1 Series and 1 Material) the results are fine, but when I choose multiple boxes in the same group, I get the PDOException.
Does anyone know why? I'm still learning this code so any help would be appreciated!

In your query, you only have one variable to be bound (the ?):
$query =
"SELECT " . $fields . " FROM " . $this->product_table . " " .
"WHERE (" . $this->primary_key . " LIKE ? " .
$AND .
"ORDER BY " . $sort_by . " " . $sort_dir;
Here, you must be either binding 0 or binding more than 1. Check how many values are in $bindings.
$sth = $this->$dbh->prepare($query);
$sth->execute($bindings);
You can check how many values are in $bindings by using print_r($bindings);
Update: Without knowing what your input is, your code seems to be using $bindings twice. It is set at the top with 3 values that are the same thing: $bindings = array('%' . $string . '%','%' . $string . '%','%' . $string . '%'); then at the bottom you have a foreach where you are not using an array at all:
foreach ($_POST[$k] as $v)
$bindings = $v;

Related

PHP PDO how to bind values to varibale contains concatenated string

How do i bind values to a variable which is partially processed with diffrent statements and then concatenated using php .= method
Please note that I am not using array to bind parameters.
below is piece of code
$wher = '';
now I have added few varibles to $wher like
if (!empty($_SESSION['advs']['title']))
{
$wher .= '(';
if (isset($_SESSION['advs']['desc']))
{
$wher .= "(au.description like '%" . $system->cleanvars($_SESSION['advs']['title']) . "%') OR ";
}
$wher .= "(au.title like '%" . $system->cleanvars($_SESSION['advs']['title']) . "%' OR au.id = " . intval($_SESSION['advs']['title']) . ")) AND ";
}
more addition to $wher
if (isset($_SESSION['advs']['buyitnow']))
{
$wher .= "(au.buy_now > 0 AND (au.bn_only = 'y' OR au.bn_only = 'n' && (au.num_bids = 0 OR (au.reserve_price > 0 AND au.current_bid < au.reserve_price)))) AND ";
}
if (isset($_SESSION['advs']['buyitnowonly']))
{
$wher .= "(au.bn_only = 'y') AND ";
}
if (!empty($_SESSION['advs']['zipcode']))
{
$userjoin = "LEFT JOIN " . $DBPrefix . "users u ON (u.id = au.user)";
$wher .= "(u.zip LIKE '%" . $system->cleanvars($_SESSION['advs']['zipcode']) . "%') AND ";
}
now I am using $wher in database query like
// get total number of records
$query = "SELECT count(*) AS total FROM " . $DBPrefix . "auctions au
" . $userjoin . "
WHERE au.suspended = 0
AND ".$wher . $ora . "
au.starts <= " . $NOW . "
ORDER BY " . $by;
$wher is being used in SQL select query.
How do I put placeholders to $wher and bind the values??
my problem is something like PHP PDO binding variables to a string while concatenating it
But slight different way

PHP trim not working

I m trying to get rid of the trailing comma my sql statemen using trim but it doesnt seem to work
if(isset($_POST['report'])){
//====
$sql = 'INSERT INTO weekly_repo ( hospnme, disease, week, under5, above5, dat) VALUES ';
$week = intval($_POST['current_week']);
$diseases = $_POST['diseases'];
foreach($diseases as $disease){
$sql .= ' ( "' . filterString($_POST['hospital']). '", "' . filterString($disease['disease']) . '", ' . $week . ', ' . intval($disease['under_5']) . ', ' . intval($disease['over_5']) . ', NOW()), ';
}
$sql = trim($sql, '\,');
// ended up doing this
//$sql = substr($sql, 0, strrpos($sql, ',')) . ';';
$stmt = $conn->query($sql);
}
You don't need to escape \ the comma. A better approach might be to construct an array and then implode():
foreach($diseases as $disease){
$sql[] = ' ( "' . filterString($_POST['hospital']). '", "' . filterString($disease['disease']) . '", ' . $week . ', ' . intval($disease['under_5']) . ', ' . intval($disease['over_5']) . ', NOW()), ';
}
$sql = implode(',', $sql);

MySQL query through PHP fix

I'm making a page, where depending on the HTML form data gets inserted/updated/deleted into/from the database.
As far as for the UPDATE goes, I have no more ideas how to fix it. The thing is, that you can update anything you want (for example nazwa_klubu only, if let's say you've changed your old nazwa_klubu and want to keep the new name (nazwa klubu = club name) in the database you type the name that you want to change to into Nazwa klubu in the Wprowadz zmiany form, and then in the second Nazwa klubu you type the name you want to be changed.
I believe it is a minor upgrade to make it all work, without having to put countless if cases, but it's my third day with PHP, so I'm confused.
EDIT: So basically, this function works properly, if all fields are filled. But I want it to work even if we fill some of fields - well, I hope you get my point. What's the point of UPDATE if you can't even use it correctly? Rhetorical Q.
And this is how it currently works:
UPDATE Koncerty SET nazwa_klubu = 'NewClubName', WHERE nazwa_klubu = 'OldClubName' AND
But obviously I want this to work like this:
UPDATE Koncerty SET nazwa_klubu = 'NewClubName' WHERE nazwa_klubu = 'OldClubName'
No matter how many input's I'll fill in this form. The first 5 inputs are responsible for SET side, and the second five are after WHERE clause.
Here's the code of the function
function update($table, $data)
{
$new_klub = 'nazwa_klubu = ' . '\'' . $data[data1] . '\',';
$new_adres = 'adres_klubu = ' . '\'' . $data[data2] . '\',';
$new_zespol = 'nazwa_zespolu = ' . '\'' . $data[data3] . '\',';
$new_ile = 'ilosc_czlonkow_zespolu = ' . '\'' . $data[data4] . '\',';
$new_wystep = 'data_wystepu = ' . '\'' . $data[data5] . '\',';
$klub = 'nazwa_klubu = ' . '\'' . $data[data6] . '\' AND';
$adres = 'adres_klubu = ' . '\'' . $data[data7] . '\' AND';
$zespol = 'nazwa_zespolu = ' . '\'' . $data[data8] . '\' AND';
$ile = 'ilosc_czlonkow_zespolu = ' . '\'' . $data[data9] . '\' AND';
$wystep = 'data_wystepu = ' . '\'' . $data[data10] . '\'';
if (empty($data[data1]) AND empty($data[data2]) AND
empty($data[data3]) AND empty($data[data4]) AND empty($data[data5])) {
echo '<span class="error">Zabezpieczenie: Musisz wpisac jakie zmiany chcesz wprowadzic</span>';
exit;
}
if (empty($data[data6]) AND empty($data[data7]) AND
empty($data[data8]) AND empty($data[data9]) AND empty($data[data10])) {
echo '<span class="error">Zabezpieczenie: Musisz wpisac na czym chcesz dokonac zmian</span>';
exit;
}
if (empty($data[data1])) {
$new_klub = '';
}
if (empty($data[data2])) {
$new_adres = '';
}
if (empty($data[data3])) {
$new_zespol = '';
}
if (empty($data[data4])) {
$new_ile = '';
}
if (empty($data[data5])) {
$new_wystep = '';
}
if (empty($data[data6])) {
$klub = '';
}
if (empty($data[data7])) {
$adres = '';
}
if (empty($data[data8])) {
$zespol = '';
}
if (empty($data[data9])) {
$ile = '';
}
if (empty($data[data10])) {
$wystep = '';
}
$safe_updates = "SET SQL_SAFE_UPDATES = 0";
$sql = "UPDATE $table SET
$new_klub
$new_adres
$new_zespol
$new_ile
$new_wystep
WHERE
$klub
$adres
$zespol
$ile
$wystep
";
echo $new_klub;
mysql_query($safe_updates);
$result = mysql_query($sql);
if (!$result) {
echo '<span class="error">' . mysql_error() . '</span><br>' . $sql . '';
}
else {
echo '<span class="success">Wprowadzono zmiany' . $sql . '</span><br>';
}
}
You shouldn't use stack overflow as somewhere ask questions like "Fix my code".
But, you could just put all your $new_ variables into an array
$new = array(
'klub' => 'nazwa_klubu = ' . '\'' . $data[data1] . '\',',
'adres' => 'adres_klubu = ' . '\'' . $data[data2] . '\',',
);
And then you can implode your array
$sql = implode(', ', $new);
Then you wont get trailing commas. Then use the same logic with AND and you'll get your SQL looking okay.

Error in updating a database table using a mysql query

There is problem with Query :
$outputs = rosy, rosmary; //array1
$filenames =2.2, 3.2; // array 2
Query:
$insert_col = "UPDATE `lil` SET `D`='" .$output. "' WHERE `A`= '" .$filename. "'";// does not work
Instead of the arrays when i give single value, it works very fine, like :
$insert_col = "UPDATE `lil` SET `D`='rosy' WHERE `A`= '2.2'"; // it works
for taking two arrays into the query i have written foreach loop, as follows
foreach (array_combine($outputs, $filenames) as $output => $filename) {
$insert_col = "UPDATE `4` SET `D`='" . $output . "' WHERE `A`= '" . $filename . "'";
echo $insert_col;
}
Please Help !!
try using for loop. get the size of array and run for loop for that no of times
Try
$query = 'UPDATE lil SET D = CASE A';
foreach($arr as $k => $v)
$query .= 'WHEN ' . $k . ' THEN ' . $v;
$query .= ' END';
$insert_col = 'UPDATE 4 SET D = CASE A';
foreach($arr as $output => $filename)
{
$insert_col .= 'WHEN ' . $output . ' THEN ' . $filename;
$insert_col .= ' END';
$insert_result= mysql_query($insert_col)or die("Query failed: " . mysql_error());
dint work #eli

Mutliple querystring parameters to mysql query

I originally had this working:
url: http://server/blah.php?FacilityCode=FT
$facilitycode = mysql_real_escape_string($_GET["FacilityCode"]);
$sql = "SELECT ..." .
"FROM ..." .
"WHERE ..." .
"AND ('" . $facilitycode . "' = '' OR Facility.FacilityCode = '". $facilitycode . "')";
$result = mysql_query($sql);
But I want to change this so that people can submit multiple values in the query strying somehow, ie: http://server/blah.php?FacilityCode=FT,CC,DD,EE
I tried changing the query to an "IN" clause instead of an "equals" but I'm not sure how to get the ' marks around each element.
Use implode() function for IN (...).
$a = array('AB', 'CD', 'EF', 'ZE');
echo "field IN ('" . implode("', '", $a) . "')";
... will output:
field IN ('AB', 'CD', 'EF', 'ZE')
+escape every option you get.
$facilitycode = mysql_real_escape_string($_GET["FacilityCode"]);
$array=explode(',',$facilitycode);
foreach ($array as $a){$output.="'$a',";}
$clause=substr($output,0,-1);
If your trying to create a string which looks like this: 'AB', 'CD', 'EF', 'ZE'
Try this before its placed inside the query:
$facilitycode = preg_replace('/([^,]+)/', '\'$1\'', $facilitycode);
I wrote this based on your query, but still I dont get this part of query "AND ('" . $facilitycode . "' = ''", anyway you need to check if $_GET data have "," and if does explode that variable by "," so that you can add an OR clausule for everything that was separated by "," in $_GET data.
After that just form your query by doing a foreach for every element in exploded array like I done below:
<?php
$facilitycode = $_GET["FacilityCode"];
$facility_number_chk = strpos($facilitycode, ",");
if ($facility_number_chk > -1) {
$facilitycode = explode(",", $facilitycode);
$sql = "SELECT ..." .
"FROM ..." .
"WHERE ..." .
"AND ('" . $facilitycode . "' = ''";
foreach($facilitycode as $facode) {
$facode = mysql_real_escape_string($facode);
$sql .= " OR Facility.FacilityCode = '". $facode . "'";
}
$sql .= "')";
}
else {
$facilitycode = mysql_real_escape_string($facilitycode);
$sql = "SELECT ..." .
"FROM ..." .
"WHERE ..." .
"AND ('" . $facilitycode . "' = '' OR Facility.FacilityCode = '". $facilitycode . "')";
}
$result = mysql_query($sql);
And if there is only one element in $_GET data just do an else like I done with your regular query.
I ended up using a combination of a few of the answers. Basically I exploded on the ",", then did a foreach to add the ' marks and call escape_string, and then imploded it back.
$facilitycodes = $_GET["FacilityCode"];
if ($facilitycodes == '') {
$additionalfilter = '';
}
else {
$facilitycodearray = explode(",", $facilitycodes);
foreach($facilitycodearray as &$facilitycode) {
$facilitycode = "'" . mysql_real_escape_string($facilitycode) . "'";
}
$facilitycodesformatted = implode(",", $facilitycodearray);
$additionalfilter = " AND Facility.FacilityCode IN (" . $facilitycodesformatted . ")";
}
$sql = "SELECT ..." .
"FROM ..." .
"WHERE ..." .
$additionalfilter;

Categories