PDO MySQL and php like statement - php

When I execute this query to the DB:
SELECT * FROM `task` WHERE `date_time_from` like '%0000%'
I get a few results, now I am trying to do the same with PDO and I can not manage to get any results or errors. This is what I have done:
$dbChain = 'mysql:host='.$GLOBALS['dbhost'].';dbname='.$GLOBALS['dbname'];
try{
$dbh = new PDO($dbChain, $GLOBALS['dbuser'], $GLOBALS['dbpassword']);
$sql = "SELECT * FROM task"
. "WHERE date_time_from like CONCAT('%', :dateFrom, '%')";
$a = '0000';
$stmt = $dbh->prepare($sql);
$stmt->bindParam(':dateFrom', $a);
$stmt->execute();
$total = $stmt->rowCount();
echo $total;
while ($row = $stmt->fetch()){
var_dump($row);
}
} catch (Exception $e){
echo 'Error'.$e->getMessage();
}
The result of this is $total = 0. Can anyone tell me what am I doing wrong?
I have also tried this:
$sql = "SELECT * FROM task"
. "WHERE date_time_from like :dateFrom";
$a = "%0000%";
$stmt = $dbh->prepare($sql);
$stmt->bindParam(':dateFrom', $a);
$stmt->execute();
Same result for $total.

bindParam escapes the "%" in the query. It will not work as you expect...
You can, however, use bindValue like so...
$sql = "SELECT * FROM task WHERE date_time_from LIKE ?";
$stmt = $dbh->prepare($sql);
$stmt->bindValue( 1, "%0000%" );
$stmt->execute();
Alternatively, if you want 0 values from a datetime column, you can just do this:
$sql = "SELECT * FROM task WHERE date_time_from = '0000-00-00'";

Related

How do I add a string at the end of user input in SQL/PHP

I have a SQL query that is based on user input.
However, in the table, theres a "-1" at the end of every word that you search for.
For example if you want to get the sql result of car, it's actually named car-1 in the database, but the user should only be able to search for car.
This is how its setup:
$sql = "SELECT * FROM that WHERE this = ?";
$stmt = $conn->prepare($sql);
$search_query = $_POST['this'];
$stmt->bind_param('s', $search_query);
$stmt->execute();
$result = $stmt->get_result();
What I want, is that the select query should be like:
$sql = "SELECT * FROM that WHERE this = ? + '-1'";
But ^^ doesn't work.
$sql = "SELECT * FROM test WHERE NAME='car' & -1";
test = that
NAME= table name
'car' = this
Why don't you just concat -1 to search_query :
$sql = "SELECT * FROM that WHERE this = ?";
$stmt = $conn->prepare($sql);
$search_query = $_POST['this'];
$stmt->bind_param('s', $search_query.'-1');
$stmt->execute();
$result = $stmt->get_result();
Using MySQL:
$sql = "SELECT * FROM that WHERE this = CONCAT(?, '-1')";
Using PHP:
$stmt->bind_param('s', $search_query . "-1");

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.

Use PDO exec(array()) with several operands

I would like to secure my requests in my code.
Today my curent functions are like this.
public function UpdatePMS($table,$data,$where) {
$ret = array();
$set_data = "";
foreach($data as $key => $value){
$set_data .= $key."= '".$value."', ";
}
if (isset($where)) {
$where = "WHERE ".$where;
}
$sql = "UPDATE ".$table." SET ".$set_data."".$where;
$sql = str_replace(", WHERE", " WHERE", $sql);
$stm = $this->db->prepare($sql);
$ret = $stm->execute();
return $ret;
}
With this way, i can select any tables, any datas, and any conditions.
For example:
WHERE id = 1 and status < 10
Or only
WHERE id = 10
Or sometimes
WHERE id = 1 and status >= 5
The content of where could change.
A kind of universal request.
Same for Delete, Update, Select, insert.
I tried to do like this, but it doesn't work.
$db = new PDO('mysql:host=localhost;dbname=asterisk','root','');
$table = "my_table";
$where = "WHERE id = 1";
$sql = 'SELECT * FROM :table :where';
$stm = $db->prepare($sql);
$stm->execute(array(":table" => $table, ":where" => $where));
$ret = $stm->fetchall(PDO::FETCH_ASSOC);
Any ideas?
Frankly, you cannot use prepared statements this way. There are rules to follow. So it just makes no sense to write something like this
$table = "my_table";
$where = "WHERE id = 1";
$sql = 'SELECT * FROM :table :where';
$stm = $db->prepare($sql);
$stm->execute(array(":table" => $table, ":where" => $where));
instead you should write this code
$sql = 'SELECT * FROM my_table WHERE id = ?';
$stm = $db->prepare($sql);
$stm->execute(array($id));
Besides, you cannot parameterize table and field names, so it's better to write them as is.
so i need to make one function per different requests, right?
Honestly - yes. It will spare you from A LOT of headaches.
public function UpdatePMS($data, $id)
{
$data[] = $id;
$sql = "UPDATE table SET f1 = ?, f2 = ? WHERE id = ?";
$stm = $this->db->prepare($sql);
$ret = $stm->execute($data);
return $ret;
}
which is going to be used like
$obj->UpdatePMS([$f1, $f2], $id);

PDO show columns multiple tables

I'm trying to execute two almost identical queries. But for some reason it keeps loading if I execute them both.
Here is my code:
$query = "show columns from auto_new";
$stmtColumns = $db->prepare($query);
$stmtColumns->execute();
$result = $stmtColumns->fetchAll(PDO::FETCH_BOTH);
foreach($result as $r) {
$velden .= $r["0"]. "| ";
}
$query = "show columns from auto_coc";
$stmtColumnsCoc = $db->prepare($query);
$stmtColumnsCoc->execute();
$resultCoc = $stmtColumnsCoc->fetchAll(PDO::FETCH_BOTH);
foreach($resultCoc as $r) {
$velden .= $r["0"]. "| ";
}
If I only execute one of two queries it works just fine, but both doesn't work at all.
Also tried the following with no luck:
$auto_new = 'auto_new';
$auto_coc = 'auto_coc';
$query = "SELECT * FROM information_schema.columns
WHERE TABLE_NAME =:auto_new OR TABLE_NAME = :auto_coc";
$stmt = $db->prepare($query);
$stmt->bindParam(':auto_new', $auto_new, PDO::PARAM_STR);
$stmt->bindParam(':auto_coc', $auto_coc, PDO::PARAM_STR);
$stmt->execute();
$result = $stmt->fetchAll(PDO::FETCH_BOTH);
In both ways it keeps loading forever. What am I doing wrong?

Why is my PDO::FETCH Statement Returning 0?

Here is my code below:
$barcode = $_POST['barcode'];
$year = $_POST['year'];
$movietitle = $_POST['movietitle'];
$stmt = $pdo->prepare("SELECT COUNT(movietitle) FROM movies WHERE movietitle LIKE '%:movie%'");
$stmt->bindParam(':movie', $movietitle);
$stmt->execute();
$fetch = $stmt->fetch();
if($fetch[0] == 0) {
$displaytitle = $_POST['displaytitle'];
$media = $_POST['media'];
$youtube = $_POST['youtube'];
$genre = $_POST['genre'];
$youtube = "www.youtube.com/embed/" . $youtube;
$stmtins = $pdo->prepare("INSERT INTO `movies` VALUES (null, :genre, :movietitle, :displaytitle, :year, :youtube, :media, :barcode)");
$stmtins->bindParam(':genre', $genre);
$stmtins->bindParam(':movietitle', $movietitle);
$stmtins->bindParam(':displaytitle', $displaytitle);
$stmtins->bindParam(':year', $year);
$stmtins->bindParam(':youtube', $youtube);
$stmtins->bindParam(':media', $media);
$stmtins->bindParam(':barcode', $barcode);
$stmtins->execute();
$message = "The movie was added to your database. - $fetch[0]";
} else {
$message = "Already owned.";
}
Every time it's run, $fetch[0] ALWAYS returns 0, despite the $stmt query returning more than 0. What's going on?
I suggest you run PDO in exception mode...
$pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
Then you would see the query error.
The problem is, you can't use interpolate params like you have in your LIKE comparison. Try this instead...
"SELECT COUNT(movietitle) FROM movies WHERE movietitle LIKE CONCAT('%', :movie, '%')"
There's also an easier way to check for existence...
$stmt = $pdo->prepare("SELECT 1 FROM movies WHERE movietitle LIKE CONCAT('%', :movie, '%')");
$stmt->bindParam(':movie', $movietitle);
$stmt->execute();
if(!$stmt->fetch()) {
// fetch will return false if there are no rows

Categories