MySqli LIKE query not matching number of parameter - php

The following query is resulting in the browser printing a
"does not match number of parameters"
type of error.
Why is this happening?
When I replace with LIKE '%".$country."%' and get rid of the bind_param it does not bring up any errors.
$query = "
SELECT * from (
SELECT link
FROM items
WHERE countries LIKE '%?%'
ORDER BY value DESC
LIMIT 10
) T ORDER BY RAND()
LIMIT 1
";
if ($statement = $mysqli->prepare($query))
{
$statement->bind_param("s", $country);
$statement->execute();
$statement->store_result();
$statement->bind_result($link);
$statement->fetch();
$statement->free_result();
$statement->close();
}
I'd like to prepare the statement instead of inserting raw data into the query.

% must be part of the value :
$query = "
SELECT * from (
SELECT link
FROM items
WHERE countries LIKE ?
ORDER BY value DESC
LIMIT 10
) T ORDER BY RAND()
LIMIT 1
";
if ($statement = $mysqli->prepare($query))
{
$statement->bind_param("s","%".$Country."%");
$statement->execute();
$statement->store_result();
$statement->bind_result($link);
$statement->fetch();
$statement->free_result();
$statement->close();
}

You can use it like
$country = "%{$country}%";
$query = "
SELECT * from (
SELECT link
FROM items
WHERE countries LIKE ?
ORDER BY value DESC
LIMIT 10
) T ORDER BY RAND()
LIMIT 1
";
if ($statement = $mysqli->prepare($query))
{
$statement->bind_param("s", $country);
$statement->execute();
$statement->store_result();
$statement->bind_result($link);
$statement->fetch();
$statement->free_result();
$statement->close();
}

Related

PHP Prepared Object Query Not Returning Any Data [duplicate]

This question already has answers here:
How can I prevent SQL injection in PHP?
(27 answers)
Closed 3 years ago.
I have some PHP code that takes a post request as input to a prepared statement.
It is not returning any information.
There are no errors.
I have tried hard coding the variables that are passed to the prepared object to no avail.
If I manually query the database with the desired query, output is received.
What am I missing here? What can I do to get output?
Heres my code:
<?php
$username = "user";
$password = "ultrasecurepassword";
try {
$pdo = new PDO('mysql:unix_socket=/run/mysql/mysql.sock;dbname=news', $username, $password);
} catch (PDOException $e) {
print "Error!: " . $e->getMessage() . "<br/>";
die();
}
$query = "SELECT * FROM newsdb ORDER BY pubdate DESC LIMIT 250";
if(!empty($_POST['search'])){
$termobusca = htmlspecialchars($_POST['search']);
$tipobusca = htmlspecialchars($_POST['searchtype']);
if($tipobusca == "title"){
$stmt = $pdo->prepare("SELECT * from newsdb where title like '%:term%' ORDER BY pubdate DESC limit 5000;");
}
else {
$stmt = $pdo->prepare("SELECT * from newsdb where pubdate like '%:term%' ORDER BY pubdate DESC limit 5000;");
}
$stmt->bindParam(1, $termobusca);
}
else {
$stmt = $pdo->prepare("SELECT * FROM newsdb ORDER BY pubdate DESC LIMIT 250");
}
$stmt->execute();
while($row = $stmt->fetch()){
print_r($row);
}
$pdo = null;
?>
I have seen this question before somehow
try this please
if($tipobusca == "title"){
$stmt = $pdo->prepare("SELECT * from newsdb where title like :term ORDER BY pubdate DESC limit 5000;");
}
else {
$stmt = $pdo->prepare("SELECT * from newsdb where pubdate like :term ORDER BY pubdate DESC limit 5000;");
}
$term = '%'.$termobusca.'%';
$stmt->bindParam(':term', $term, PDO::PARAM_STR);

Adding a PHP Prepared statement to a SELECT statement

I need to create a Prepared statement and incorporate it into a SELECT statement, as shown below. I am happy with creating the Prepared statement for line 1, but I need to include the result in the SELECT statement in line 2 as I cannot use the WHERE option because of line 4 (function of a search)
So, I guess I need some insight into how I can combine both the SELECT and prepared statement into line 2.
//$sql = "SELECT * FROM customer_crm WHERE sales_agent = '".$username."'";
$sql = "SELECT * FROM customer_crm";
$query = isset($_GET['query'])?('%'.$_GET['query'].'%'):'%';
$sql .= "WHERE company_name LIKE :query OR email LIKE :query OR
date_followup LIKE :query "; //is needed for a search function
$start = (($paginator->getCurrentPage()-1)*$paginator->itemsPerPage);
$length = ($paginator->itemsPerPage);
$sql .= "ORDER BY date_followup DESC limit :start, :length ";
$sth = $pdo->prepare($sql);
$sth->bindParam(':start',$start,PDO::PARAM_INT);
$sth->bindParam(':length',$length,PDO::PARAM_INT);
$sth->bindParam(':query',$query,PDO::PARAM_STR);
$sth->execute();
foreach ($sth->fetchAll(PDO::FETCH_ASSOC) as $row1)
You can't have two WHERE clauses. The second one should be AND to combine those conditions into the query.
$sql = "SELECT * FROM customer_crm WHERE sales_agent = :username";
$query = isset($_GET['query'])?('%'.$_GET['query'].'%'):'%';
$sql .= " AND (company_name LIKE :query OR email LIKE :query OR
date_followup LIKE :query)"; //is needed for a search function
$start = (($paginator->getCurrentPage()-1)*$paginator->itemsPerPage);
$length = ($paginator->itemsPerPage);
$sql .= " ORDER BY date_followup DESC limit :start, :length ";
$sth = $pdo->prepare($sql);
$sth->bindParam(':username', $username, PDO::PARAM_STR);
$sth->bindParam(':start',$start,PDO::PARAM_INT);
$sth->bindParam(':length',$length,PDO::PARAM_INT);
$sth->bindParam(':query',$query,PDO::PARAM_STR);
$sth->execute();

Pagination 2nd page not displaying

Pagination works fine when I don't use the WHERE statement in my SELECT statement. For some reason as soon as I add additional requests in the SELECT statement, only the 1st pagination page works. So it seems like the variable data is lost after the first page is displayed. Below is some of the code:-
<?php
include 'database.php';
include 'paginator.php';
$pdo = Database::connect();
$paginator = new Paginator();
$sql = "SELECT count(*) FROM customer_crm ";
$paginator->paginate($pdo->query($sql)->fetchColumn());
$query = $_GET["query"];
if (isset($query)) {
($_GET['query'])?('%'.$_GET['query'].'%'):'%';
$sql = "SELECT * FROM customer_crm WHERE firstname LIKE :query OR email LIKE :query OR telephone LIKE :query ";
}
else {
$start = (($paginator->getCurrentPage()-1)*$paginator->itemsPerPage);
$length = ($paginator->itemsPerPage);
//$sql = "SELECT * FROM customer_crm WHERE customer_group_id = $input OR date_followup= CURDATE() ORDER BY customer_group_id DESC limit $start, $length ";
$sql = "SELECT * FROM customer_crm ORDER BY date_followup DESC limit $start, $length ";
//$sql = "SELECT * FROM customer_crm WHERE customer_group_id = $input ORDER BY date_followup DESC limit $start, $length ";
}
$sth = $pdo->prepare($sql);
$sth->bindParam(':start',$start,PDO::PARAM_INT);
$sth->bindParam(':length',$length,PDO::PARAM_INT);
$sth->bindParam(':query',$query,PDO::PARAM_STR);
$sth->execute();
foreach ($sth->fetchAll(PDO::FETCH_ASSOC) as $row) {
Without knowing which Paginator are we talking about, I could only advise you to do something like
include 'database.php';
include 'paginator.php';
$pdo = Database::connect();
$paginator = new Paginator();
$query = (isset($_GET["query"]) && strlen($_GET["query"])>1)? '%'.$_GET["query"].'%':'%';
$countsql = "SELECT * FROM customer_crm WHERE firstname LIKE :query OR email LIKE :query OR telephone LIKE :query ";
$sthcount = $pdo->prepare($countsql);
$sthcount->bindParam(':query',$query,PDO::PARAM_STR);
$sthcount->execute();
$count=$sthcount->fetchColumn();
$paginator->paginate($count);
$start = (($paginator->getCurrentPage()-1)*$paginator->itemsPerPage);
$length = ($paginator->itemsPerPage);
$sql = $countsql . ' ORDER BY date_followup DESC limit :start, :length ';
$sth = $pdo->prepare($sql);
$sth->bindParam(':start',$start,PDO::PARAM_INT);
$sth->bindParam(':length',$length,PDO::PARAM_INT);
$sth->bindParam(':query',$query,PDO::PARAM_STR);
$sth->execute();
See, you where making two mistakes here:
getting your count value without considering the query. You should set the value of $query regardless of the existance of $_GET['query'], and use it in your count query as well as your results query.
binding parameters whose placeholders and values do not exist in the query you're executing. Make sure your results query contains :query, :start and :length or you will be binding more parameters than the query has.
You should also have wrapped your statements in try/catch blocks so you could debug what was happening.
try {
$sth = $pdo->prepare($sql);
$sth->bindParam(':start',$start,PDO::PARAM_INT);
$sth->bindParam(':length',$length,PDO::PARAM_INT);
$sth->bindParam(':query',$query,PDO::PARAM_STR);
$sth->execute();
} catch(\PDOException $e) {
die('Error in query: '. $e->getMessage());
}
That way you would have known that the query was failing because of
Invalid parameter number: parameter was not defined
NOTE I have no clue about how your paginator will know about the current page, nor can I see where are you setting the itemsPerPage value.

Fetch row with the highest id column value [duplicate]

This question already has answers here:
Select the most recent 5 rows based on date
(2 answers)
Closed 2 years ago.
I would like to reuse a query with concatenation but It seems not working.
I have this for counting rows (working):
$q = $db->prepare("SELECT id, image_date, image_link, image_name, image_category FROM image WHERE image_date < NOW() AND image_category= :category";
$q->bindValue(':category', $category, PDO::PARAM_STR);
$q->execute();
$row = $q->fetchColumn();
And I would like to concatenate with that to use data (not working):
$q .= " ORDER BY id DESC LIMIT :limit");
$q->bindValue(':limit', 1, PDO::PARAM_INT);
$q->execute();
I've also test with that form but not working :
$q=$q. " ORDER BY id DESC LIMIT :limit");
The problem with PDO is that you have to prepare a query before you can bind anything, and once prepared, a query obviously cannot be extended anymore.
Besides, your first query does anything but count. So the simpler the better - just run two separate queries without concatenation
$q = $db->prepare("SELECT count(*) FROM image WHERE image_date < NOW() AND image_category= ?";
$q->execute([$category]);
$count = $q->fetchColumn();
And then
$q = $db->prepare("SELECT id, image_date, image_link, image_name, image_category
FROM image WHERE image_date < NOW() AND image_category= ? ORDER BY id DESC LIMIT ?";
$q->execute([$category, $limit]);
$rows = $q->fetchall();
You need to append the second part to the SQL string,
but not to the Prepared Statement variable $q.
$sql = "SELECT id, image_date, image_link, image_name, " .
"image_category FROM image WHERE image_date < NOW() " .
"AND image_category= :category ORDER BY id DESC LIMIT :limit";
$q = $db->prepare($sql);
$q->bindValue(':category', $category, PDO::PARAM_STR);
$q->bindValue(':limit', 1, PDO::PARAM_INT);
$q->execute();
$row = $q->fetchColumn();

Unable to run named placeholder for order by ASC in php pdo

I am new to PHP PDO and trying to use named placeholder at the place of ORDER BY ASC. Sometime in simple query page this run very successfully but unable to run in the following query:
PHP CODE IS:
$price_sort = "ASC";
$keyword = "samsung glaxy";
$limit = 0;
$query = $db->prepare("SELECT *, MATCH(title) against (:keyword) as 'relevence'
FROM view_store_items_grid
WHERE MATCH(title) against(:keyword)
ORDER BY relevence DESC, price :order
LIMIT :limit,25");
$query->bindValue(":keyword",$keyword);
$query->bindValue(":order",$price_sort);
$query->bindValue(":limit", $limit, PDO::PARAM_INT);
$query->execute();
When I remove placeholder :order with ASC this run and gives result but when I use this placeholder, I get empty result.
For Fetching data or to show fetched result I am using
while ($row = $query->fetch(PDO::FETCH_ASSOC)) :
extract($row);
echo "$name";
endwhile;
What I am doing wrong and How I can use many named placeholder in query at different places?
You should not bind ASC/DESC in prepared statement. Parameters are automatically quoted, and ASC/DESC shouldn't be quoted. this is the same reason that table and column names can't be parameters.
Instead you can do like that
$sql_query = "SELECT *, MATCH(title) against (:keyword) as 'relevence'
FROM view_store_items_grid
WHERE MATCH(title) against(:keyword)
ORDER BY relevence DESC, price "
if($price_order == 'ASC'){
$sql_query .= " ASC "
}else{
$sql_query .= " DESC "
}
$sql_query .= " LIMIT :limit,25 "
$query = $db->prepare($sql_query);
Refer How bindValue in LIMIT
Refer pdo binding asc/desc order dynamically
Also do not try to use the same named parameter twice in a single SQL statement, for example
<?php
$sql = 'SELECT * FROM some_table WHERE some_value > :value OR some_value < :value';
$stmt = $dbh->prepare($sql);
$stmt->execute( array( ':value' => 3 ) );
?>
...this will return no rows and no error -- you must use each parameter once and only once. Apparently this is expected behavior (according to this bug report: http://bugs.php.net/bug.php?id=33886) because of portability issues.
This one solved this question by replacing the price_sort variable value with price ASC and removing the price before the placehoder :order
as:
$price_sort = "price ASC";
and the query is as:
$query = $db->prepare("SELECT *, MATCH(title) against (:keyword) as 'relevence'
FROM view_store_items_grid
WHERE MATCH(title) against(:keyword)
ORDER BY relevence DESC, :order
LIMIT :limit,25");
this solved my question with the help of answer of #tamil
Thank you

Categories