Why is my PDO query using LIKE & LIMIT not working? - php

I am making a search box feature that has this query:
$query="SELECT * FROM article WHERE title LIKE ? OR description LIKE ?";
Then in a foreach loop, I make this array:
$params[]= "%".$keyword."%";
$params[]= "%".$keyword."%";
Then I execute:
$stmt=$cxn->prepare($query);
$stmt->execute($params);
This WORKS, but...
If, after the foreach loop, I want to add " LIMIT ?,?", I do this:
$query.=" LIMIT ?, ?";
$params[]=$row_number;
$params[]=$items_per_page;
Then I execute the script, and it throws this Fatal Error:
PHP Fatal error: Uncaught exception 'PDOException' with message
'SQLSTATE[42000]: Syntax error or access violation: 1064 You have an error in your SQL syntax;
check the manual that corresponds to your MySQL server version for the right syntax
to use near ''0', '2'' at line 1' in ..../index.php:247
Stack trace:
#0 .../index.php(247): PDOStatement->execute(Array)
#1 {main}
thrown in ..../index.php on line 247
I tried to do add apostrophes around the keywords: $params= "'%".$keyword."%'";
But this didn't work.
Also, I tried the exact same query inside PHPMyAdmin and it worked.
Does anyone know why this is throwing an error?
Thanks a lot in advance.

Update:
$query="SELECT * FROM article WHERE title LIKE ? OR description LIKE ?";
$query.=" LIMIT ?, ?";
$stmt=$cxn->prepare($query);
$stmt->bindValue(1, "%".$keyword."%");
$stmt->bindValue(2, "%".$keyword."%");
$stmt->bindValue(3, $row_number, PDO::PARAM_INT);
$stmt->bindValue(4, $items_per_page, PDO::PARAM_INT);
$stmt->execute();

The reason LIKE isn't working, is because when you use bind parameters with LIKE it's treating '%value%' as a string.
You're going to have to use:
$query="SELECT * FROM article WHERE title LIKE CONCAT('%',?,'%') OR description LIKE CONCAT('%',?,'%')";

I think you need to convert the variable you have passed in your limit clause. see this ...to use near ''0', '2'' there are single quotes on the values in the LIMIT clause
try
$query.=" LIMIT ?, ?";
$params[] = intval($row_number);
$params[] = intval($items_per_page);

Related

Syntax error while executing a sql request with parameters in symfony?

I have a just simple problem I guess, I followed Symfony 4.3 documentation, and tried to do do exactly what they have done to execute a SQL request, but I get an error when passing parameters in the execute method, but I get no error while executing the same code but without passing parameters to the request.
I tried this and it worked:
$conn = $this->getDoctrine()->getManager()->getConnection();
$sql = '
SELECT * FROM question_comment WHERE question=2 LIMIT 0, 3';
$stmt = $conn->prepare($sql);
$stmt->execute();
var_dump($stmt->fetchAll());
But this does not work, I get a syntax error:
$question = $request->query->get('question');
$row = $request->query->get('row');
$question = intval($question);
$beggining = intval($row*3);
$conn = $this->getDoctrine()->getManager()->getConnection();
$sql = '
SELECT * FROM question_comment WHERE question=:question LIMIT :beggining , 3';
$stmt = $conn->prepare($sql);
$stmt->execute(['question' => $question, 'beggining' => $beggining]);
var_dump($stmt->fetchAll());
This is the error:
An exception occurred while executing ' SELECT * FROM question_comment
WHERE question= :question LIMIT :beggining , 3' with params [2, 0]:
SQLSTATE[42000]: Syntax error or access violation: 1064 You have an
error in your SQL syntax; check the manual that corresponds to your
MySQL server version for the right syntax to use near ''0' , 3' at
line 1
Here is what I have followed, I did exactly what was there, but its not working.
I tried this solution to bind my parameters but it did not work too :
$sql = '
SELECT * FROM question_comment WHERE question=:question LIMIT :beggining , 3';
$stmt = $conn->prepare($sql);
$stmt->bindParam(':question', $question, \PDO::PARAM_INT);
$stmt->bindParam(':beginning', $beginning, \PDO::PARAM_INT);
$stmt->execute();
And I got this :
An exception occurred while executing ' SELECT * FROM question_comment
WHERE question=:question LIMIT :beggining , 3' with params [2, null]:
SQLSTATE[HY093]: Invalid parameter number: parameter was not defined
alternative way to bind parameters is using this.
$stmt->bindParam(':question', $question, PDO::PARAM_STR);
$stmt->bindParam(':beginning', $beginning, PDO::PARAM_INT);
or to make it sure you binded the $beginning parameter, cast it to int.
$stmt->bindValue(':beginning', (int)trim($beginning), PDO::PARAM_INT);
or if you want to stick on your existing code.
$stmt->execute(['question' => $question, 'beggining' => (int)trim($beggining)]);

PDO SQLSTATE[42000] on simple select query

Im just new with programming in OOP, so im writing a function but it gives an error, i think im using PDO wrong, actually i now it for sure, but i dont now how to fix it. This is my code im using currently:
public function takedrugs($soort, $hoeveelheid, $id){
$conn = $this->conn;
$drugsophalen = $conn->prepare('SELECT * FROM gebruikers WHERE id=:id');
$drugsophalen->execute(array(':id' => $id));
$result = $drugsophalen->fetch();
$huidigdrugs = $result[$soort];
if($huidigdrugs >= $hoeveelheid){
//Voldoende drugs dus drugs afnemen
$drugsafnemen = $conn->prepare('UPDATE gebruikers
SET :soort = :soort - :hoeveelheid,
WHERE id = :id');
$drugsafnemen->execute(array(
':soort' => $soort,
':hoeveelheid' => $hoeveelheid,
':id' => $id));
} else {
return false;
}
}
So when i use this function i get an error, its all about the SET :soort = :soort - :hoeveelheid.
This is the error i get:
Fatal error: Uncaught exception 'PDOException' with message
'SQLSTATE[42000]: Syntax error or access violation: 1064 You have an
error in your SQL syntax; check the manual that corresponds to your
MySQL server version for the right syntax to use near ''Cannabis' =
'Cannabis' - '2000', WHERE id ' at line 2' in
I hope there are some people who now how to fix it since i dont :S
Thanks in advance!
You CANT bind column names SEE Complex Cases in PDO info.
Also as Jason states about lazy binding use bindParam OR bindValue
TRY
$drugsafnemen = $conn->prepare('UPDATE gebruikers
SET $soort = $soort - :hoeveelheid,
WHERE id = :id');
$drugsafnemen->bindParam(':hoeveelheid', $hoeveelheid, PDO::PARAM_INT);
$drugsafnemen->bindParam(':id', $id, PDO::PARAM_INT);
$drugsafnemen->execute();
You have two problems:
First, by using execute() all your values are being treated as a string. This results in the syntax error:
UPDATE gebruikers SET field = 'Cannabis' - '2000' ...
I assume this is not your intention. Instead, use bindParam() so you can define these parameters as integers.
$drugsafnemen->bindParam(':soort', $soort, PDO::PARAM_INT);
Second, you should are setting the column name dynamically (:soort). As such, it too is getting interpolated with $soort, which is probably not your intention.

PDO order by throws error

I am confused.
This is working:
$sql = 'SELECT * FROM TABLE ORDER BY DATEOFUPLOAD DESC';
$stmt = $conn->prepare($sql);
$stmt->execute();
This is not:
$sql = 'SELECT * FROM TABLE ORDER BY DATEOFUPLOAD :orderbydateofupload';
$stmt = $conn->prepare($sql);
$stmt->bindValue(':orderbydateofupload', $orderbydateofupload, PDO::PARAM_STR);
$stmt->execute();
I have checked and set $orderbydateofupload by $orderbydateofupload='DESC', so it's definitely not null.
I get an error to the last line ($stmt->execute()):
Fatal error: Uncaught exception 'PDOException' with message 'SQLSTATE[42000]: Syntax error or access violation: 1064 You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near ''DESC'' at line 1' in /home/gh6534/public_html/query.php:77 Stack trace: #0 /home/gh6534/public_html/query.php(77): PDOStatement->execute() #1 {main} thrown in /home/gh6534/public_html/query.php on line 77
I also tried to use the column as parameter:
$sort = 'DATEOFUPLOAD';
$sql = 'SELECT * FROM TABLE ORDER BY :sort :orderbydateofupload';
$stmt = $conn->prepare($sql);
$stmt->bindParam(':sort', $sort);
$stmt->bindParam(':orderbydateofupload', $orderbydateofupload);
$stmt->execute();
This does not throw an exception, but all items are queried without any sorting. What's wrong?
Try this
$orderbydateofupload = 'ASC'; //Or DESC
if($orderbydateofupload == 'DESC')
$sql = 'SELECT * FROM TABLE ORDER BY DATEOFUPLOAD DESC';
else
$sql = 'SELECT * FROM TABLE'
You can't bind identifiers with PDO because prepared statements can be used only with data, but not with identifiers or syntax keywords.
So, you have to use whitelisting, as shown in the example I posted before
That's why in my own class I use identifier placeholder, which makes whole code into one line (when you need to set the order by field only):
$data = $db->getAll('SELECT * FROM TABLE ORDER BY ?n',$sort);
but with keywords whitelisting is the only choice:
$order = $db->whiteList($_GET['order'],array('ASC','DESC'),'ASC');
$data = $db->getAll("SELECT * FROM table ORDER BY ?n ?p", $sort, $order);

How to add variable values inside pdo->query

I want to upgrade my current code which is constantly sql injected with PDO.
Currently I'm stuck with using a variable inside a PDO query.
If I have two arguments like this
$rowsPerPage = 3;
// by default we show first page
$pageNum = 1;
if (isset($_GET['page'])) {
$pageNum = mysql_real_escape_string($_GET['page']);
}
$offset = ($pageNum - 1) * $rowsPerPage;
And I have query like this
$STH = $DBH->query("SELECT News.ID, LEFT(NewsText,650), Title, AID, Date, imgID," .
"DATE_FORMAT(Date, '%d.%m.%Y.') as formated_date " .
"FROM News, Categories, NewsCheck WHERE Name LIKE '%News - Block%' AND CID=Categories.ID AND JID=News.ID ".
"ORDER BY `Date` DESC LIMIT $offset, $rowsPerPage");
PDO reports an error in last line of the query ORDER BY
When I replace these line with
"ORDER BY Date DESC LIMIT3,3"); everything work.
So how to add variable values inside PDO::query ?
Updated:
Thanks to answer bellow I have updated my code like this
$STH = $DBH->prepare("SELECT News.ID, LEFT(NewsText,650), Title, AID, Date, imgID," .
"DATE_FORMAT(Date, '%d.%m.%Y.') as formated_date " .
"FROM News, Categories, NewsCheck WHERE Name LIKE '%News - Block%' AND CID=Categories.ID AND JID=News.ID ".
"ORDER BY `Date` DESC LIMIT :offset, :rowsPerPage;");
$STH->bindParam(':offset', $offset, PDO::PARAM_STR);
$STH->bindParam(':rowsPerPage', $rowsPerPage, PDO::PARAM_STR);
$STH->execute();
But error occured:
Fatal error: Uncaught exception 'PDOException' with message
'SQLSTATE[42000]: Syntax error or access violation: 1064 You have an
error in your SQL syntax; check the manual that corresponds to your
MySQL server version for the right syntax to use near ''-3', '3'' at
line 1' in /pdo/test.php:42 Stack trace: #0
/pdo/test.php(42): PDOStatement->execute() #1 {main} thrown in
/pdo/test..
Second Update
Changed from PARAM_STR TO PARAM_INT like this
$STH->bindParam(':offset', $offset, PDO::PARAM_INT);
$STH->bindParam(':rowsPerPage', $rowsPerPage, PDO::PARAM_INT);
Everything works.
You want to use prepared statements and query parameters like the following:
$sth = $dbh->prepare('SELECT your_column FROM your_table WHERE column < :parameter');
$sth->bindParam(':parameter', $your_variable, PDO::PARAM_STR);
$sth->execute();
Using variables directly in your query will not protect you from SQL injections, even if you are using PDO. Parameters are the only good way to prevent them.

MySQLi query in PHP isn't working right, is there a way to get the exact query?

Is there a way to get the query after MySQLi prepares it? My query is messing up:
$query = "UPDATE event SET group=?, boxed=?, name=?, location=?, time=?, day=?, type=? WHERE id=? LIMIT 1";
if($stmt = $db -> prepare($query))
{
$stmt -> bind_param("iisssssi", $group, $boxed, $name, $location, $time, $day, $etype, $id);
$stmt -> execute();
$stmt -> close();
}
else
Error message:
You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'group=?, boxed=?, name=?, location=?, time=?, day=?, type=? WHERE id=? LIMIT 1' at line 1
Variable group is an int, boxed is an int, the rest are strings, and id is an int.
You're using the SQL reserved word "group" as one of the column names.
No, there is no way to get the query after MySQLi prepares it, because there is no query in the usual sense. The string goes to the server as you wrote it - with question marks. That's an annoying disadvantage of the prepared statements.

Categories