Mysqli will not store my result or display my result - php

Here is my code.. It doesn't give me an error whale binding, but it will not display anything even though there is more than one row that meets the select statements criteria
$sql = 'SELECT reply_content FROM ticket_replies WHERE reply_id = ? ORDER BY reply_order ASC';
$stmt2 = $mysqli->prepare($sql);
if($stmt2 === false) {
trigger_error('Wrong SQL: ' . $sql . ' Error: ' . $mysqli->error, E_USER_ERROR);
}
$stmt2->bind_param('i', $loggedInUser->user_id);
$stmt2->execute();
$stmt2->store_result();
$stmt2->bind_result($reply_content1);
$stmt2->fetch();
if($stmt2->num_rows > 0) {
while ($stmt2 ->fetch()) {
echo $reply_content1;
}
}
$stmt2->close();

You are fetching twice, try commenting out the first one
//$stmt2->fetch();
if($stmt2->num_rows > 0) {
while ($stmt2 ->fetch()) {
...
The way you have it now will move the cursor one more time. But you have only one record, that's why you don't see anyting.

Related

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);
}

Same statements, the second not working in different if

I'm trying to figure out why a mysqli parepared statement is not working. I can say the page have something like 2 sections, the first one needs $_GET to be empty and the last one needs $_GET['id'] and other to be set (isset). Both "sections" have the same query but in the last section there's a different query first.
Everyting is working fine until the repeated query in the last "section", where nothing is printed.
I have something like this:
if (login_check($mysqli) == true) {
if(empty($_GET)) { //first section
if ($stmt = $mysqli->prepare("SELECT friends.*, members.*, account_type.* FROM friends INNER JOIN members ON members.id = friends.friendID
INNER JOIN account_type ON account_type.name = members.acc_type
WHERE friends.userID = ? AND members.acc_type = ?")) {
$stmt->bind_param('is', $_SESSION['user_id'], $_SESSION['acc_type']);
$stmt->execute();
} else echo $mysqli->error;
$result = $stmt->get_result();
// php/mysqli stuff working as expected ($row[] printing db data)
// no need to close
}
if(isset($_GET['id'], $_SESSION['user_id'])) { // last section
if (mysqli_connect_errno()) {
printf("Connect failed: %s\n", mysqli_connect_error());
exit();
}
/* prepare statement */
if ($stmt = $mysqli->prepare("SELECT COUNT(*) rowCount FROM friends WHERE friendID = ? AND userID = ?")) {
$stmt->bind_param('ii', $_GET['id'], $_SESSION['user_id']);
$stmt->execute();
/* bind variables to prepared statement */
$stmt->bind_result($rowCount);
/* fetch values */
if($stmt->fetch()) {
if ($rowCount > 0) { // This check is working fine, I tested.
$stmt->close(); // close here so no "non-object" error
$stmt = $mysqli->prepare("SELECT friends.*, members.*, account_type.* FROM friends INNER JOIN members ON members.id = friends.friendID
INNER JOIN account_type ON account_type.name = members.acc_type
WHERE friends.friendID = ? AND members.acc_type = ?");
$stmt->bind_param('is', $_GET['id'], $_SESSION['acc_type']);
$stmt->execute();
$result = $stmt->get_result();
$row = $result->fetch_array();
// Here I have some $row['columns'] and nothing is printed.
} else{
echo $_SESSION['username'], ', you are not allowed to be here.';
}
}
/* close statement */
$stmt->close();
}
/* close connection */
$mysqli->close();
}
} else {
echo 'Please, log in.';
}
The first query is working fine, the other is a copy/paste.
I don't see where the problem is :(
Thanks!
Edit: sorry the second query should be "WHERE friends.friendID".
for ($i = 1; $i < 13; $i++) {
$month = $row['month' . $i];
if($row[$month] == 1) {
$paid[] = 'Paid';
} else {
$paid[] = 'Not Paid';
}
$bonus = $row['bonus'];
}
The problem is members.monthx and friends.monthx have the same name, but they are not meant to have the same values so I don't know from what table is getting $row['month' . $i]. The value should be taken from friends.monthx. How do I specify that?

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!

How to put PDO bindParam in if statement?

How to put PDO bindParam in if statement? I tried to do a different variations, but none of them worked.
function get_all_pages($subject_id, $public = true)
{
$db = new PDO('mysql:host=localhost;dbname=name;charset=utf8', 'root', 'whatewer');
$query = "SELECT * ";
$query.= "FROM pages ";
$query.= "WHERE subject_id =:id ";
if ($public)
{
$query.= " AND visible =:visible ";
}
$query.= "ORDER BY position ASC";
$query.= "ORDER BY position ASC";
$stmt = $db->prepare($query);
if ($public)
{
$stmt->bindParam(':id', $subject_id, PDO::PARAM_INT);
$stmt->bindValue(':visile', 2, PDO::PARAM_INT);
}
else
{
$stmt->bindParam(':id', $subject_id, PDO::PARAM_INT);
}
$stmt->execute();
$affected_rows = $stmt->rowCount();
if ($affected_rows == 1)
{
$subject = $stmt->fetch(PDO::FETCH_ASSOC);
return $subject;
}
}
else
{
return null;
}
}
Ok there was misunderstanding I got my cod "Wright" it was stackoverflow that messed my code up. i was struggling to put code in code area. In reality it looks like this.
http://imagizer.imageshack.us/v2/800x600q90/593/zvf8.png
$affected_rows = $stmt->rowCount(); might give you unexpected results as according to the manual:
For most databases, PDOStatement::rowCount() does not return the
number of rows affected by a SELECT statement.
You should fetch a row directly and see what the result is:
$stmt->execute();
if ($subject = $stmt->fetch(PDO::FETCH_ASSOC))
{
return $subject;
}
else
{
return null;
}
And I would recommend opening your database connection as I mentioned in my comment:
$db = new PDO('mysql:host=localhost;dbname=name;charset=utf8', 'root',
'whatewer', array(PDO::ATTR_ERRMODE => PDO::ERRMODE_WARNING));
That will cause PDO to throw exceptions and that will give you a clear error message whenever something goes wrong on any of the db calls.

Php prepare method where should I use While loop

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.

Categories