Proper way to pass %like% param with PDO? - php

Here's the query below,
public function getSearchResult($searchString){
$stmt = $this->conn->prepare("SELECT t.* FROM company t WHERE t.company_name like ? ");
$stmt->bind_param("i", "%".$searchString."%");
$stmt->execute();
$tasks = $stmt->get_result();
$stmt->close();
return $tasks;
}
Error I am getting is
Fatal error: Cannot pass parameter 2 by reference in
I guess I am doing the like param incorrectly (as it works for where = condition). I am pretty new to slim, any help?

You have to form the string before you can use it in bind_param()
public function getSearchResult($searchString){
$search = '%'. $searchString . '%';
$stmt = $this->conn->prepare("SELECT t.* FROM company t WHERE t.company_name like ? ");
$stmt->bind_param("s", $search);
$stmt->execute();
$tasks = $stmt->get_result();
$stmt->close();
return $tasks;
}
In addition it looks like you're passing a string, not an integer, make sure you set the type to "s"

You need to set where your i variable goes.
$stmt = $this->conn->prepare("SELECT t.* FROM company t WHERE t.company_name LIKE :i ");
$stmt->bind_param(":i", "%$searchString%", PDO::PARAM_STR);
Here is an example in php.net

<?php
public function getSearchResult($searchString){
$stmt = $this->conn->prepare("SELECT t.* FROM company t WHERE t.company_name like ? ");
$stmt->bind_param("s", "%$searchString%",PDO::PARAM_STR);
$stmt->execute();
$tasks = $stmt->get_result();
$stmt->close();
return $tasks;
}
Search string in where condition so it would be s and add PDO::PARAM_STR

Related

how to use prepared statement on php function that have multiple table and small query? [duplicate]

This is my code but it dosn't work:
$param = "%{$_POST['user']}%";
$stmt = $db->prepare("SELECT id,Username FROM users WHERE Username LIKE ?");
$stmt->bind_param("s", $param);
$stmt->execute();
$stmt->bind_result($id,$username);
$stmt->fetch();
This code it doesn't seem to work. I have searched it a lot.
Also it may return more than 1 row.
So how can I get all the results even if it returns more than 1 row?
Here's how you properly fetch the result
$param = "%{$_POST['user']}%";
$stmt = $db->prepare("SELECT id, username FROM users WHERE username LIKE ?");
$stmt->bind_param("s", $param);
$stmt->execute();
$result = $stmt->get_result();
while ($row = $result->fetch_assoc()) {
echo "Id: {$row['id']}, Username: {$row['username']}";
}
or, if you prefer the old fetch and bind_result syntax, you can also do:
$param = "%{$_POST['user']}%";
$stmt = $db->prepare("SELECT id,username FROM users WHERE username LIKE ?");
$stmt->bind_param("s", $param);
$stmt->execute();
$stmt->bind_result($id,$username);
while ($stmt->fetch()) {
echo "Id: {$id}, Username: {$username}";
}
I got the answer directly from the manual here and here.
From comments it is found that LIKE wildcard characters (_and %) are not escaped by default on Paramaterised queries and so can cause unexpected results.
Therefore when using "LIKE" statements, use this 'negative lookahead' Regex to ensure these characters are escaped :
$param = preg_replace('/(?<!\\\)([%_])/', '\\\$1',$param);
As an alternative to the given answer above you can also use the MySQL CONCAT function thus:
$stmt = $db->prepare("SELECT id,Username FROM users WHERE Username LIKE CONCAT('%',?,'%') ");
$stmt->bind_param("s", $param);
$stmt->execute();
PDO named placeholder version:
$stmt = $db->prepare("SELECT id,Username FROM users WHERE Username LIKE CONCAT('%',:var,'%') ");
$stmt->bind_param("s", ['var'=>$param]);
$stmt->execute();
Which means you do not need to edit your $param value but does make for slightly longer queries.

Can someone please explain why I get this error when preparing SQL statement using prepare() and bind_param? [duplicate]

This is my code but it dosn't work:
$param = "%{$_POST['user']}%";
$stmt = $db->prepare("SELECT id,Username FROM users WHERE Username LIKE ?");
$stmt->bind_param("s", $param);
$stmt->execute();
$stmt->bind_result($id,$username);
$stmt->fetch();
This code it doesn't seem to work. I have searched it a lot.
Also it may return more than 1 row.
So how can I get all the results even if it returns more than 1 row?
Here's how you properly fetch the result
$param = "%{$_POST['user']}%";
$stmt = $db->prepare("SELECT id, username FROM users WHERE username LIKE ?");
$stmt->bind_param("s", $param);
$stmt->execute();
$result = $stmt->get_result();
while ($row = $result->fetch_assoc()) {
echo "Id: {$row['id']}, Username: {$row['username']}";
}
or, if you prefer the old fetch and bind_result syntax, you can also do:
$param = "%{$_POST['user']}%";
$stmt = $db->prepare("SELECT id,username FROM users WHERE username LIKE ?");
$stmt->bind_param("s", $param);
$stmt->execute();
$stmt->bind_result($id,$username);
while ($stmt->fetch()) {
echo "Id: {$id}, Username: {$username}";
}
I got the answer directly from the manual here and here.
From comments it is found that LIKE wildcard characters (_and %) are not escaped by default on Paramaterised queries and so can cause unexpected results.
Therefore when using "LIKE" statements, use this 'negative lookahead' Regex to ensure these characters are escaped :
$param = preg_replace('/(?<!\\\)([%_])/', '\\\$1',$param);
As an alternative to the given answer above you can also use the MySQL CONCAT function thus:
$stmt = $db->prepare("SELECT id,Username FROM users WHERE Username LIKE CONCAT('%',?,'%') ");
$stmt->bind_param("s", $param);
$stmt->execute();
PDO named placeholder version:
$stmt = $db->prepare("SELECT id,Username FROM users WHERE Username LIKE CONCAT('%',:var,'%') ");
$stmt->bind_param("s", ['var'=>$param]);
$stmt->execute();
Which means you do not need to edit your $param value but does make for slightly longer queries.

How to fetch data from database using prepare statement in php?

I have a database in which I have user_id & associated_id.There can be multiple associated_id for a single user_id. Now I want to fetch all the associated_ids into a single array. I have tried this method but don't know how to get them in array.
$stmt = $this->conn->prepare("SELECT * FROM my_contacts WHERE user_id = ?");
$stmt->bind_param("s", $user_id);
if ($stmt->execute())
{
while ($stmt->fetch())
{
//what to write here
}
//echo var_dump($user);
$stmt->close();
}
Try this:
$stmt = $mysqli->prepare("SELECT associated_id FROM my_contacts WHERE user_id = ?")) {
$stmt->bind_param('s', $user_id); // Bind "$user_id" to parameter.
$stmt->execute(); // Execute the prepared query.
$stmt->store_result();
// get variables from result.
$stmt->bind_result($associated_id);
$stmt->fetch();
The results will be stored in the $associated_id array.
You can bind parameters like this and use fetchall method to get all the results in a array
$stmt = $this->conn->prepare("SELECT * FROM my_contacts WHERE user_id = :user_id");
$stmt->bind_param(":user_id", $user_id, PDO::PARAM_INT);
if ($stmt->execute())
{
$result = $stmt->fetchall(PDO::FETCH_ASSOC);
//echo var_dump($user);
$stmt->close();
}
According to your code you used mysqli.
$stmt = $this->conn->prepare("SELECT * FROM my_contacts WHERE user_id = ?");
if($stmt->execute()){
$result = $stmt->get_result();
if($result->nom_rows > 0){
while($row = $result->fetch_assoc()){
var_dump($row)
}
}else{
echo "Sorry NO data found";
}
}else{
echo "Some thing is wrong";
}
here you can't used $stmt->bind_result(); instead of use $stmt->get_result()
$stmt->bind_result(); is only used when you define field in select query
with * you need to used $stmt->get_result()
refer this link for more information
Example of how to use bind_result vs get_result

How can I with mysqli make a query with LIKE and get all results?

This is my code but it dosn't work:
$param = "%{$_POST['user']}%";
$stmt = $db->prepare("SELECT id,Username FROM users WHERE Username LIKE ?");
$stmt->bind_param("s", $param);
$stmt->execute();
$stmt->bind_result($id,$username);
$stmt->fetch();
This code it doesn't seem to work. I have searched it a lot.
Also it may return more than 1 row.
So how can I get all the results even if it returns more than 1 row?
Here's how you properly fetch the result
$param = "%{$_POST['user']}%";
$stmt = $db->prepare("SELECT id, username FROM users WHERE username LIKE ?");
$stmt->bind_param("s", $param);
$stmt->execute();
$result = $stmt->get_result();
while ($row = $result->fetch_assoc()) {
echo "Id: {$row['id']}, Username: {$row['username']}";
}
or, if you prefer the old fetch and bind_result syntax, you can also do:
$param = "%{$_POST['user']}%";
$stmt = $db->prepare("SELECT id,username FROM users WHERE username LIKE ?");
$stmt->bind_param("s", $param);
$stmt->execute();
$stmt->bind_result($id,$username);
while ($stmt->fetch()) {
echo "Id: {$id}, Username: {$username}";
}
I got the answer directly from the manual here and here.
From comments it is found that LIKE wildcard characters (_and %) are not escaped by default on Paramaterised queries and so can cause unexpected results.
Therefore when using "LIKE" statements, use this 'negative lookahead' Regex to ensure these characters are escaped :
$param = preg_replace('/(?<!\\\)([%_])/', '\\\$1',$param);
As an alternative to the given answer above you can also use the MySQL CONCAT function thus:
$stmt = $db->prepare("SELECT id,Username FROM users WHERE Username LIKE CONCAT('%',?,'%') ");
$stmt->bind_param("s", $param);
$stmt->execute();
PDO named placeholder version:
$stmt = $db->prepare("SELECT id,Username FROM users WHERE Username LIKE CONCAT('%',:var,'%') ");
$stmt->bind_param("s", ['var'=>$param]);
$stmt->execute();
Which means you do not need to edit your $param value but does make for slightly longer queries.

pass FILTER_SANITIZE_STRING

I have a this query:
$query="select * from news where news_id = (select max(news_id) from news where news_id< $id)";
for execute I use class. in this class
public function query($query)
{
$this->_query = filter_var($query, FILTER_SANITIZE_STRING);
$stmt = $this->_prepareQuery();
$stmt->execute();
$results = $this->_dynamicBindResults($stmt);
return $results;
}
Is there any way that < signal is not filtered?
Unfortunately, the whole idea is wrong. FILTER_SANITIZE_STRING won't help even slightest. Let alone it just breaks your SQL.
To protect SQL from injection you must use prepared statements. So instead of adding a variable directly to the query, add a question mark. And then put this variable into execute like this
public function query($query, $params)
{
$stmt = $this->mysqli->prepare();
$types = $types ?: str_repeat("s", count($params));
$stmt->bind_param($types, ...$params);
$stmt->execute();
return $stmt->get_result();
}
then just use it this way
$query="select * from news where news_id = (select max(news_id) from news where news_id<?)";
$data = $db->query($query, [$id])->fetch_all(MYSQLI_ASSOC)

Categories