PDO: Binding Values Wrapped in Single Quotes for MATCH() Query - php

I'm having some difficulty with implementing fulltext() searching into my queries. Now the parameters in the AGAINST() segment won't invoke an error - unless they're wrapped in single-quotes.
Error: PDOStatement::execute(): SQLSTATE[HY093]: Invalid parameter number: number of bound variables does not match number of tokens
Which makes sense as they shouldn't be literals, instead, they should be strings, so the values aren't be bound, right? But in order for this query to function the parameters in AGAINST() must be surrounded by single quotes.
MATCH(features) AGAINST(':feature_set :feature_unset')
$bind_array[":feature_set"] = $feature_set;
$bind_array[":feature_unset"] = $feature_unset;
$stmt = $conn->prepare($query);
$stmt->execute($bind_array);
:feature_set :feature_unset
Would return a string formatted like so:
+Softaculous -Free Domain -Site Builder -Fantastico
Does anyone know of a solution for this? Much appreciated, thanks!

Try it this way
$query = '... MATCH(features) AGAINST(:against IN BOOLEAN MODE)';
$bind_array[":against"] = $feature_set . ' ' . $feature_unset;
$stmt = $conn->prepare($query);
$stmt->execute($bind_array);
Here is SQLFiddle demo.

Related

PHP-PDO_PGSQL - SQLSTATE[HY093]: Invalid parameter number

It's all the day that I'm stuck with this simple prepared statement:
// $conn it's my PDO Object
// and $intervention my params'array
$s = $conn->prepare("INSERT INTO intervention(firm_id,category,subject,amount,start_date,end_date) VALUES(:firm_id,':category',':subject',:amount,':start_date',':end_date')");
$result = $s->execute(array(
'firm_id' => $firm_id ,
'category' => $intervention["category"] ,
'subject' => $intervention["subject"] ,
'amount'=> $intervention["amount"] ,
'start_date'=> $intervention["start_date"],
'end_date'=>$intervention["end_date"]
));
The execute will give me:
Warning: PDOStatement::execute(): SQLSTATE[HY093]: Invalid parameter number: :category
Can someone help me understand what is wrong with this simple code?
In this part of the query:
VALUES(:firm_id,':category',
:category is taken as a literal string and not as a parameter name, because of the quotes enclosing it.
There should be no quotes around parameter names, as in:
...VALUES(:firm_id, :category,...
There is the same mistake for the other non-numeric parameters of the rest of the query.
Parameters name should not have a quotes. The prepared statement will do the replacement properly. Pay attention too at the number of parameters you write in the query and what will you bind on execute method.

pg_query_params return error: bind message supplies 2 parameters, but prepared statement "" requires 1

$Query = pg_query_params($db, 'SELECT username FROM users WHERE id = $1 AND password=(crypt(\'$2\',password)) LIMIT 1', array(33,'thepassword'));
"bind message supplies 2 parameters, but prepared statement "" requires 1"
The problem seem around the '$2' parameter, heredoc string doesnt works.
Suggestions ?
Single quotes are used in SQL for string literals. That means that this:
'$2'
is just a string that contains the characters $ and 2 rather than a placeholder. If you want a placeholder, you need to leave out the quotes:
$Query = pg_query_params($db, '...password=(crypt($2,password))...', array(33,'thepassword'));
That gives you the placeholder rather than the string literal.

MySQL REGEX with prepared statement: "?" being misunderstood

I've consulted this question for this problem, but couldn't seem to see the answer.
I have a prepared statement with a ? placeholder for a param I'm binding. Problem is, MySQL doesn't seem to like this because it's inside a REGEX block, like so:
$sql = 'SELECT id FROM teams WHERE name REGEXP "^(?)"';
$stmt = $db->prepare($sql);
$stmt->bind_param('s', implode('|', $letters));
This throws:
"Got error 'repetition-operator operand invalid' from regexp"
Is there a way of escaping the ? or something?
[EDIT]
Based on the comment below, I tried:
$sql = 'SELECT id FROM teams WHERE name REGEXP "^(:letters)"';
$stmt = $db->prepare($sql);
$stmt->bind_param(':letters', implode('|', $letters));
Now I get the error
"Warning: mysqli_stmt::bind_param(): Number of elements in type definition string doesn't match number of bind variables"
Interestingly, I note I'm using bind_param() but the PHP docs say bindParam(). For me, the latter is an undefined method.

How to deliver params for SELECT with IN in mysqli

My prepared query looks like this:
$sql = "SELECT $t1.id FROM $t1 WHERE $t1.name IN (?)";
When I try:
$stmt = Sql::$select->prepare($sql);
$string="'aaa','bbb','ccc'";
$stmt->bind_param('s', $string);
...it doesn't return the expected results. It treats the string as one name and not many separate names. How can it be solved?
The rest of the function:
$stmt->execute();
$stmt->store_result();
return $stmt;
Try altering query like this
$sql = "SELECT $t1.id FROM $t1 WHERE FIND_IN_SET($t1.name, ?)>0";
$stmt = Sql::$select->prepare($sql);
$string='aaa,bbb,ccc';
$stmt->bind_param('s', $string);
And this solution is not reliable.
Please see FIND_IN_SET(str,strlist)
Correct method is to use separate placeholders for each element in the IN statement.
Another suggestion, get rid of the IN statement and run through a loop in php to generate the query and bind the params.
The problem is that the bind_param function with 's' threats the parameter as a single string, so it is basically transforming your query to:
"SELECT $t1.id FROM $t1 WHERE $t1.name IN (''aaa','bbb','ccc'')";
A quick fix would be to change the string variable to:
$string="aaa','bbb','ccc";
Note: without the leading/trailing quotes (you can make this using trim($string, "'")
You may also try inverting the quotes: using " instead of ' if this does not work.
A more reliable and robust solution is to change the query to incude a ? for each string (using arrays with expolode() / implode() php functions.

PHP PDO unnamed bound variables does not match number of tokens

I try to make a specific MySQL query work with PDO unnamed placeholders, and I suspect the problem might have something to do with the ' ' around the third question mark, but I just can't figure it out.
I get the exception:
'Invalid parameter number: number of bound variables does not match number of tokens'
Here's the relevant parts of the function, try-catch and the like removed for ease of reading. Function is called with $column and $mytype containing simple alphanumeric strings that worked fine with the earlier pure MySQL code, before I changed it to PDO-MySQL, so they should be ok.
define('SQL_TABLE', 'mytable');
function listThem($column, $mytype) {
# These lines succeed
$databaseHandle = new PDO('mysql:host=' . SQL_HOST . ';dbname=' . SQL_DATABASE, SQL_USER, SQL_PASSWORD);
$databaseHandle->setAttribute( PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION );
# The following three lines cast the exception
$input = array(SQL_TABLE, $column, $mytype);
$statementHandle = $databaseHandle->prepare('SELECT *, ((100 * likes) / (dislikes + 1)) '
. "AS rating FROM ? WHERE ? REGEXP '?' ORDER BY rating DESC;");
$statementHandle->execute($input);
# . . . more code here
}
You can't bind table or field names as arguments using prepared statements. Parameter binding is only for values.
You will need to build those into the string. Just make sure you filter the values properly.
Also, you should not need to use '?', bound arguments take care of this.

Categories