How to convert this mySql query to PDO format...? - php

How should i write my PDO Prepare and bindValue/param statement for this type of query where i check whether the value is not null then only add it to the query string.....
$query = "SELECT * FROM cabs WHERE DATE='$date' ";
if ($mode!=='' || $mode!=="")
$query .="AND MODE='$mode' ";
if ($tfno!=='')
$query .="AND TFNO='$tfno' ";
$query .="ORDER BY TIME";

Quick answer, without testing:
<?php
$params = array(':date' => $date);
$query = "SELECT * FROM cabs WHERE DATE=':date' ";
if ($mode!=='' || $mode!=="") {
$query .="AND MODE=':mode' ";
$params[':mode'] = $mode;
}
if ($tfno!=='') {
$query .="AND TFNO=':tfno' ";
$params[':tfno'] = $tfno;
}
$query .="ORDER BY TIME";
$req = $dbh->prepare($query);
$req->execute($params);
Just push in the param array each time your query gets more filters, and using a name should be easier, I'm not sure that array_push would preserve the order, so ..

Related

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.

does not work request

What am I doing wrong in my query?
thank you in advance for your help
new - not work
$query = "SELECT * ";
$query .= "FROM photographs ";
$query .= "WHERE `caption` LIKE '%".$query."%' ";
$query .= "OR `caption2` LIKE '%".$query."%' ";
//$query .= "WHERE visible = 1 ";
$query .= "ORDER BY $order_by LIMIT $start, $display ";
$result = mysqli_query ($connection, $query);
old query - work
//$query = ("SELECT * FROM photographs WHERE (`caption` LIKE '%".$query."%') OR (`caption2` LIKE '%".$query."%')");
//$result = mysqli_query($connection, $query);
You are overwriting the $query variable with parts of your query. :-)
LIKE '%".$query."%' ";
should be replaced with
LIKE '%".$yourTerm."%' ";
where $yourTerm is what you are trying to search in your database

Problems with using PDO to perform an advanced search query

I have the following code and all of the search functions work except for the title field. So I can search by genre, date, location etc... but not by title. When attempting to search by title nothing is returned at all. Can anyone help me with this?
Also, is there a more efficient way to count all the fields before limiting it for use in pagination later on?
$today = date("Y-m-d");
$query = "SELECT * FROM TABLE_NAME WHERE Date >= '$today'";
$bind = Array();
if ($_GET["Title"] && $_GET["Title"] != "") {
$query .= " and Title like %?%";
$bind['Title'] = $_GET['Title'];
}
if ($_GET["Genre"] && $_GET["Genre"] != "") {
$query .= " and Genre like %?%";
$bind['Genre'] = $_GET['Genre'];
}
if ($_GET["Location"] && $_GET["Location"] != "") {
$query .= " and Location like %?%";
$bind['Location'] = $_GET['Location'];
}
if ($_GET["Date"] && $_GET["Date"] != "") {
$query .= " and Date = %?%";
$bind['Date'] = $_GET['Date'];
}
$stmt = $db->prepare($query);
$stmt->execute($bind);
$rows = $stmt->fetchAll(PDO::FETCH_ASSOC);
$num = count($rows);
$query .= " ORDER BY Date LIMIT $limit, 9";
$stmt = $db->prepare($query);
$stmt->execute($bind);
$rows = $stmt->fetchAll(PDO::FETCH_ASSOC);
Edit: After everyone's help I thought I would post my now revised code for future reference. It turns out the other fields were not working, but instead due to the if statement all this was nested in the code simply wasn't being executed.
$today = date("Y-m-d");
$query = "SELECT * FROM TABLE_NAME WHERE Date >= '$today'";
$countq = "SELECT count(*) FROM TABLE_NAME WHERE Date >= '$today'";
$bind = Array();
if ($_GET["Title"] && $_GET["Title"] != "") {
$query .= " and Title like :title";
$countq .= " and Title like :title";
$bind[':title'] = "%{$_GET['Title']}%";
}
if ($_GET["Genre"] && $_GET["Genre"] != "") {
$query .= " and Genre like :genre";
$countq .= " and Genre like :genre";
$bind[':genre'] = "%{$_GET['Genre']}%";
}
if ($_GET["Location"] && $_GET["Location"] != "") {
$query .= " and Location like :loc";
$countq .= " and Location like :loc";
$bind[':loc'] = "%{$_GET['Location']}%";
}
if ($_GET["Date"] && $_GET["Date"] != "") {
$query .= " and Date = :date";
$countq .= " and Date = :date";
$bind[':date'] = "{$_GET['Date']}";
}
$stmt = $db->prepare($countq);
$stmt->execute($bind);
$rows = $stmt->fetchAll();
$num = count($rows);
$query .= " ORDER BY Date LIMIT $limit, 9";
$stmt = $db->prepare($query);
$stmt->execute($bind);
$rows = $stmt->fetchAll(PDO::FETCH_ASSOC);
all of the search functions work
With the given query it is not true
From PDO tag wiki:
placeholders cannot represent an arbitrary part of the query, but a complete data literal only. Neither part of literal, nor whatever complex expression or a syntax keyword can be substituted with prepared statement.
Prepare FULL literal first: $name = "%$name%"; and then bind it.
As for the "more" efficient method for pagination - yes, oh yes.
With your current way of counting data you don't actually need other queries. as you have ALL the data already and can paginate it as well.
But of course it will pollute all the memory soon. So, if you want to get a count of rows from database, get the very count: run the same query but instead of SELECT * make it "SELECT count(*)
There are not any errors returned, that's why I am so confused
From PDO tag wiki again:
It is essential to set ERRMODE_EXCEPTION as a connection option as it will let PDO throw exceptions on connection errors. And this mode is the only reliable way to handle PDO errors.

mysqli multiple query

I do following:
$query .=" SELECT * , COUNT(PRESENT) FROM seventh_a";
$query .=" WHERE class ='0' AND NAME ='Alexander Kirkby Scherer'";
$query .=" AND PRESENT = 'TS' GROUP BY lesson";
$query = " SELECT * , COUNT(lesson) FROM seventh_a";
$query .=" WHERE class ='0' AND NAME ='Alexander Kirkby Scherer'";
$query .=" GROUP BY lesson";
After that I can echo out $row['COUNT(PRESENT)'] but not $row['COUNT(lesson)'].
Can anybody tell me what to do to get both values, so that i am able to work with them?
According to the man page, if you're using mysqli_multi_query, you can access results from the different queries like so:
To retrieve the resultset from the first query you can use mysqli_use_result() or
mysqli_store_result(). All subsequent query results can be processed using
mysqli_more_results() and mysqli_next_result().
They give some sample code:
$query = "SELECT CURRENT_USER();";
$query .= "SELECT Name FROM City ORDER BY ID LIMIT 20, 5";
/* execute multi query */
if ($mysqli->multi_query($query)) {
do {
/* store first result set */
if ($result = $mysqli->store_result()) {
while ($row = $result->fetch_row()) {
printf("%s\n", $row[0]);
}
$result->free();
}
/* print divider */
if ($mysqli->more_results()) {
printf("-----------------\n");
}
} while ($mysqli->next_result());
}
You can't use 2 query . Use combine query like this
$query .=" SELECT * , COUNT(PRESENT),COUNT(lesson) FROM seventh_a";
$query .=" WHERE class ='0' AND NAME ='Alexander Kirkby Scherer'";
$query .=" AND PRESENT = 'TS' GROUP BY lesson";
you will get your result $row['COUNT(PRESENT)'] and $row['COUNT(lesson)']
OR use mysqli's multi_query function for this add ; between queries like this
$query .=" SELECT * , COUNT(PRESENT) FROM seventh_a";
$query .=" WHERE class ='0' AND NAME ='Alexander Kirkby Scherer'";
$query .=" AND PRESENT = 'TS' GROUP BY lesson;"; // semicolon here
$query .= " SELECT * , COUNT(lesson) FROM seventh_a";
$query .=" WHERE class ='0' AND NAME ='Alexander Kirkby Scherer'";
$query .=" GROUP BY lesson";

Categories