Php prepare method where should I use While loop - php

I am new to PHP prepare method, I need some help to use while loop in the following code.
Here is the query function
function query($query, $bindings, $conn) {
$stmt = $conn->prepare($query);
$stmt-> execute($bindings);
$result = $stmt->fetchAll();
return $result ? $result : false;
}
and the query
$home_team = query('SELECT home_team FROM premier_league
WHERE match_date >= :current_date
AND pre_selected = :pre_selected
ORDER BY match_date LIMIT 5',
array('current_date' => $current_date,
'pre_selected' =>$pre_selected),
$conn);
if (empty($home_team)){
echo "No Match Selected for Today.";
} else {
print_r($home_team);
}
How and where I use while loop for this query?

you don't need no while here
function query($query, $bindings, $conn) {
$stmt = $conn->prepare($query);
$stmt-> execute($bindings);
return $stmt->fetchAll();
}
$sql = 'SELECT home_team FROM premier_league WHERE match_date >= ?
AND pre_selected = ? ORDER BY match_date LIMIT 5';
$home_team = query($sql,array($current_date, $pre_selected), $conn);
foreach ($home_team as $row) {
echo $row['home_team']."<br>\n";
}

In else block
else {
print_r($home_team);
/* here
foreach ($home_team as $team) {
echo $team->home_team . '<br>';
}*/
}

PDOStatement implements Traversable so using fetchAll would be a overhead.
function query($query, $bindings, $conn) {
$stmt = $conn->prepare($query);
$stmt->execute($bindings);
$stmt->setFetchMode(PDO::FETCH_ASSOC);
return $stmt;
}
$home_team = query...;
foreach ($home_team as $row) {
echo $row['home_team']."<br>\n";
}

The idea of using a prepared query is to have the server parse the query once and create a query plan once. This is useful for queries that you execute repeatedly, only changing the parameter values.
Accordingly:
- the prepare should be done once.
- the execute should be done inside the loop.
If you are executing a query once in a while, then the prepare overhead is not worth it.

Related

PDO Limit Query Not Working using Binding in Execute

I'm trying to get a limit query working. So far I've verified the following:
All input it valid and correct.
The Query works when manually run against MySQL
The Values are Cast to INT. I have even replcated the variables with the int value.
try {
$sql = "SELECT * FROM sensor_data WHERE sid=:sid ORDER BY id DESC LIMIT :starting_limit, :recordlimit";
$core = CoreDB::getInstance();
$sth = $core->dbh->prepare($sql);
$sth->execute(array(':sid' => $sensor->getID(), ':starting_limit' => (int)0, ':recordlimit' => (int)10));
// $sth->execute(array(':sid' => $sensor->getID()));
$results = $sth->fetchAll();
var_dump($sth->rowCount());
if ($sth->rowCount() > 0) {
foreach($results as $row){
$id = $row['id'];
var_dump($id);
}
}
}
catch(Exception $e){
}
Any advice is appreciated
The only solution I've found is to manually bind params rather than put them in an array in the execute method.
try {
$sql = "SELECT * FROM sensor_data WHERE sid=:sid ORDER BY id DESC LIMIT :starting_limit, :recordlimit";
$core = CoreDB::getInstance();
$sth = $core->dbh->prepare($sql);
$sth->bindValue(':sid', $sensor->getID(), PDO::PARAM_INT);
$sth->bindValue(':starting_limit', 0, PDO::PARAM_INT);
$sth->bindValue(':recordlimit', 10, PDO::PARAM_INT);
$sth->execute();
$results = $sth->fetchAll();
var_dump($sth->rowCount());
if ($sth->rowCount() > 0) {
foreach($results as $row){
$id = $row['id'];
var_dump($id);
}
}
}
catch(Exception $e){
}
If anyone is aware of how to get it working in the execute method please let me know and I will update the answer.

Prepared Statement Return Get Results & Count

I am trying to get both the results of my query and the row count wihtout having to make two trips the the DB if possible. I am using prepared statements in a procedural way. My code is as follows:
$dbd = mysqli_stmt_init($dbconnection);
if (mysqli_stmt_prepare($dbd, "SELECT * FROM Contacts WHERE First_Name = ?" )) {
mysqli_stmt_bind_param($dbd, "s", $val1);
if (!mysqli_stmt_execute($dbd)) {
echo "Execute Error: " . mysqli_error($dbconnection);
} else {
//do nothing
}
} else {
echo "Prep Error: " . mysqli_error($dbconnection);
}
$result = mysqli_stmt_get_result($dbd);
So the above code works just fine and returns my results. What I want to do now is get the row count using this same statement but i don't want to have to write a brand new prepared statement. If I writer a separate prepared statement and use store_results and num_rows I get the row count but that would force me to have to write an entire new block of code and trip to db. I am trying to do something as follows but It throws and error:
$dbd = mysqli_stmt_init($dbconnection);
if (mysqli_stmt_prepare($dbd, "SELECT * FROM Contacts WHERE First_Name = ?" )) {
mysqli_stmt_bind_param($dbd, "s", $val1);
if (!mysqli_stmt_execute($dbd)) {
echo "Execute Error: " . mysqli_error($dbconnection);
} else {
//do nothing
}
} else {
echo "Prep Error: " . mysqli_error($dbconnection);
}
$result = mysqli_stmt_get_result($dbd);
mysqli_stmt_store_result($dbd);
$rows = mysqli_stmt_num_rows($dbd);
The throws and error as if i can't run both get results and store results using the same prepared statement. Im simply trying to keep my code compact and reuse as much as possible. If i break the above out into two separat prepared statements it works fine, Im just wondering there is a way to just add a line or two to my existing statement and get the row count. Or do i have to write an entire new block of code with new stmt_init, stmt_prepare, bind_param, execute, etc...
I tried your code (and reformatted it a bit), but I can't get it to work when I use both store_result() and get_result(). I can only use store_result then bind_result().
So the alternative is to fetch all the rows and then count them:
Example:
$sql = "SELECT * FROM Contacts WHERE First_Name = ?";
$stmt = mysqli_stmt_init($dbconnection);
if (mysqli_stmt_prepare($stmt, $sql) === false) {
trigger_error("Prep Error: " . mysqli_error($dbconnection));
return 1;
}
if (mysqli_stmt_bind_param($stmt, "s", $val1) === false) {
trigger_error("Bind Error: " . mysqli_stmt_error($stmt));
return 1;
}
if (mysqli_stmt_execute($stmt) === false) {
trigger_error("Execute Error: " . mysqli_stmt_error($stmt));
return 1;
}
$result = mysqli_stmt_get_result($stmt);
$rows = mysqli_fetch_all($result, MYSQLI_ASSOC);
$num_rows = count($rows);
print "$num_rows rows\n";
foreach ($rows as $row) {
print_r($row);
}
In my opinion, PDO is much easier:
$pdo = new PDO("mysql:host=127.0.0.1;dbname=test", "xxxx", "xxxxxxxx");
$pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
$pdo->setAttribute(PDO::MYSQL_ATTR_USE_BUFFERED_QUERY, true);
$pdo->setAttribute(PDO::ATTR_DEFAULT_FETCH_MODE, PDO::FETCH_ASSOC);
$sql = "SELECT * FROM Contacts WHERE First_Name = ?";
$stmt = $pdo->prepare($sql);
$stmt->execute([$val1]);
$num_rows = $stmt->rowCount();
print "$num_rows rows\n";
while ($row = $stmt->fetch()) {
print_r($row);
}

PDO - executed query with binded parameters yields no results?

I am trying to create a PHP array of random "fruits" from a database.
The database class that I am using:
class Db
{
private static $_instance = null;
private $_pdo;
private function __construct()
{
try {
$this->_pdo = new PDO('mysql:host=' . DB_HOST . ';dbname=' . DB_NAME .'', DB_USER, DB_PASS);
} catch (PDOException $e) {
die($e->getMessage());
}
}
public static function getInstance()
{
if (!isset(self::$_instance)) {
self::$_instance = new Db();
}
return self::$_instance;
}
public function prepare($sql)
{
return $this->_pdo->prepare($sql);
}
}
The class that is using the database to fetch "fruits" to create an array of a given size of random entries by using 3 seperate queries to calculate and retrieve "x" number of random items form the database.
class FruitBasket
{
private $_fruitArray = array(),
$_inputCode,
$_db;
public function __construct($input = null)
{
$this->_inputCode = $input;
$this->_db = Db::getInstance();
var_dump($this->_db);
}
public function pickFruit($count)
{
$doubleCount = $count * 2;//double the count used in calculation with the random number
$fruitIDs = ''; //the choosen fruits (id's)
$i = 0;
//#1 get total count of fruits table
$sql = "SELECT COUNT(*) FROM `fruits`";
if ($query = $this->_db->prepare($sql)) {
if ($query->execute()) {
$allFruits = $query->fetch(PDO::FETCH_NUM);
} else {
print_r("ERROR QUERY DID NOT EXECUTE #1");
}
} else {
print_r("ERROR CHECK SQL SYNTAX #1");
}
//#2 calculate random number to pull from all of id's
$sql = "SELECT id FROM `fruits` WHERE RAND()* ? < ? ORDER BY RAND() LIMIT 0, ? ";
if ($query = $this->_db->prepare($sql)) {
$query->bindParam(1, $allFruits[0], PDO::PARAM_INT);
$query->bindParam(2, $doubleCount, PDO::PARAM_INT);
$query->bindParam(3, $count, PDO::PARAM_INT);
if ($query->execute()) {
while ($row = $query->fetch(PDO::FETCH_ASSOC)) {
if ($i == 0) {
$fruitIDs .= "'" . $row['id'] . "'";
} else {
$fruitIDs .= ", '" . $row['id'] . "'";
}
$i++;
}
} else {
print_r("ERROR QUERY DID NOT EXECUTE #2");
}
} else {
print_r("ERROR CHECK SQL SYNTAX #2");
}
//#3 get the fruits
$sql="SELECT NAME FROM `fruits` WHERE `id` IN( ? )";
if ($query = $this->_db->prepare($sql)) {
$query->bindParam(1, $fruitIDs, PDO::PARAM_STR);
if ($query->execute()) {
while ($row = $query->fetch(PDO::FETCH_ASSOC)) {
$this->_fruitArray[] = $row['name'];
}
} else {
print_r("ERROR QUERY DID NOT EXECUTE #3");
}
} else {
print_r("ERROR CHECK SQL SYNTAX #3");
}
return $this->_fruitArray;
}
}
The table that I am attempting has a bunch of "fruits" in it, an example of how the table is structured:
==================================
| ID | NAME |
==================================
| 01 | Apple |
==================================
I am attempting to test this all out by using the following:
echo "<pre>";
echo "TESTING FRUIT ARRAY:</br></br>";
$basket = new FruitBasket();
echo"</br></br> PRINT_R: </br></br>";
print_r($basket->pickFruit(10));
echo "</br></br> VARDUMP: </br></br>";
var_dump($basket->pickFruit(10));
The sql query prepares and executes properly, I can do a vardump of the prepares and the binds and they return TRUE. Nothing is returned on the last query however.
In the first query that executes Doing a print statement of $allFruits shows the correct total count from the table.
The second query seems to be working properly,the string $fruitIDs, gets random id's from the table, I can echo this out and confirm that indeed the correct number of ID's are returned.
The problem occurs (I think) with the third query:
Nothing is returned form this query. The prepare statement returns true on a var dump as does the execute, however there is no results!
If I manually take the ID's that are output from query#2 and run it myself in mysql, the correct "fruit" names are returned.
Am I binding the variables incorrectly? I read the pages from the PHP manual but clearly I am doing something wrong.
Please help! :)
Thanks to the links and input provided by Your common sense, using the following:
Reference - frequently asked questions about PDO
and
Can I bind an array to an IN() condition?
I was able to resolve this by changing my query as follows:
//#2 calculate random number to pull from all of id's
$sql = "SELECT id FROM `fruits` WHERE RAND()* ? < ? ORDER BY RAND() LIMIT 0, ? ";
if ($query = $this->_db->prepare($sql)) {
$query->bindParam(1, $allFruits[0], PDO::PARAM_INT);
$query->bindParam(2, $doubleCount, PDO::PARAM_INT);
$query->bindParam(3, $count, PDO::PARAM_INT);
if ($query->execute()) {
while ($row = $query->fetch(PDO::FETCH_ASSOC)) {
$fruitIDs[] = $row['id'];
}
} else {
print_r("ERROR QUERY DID NOT EXECUTE #2"); }
} else {
print_r("ERROR CHECK SQL SYNTAX #2");
}
//#3 get the fruits
$inQuery = implode(',', array_fill(0, count($fruitIDs), '?'));
$sql="SELECT NAME FROM `fruits` WHERE `id` IN($inQuery)";
if ($query = $this->_db->prepare($sql)) {
if ($query->execute($fruitIDs)) {
while ($row = $query->fetch(PDO::FETCH_NUM)) {
$this->_fruitArray[] = $row[0];
}
} else {
print_r("ERROR QUERY DID NOT EXECUTE #3");
}
} else {
print_r("ERROR CHECK SQL SYNTAX #3");
}
return $this->_fruitArray;
}
I do not fully understand the security benefits or ramifications of binding the parameters or simply including them in the actual execute() but for now the query is performing as intended, so thank you for the input!

mysqli get_result alternative with multiple parameters

SELECT * FROM `ware_house_indents` WHERE `has_cancel` = ? AND `eid`= ?
i need to get result above query in mysqli. but i cant use get_result() function because it is not working in server.i have found this below function and it is working fine.but that function not possible to pass multiple parameters.please help me to solve this problem.
function db_bind_array($stmt, &$row)
{
$md = $stmt->result_metadata();
$params = array();
while($field = $md->fetch_field()) {
$params[] = &$row[$field->name];
}
return call_user_func_array(array($stmt, 'bind_result'), $params);
}
function db_query($db, $query, $types, $params)
{
$stmt = $db->prepare($query);
$bindRet = call_user_func_array(array($stmt,'bind_param'),
array_merge(array($types), $params));
$stmt->execute();
$result = array();
if (db_bind_array($stmt, $result) !== FALSE) {
return array($stmt, $result);
}
$stmt->close();
return FALSE;
}
if (($qryRes = db_query($mysqli, $sql, 'i', array(&$var))) !== FALSE) {
$stmt = $qryRes[0];
$row = $qryRes[1];
while ($stmt->fetch()) {
print_r($row);
}
$stmt->close();
}
Let me suggest you a quite indirect solution.
You'd do yourself a huge favor if start using PDO instead of mysqli
It has no mysqli disadvantages when dealing with prepared statements as it has a way better implementation of above functions out of the box. So, it will let you to get your data in a few lines:
$sql = "SELECT * FROM ware_house_indents WHERE has_cancel = ? AND eid= ?";
$stm = $pdo->prepare($sql);
$stm->execute(array($cancel,$eid));
$data = $stm->fetchAll(); // or fetch() if you need only one row
that's all

Can't get array from PDO query

i'm trying to get an array from a SQL query using pdo, what i send to the method it's for example $connection->selectFrom('Person',array(1,2));
when i try to get the results it returns an empty array, here is my code:
public function selectFrom($table,$indexes){
try{
$pdo=$this->getPdo();
// HERE I GET ALL THE COLUMN NAMES FROM THE TABLE I RECEIVE
$columns = $this->getColumnNames($table);
$finals = array();
// IN THIS CICLE I GET THE COLUMNS THAT MATCH THE INDEXES I RECEIVE
for($i=0;$i<count($indexes);$i++){
$finals[$i] = $columns[$indexes[$i]];
}
// FROM HERE I GET THE QUERY STATEMENT WICH IS SELECT column1,column2 from $table
$query = $this->getSelectSQL($table, $finals);
// ALL OF THE ABOVE WORKS BUT HERE IT STOPS WORKING
$results = $pdo->query($query);
return $results;
}catch(PDOException $ex){
echo "EXCEPTION ".$ex;
}
}
Thanks to #Cymbals for your answer, the final code ended up like this:
public function selectFrom($table,$indexes){
try{
$pdo=$this->getPdo();
$columns = $this->getColumnNames($table);
$finals = array();
for($i=0;$i<count($indexes);$i++){
$finals[$i] = $columns[$indexes[$i]];
}
$query = $this->getSelectSQL($table, $finals);
$query.= " WHERE Available = 1";
$stmt = $pdo->prepare($query);
$stmt->execute();
$results = $stmt ->fetchAll();
return $results;
}catch(PDOException $ex){
echo "EXCEPTION ".$ex;
}
}
Try this after getting the query, prepare and execute it
$stmt = $pdo->prepare($query);
var_dump($stmt);// if the prepare fails or sql query is messed up it will give false
$results = $stmt->execute();
return $results;

Categories