Possible to call PDO::fetchAll() more then once? - php

Ive been running some queries using PHP's PDO library. It seems that when i use:
<?php
$smtp->execute();
$result = stmt->fecthArray();
?>
It unsets the array inside PDO. I know this because when i call that very same line again, it returns an empty array. Why does it do this? Is this normal behavior?

When building the resulting array, fetchAll() removes all the results from the result set. Instead of calling it again, re-use the array you retrieved in the first time.

Related

Php PDO | how to use fetchAll with FETCH_LAZY?

I am trying to use FETCH_LAZY. I can use a while loop whilst setting $row equal to $query->fetch(). The problem is that fetchAll does not work when the fetchMode is FETCH_LAZY.
How can I return an array of PDO Objects?
Thanks.
Due to the very nature of FETCH_LAZY, you cannot use fetchAll with this mode. It can be used with fetch() only.
It seems that you are simply confusing this mode with FETCH_OBJ which will give you an array of objects you need
$array = $stmt->fethAll(PDO::FETCH_OBJ);
Also note that beside creating stdObj instances you can make fetchAll to return an array of objects of any other class as well.

Custom buffering of php mysql results - strange issue

I discovered something very strange with my PHP code and mysqli functions. When I have my code in the format below:
function mainline(){
$q=mysqli_query($this->conn,"select * from table",MYSQLI_USE_RESULT);
$dataset=parse($q);
}
function parse($q){
if (!$q){return NULL;}
while($res=mysqli_fetch_array($q)){$r[]=$res;}
mysqli_free_result($q);$q=NULL;$res=NULL;return $r;
}
I'm able to retrieve data and process it. In the above example, data is returned to $dataset and each element is retrieved in the form of $dataset[row number][field name].
Now when I change my code so its like this:
function mainline(){
$q=mysqli_query($this->conn,"select * from table",MYSQLI_USE_RESULT);
$dataset=parse($q);
}
function parse($q){
if (!$q){return NULL;}
while($r[]=mysqli_fetch_array($q)); // I made change here
mysqli_free_result($q);$q=NULL;return $r;
}
The data returned is always nothing even though the select statement is exactly the same and always returns rows. During both tests, nothing has modified the data in the database.
My question then is why does while($res=mysqli_fetch_array($q)){$r[]=$res;} retrieve correct results and while($r[]=mysqli_fetch_array($q)); does not?
With the second while loop, I won't have to allocate an extra variable and I'm trying to cut down on the use of system memory so that I can run more apache processes on my system instead of waste memory unnecessarily on PHP.
Any ideas why while($r[]=mysqli_fetch_array($q)); wont work? or any ideas how I can make it work without using an extra variable? or am I stuck?
if you want to store all result in array than why not use
mysqli_fetch_all($q)
and store result in whatever you want. Though if you want to have quick access I
think caching sounds more appropriate.
mysqli_fetch_all — Fetches all result rows as an associative array, a numeric array, or both

Why doesn't array_push() take a pdo query object as an argument

Just curious. When pushing an array on another:
array_push($array_1, $array_2);
I get the usual behavior, but when I push a pdo query->fetchAll which contains and returns an array, nothing happens.
array_push($array_1, $query->fetchAll());
What is interesting to me is, if I assign the query object to a variable:
$array_fetchAll = $query->fetchAll();
array_push($array_1, $array_fetchAll);
It works like expected.
The only way this would work is using PHP version 5.5.X or above where a new feature allow functions to be dereferenced directly to access individual elements.
For example echo $stmt->fetchAll()[0]; would not work if you running PHP older than 5.5.x
array_push requires an array as parameter, if you are using older PHP you must store $query->fetchAll() into a variable.

While loop is not working properly

I am having a while loop in my function for getting the values 1 by 1 but i am getting the only 1 value
while($row= mysqli_fetch_array($this->result))
{
$image=$this->getEventDetails($row['Album_top'],'Event_image');
$alert.="<div class=facBox>
<a href='gallery.php?id=$row[Id]' style=margin-top:0px;>
<img src='admin/customer/eventgallery/$image' alt=''>
</a>
<div class=clear></div>
<a href='gallery.php?id=$row[Id]' style=margin-top:0px;>$row[Album_title]</a>
</div>";
}
I am getting the image name from another function that is
function getEventDetails($id,$fieldname)
{
$get="Select * from sarnaevent where Id='$id'";
$this->result=mysqli_query($this->con,$get);
$row=mysqli_fetch_array($this->result);
return $row[$fieldname];
}
Now i am getting the only value from the loop my $alert is having only one facbox. if i remove this line
$this->getEventDetails($row['Album_top'],'Event_image');
It works fine but i want this line to get the image name.
Inside getEventDetails(), you assign $this->result, overwriting the previous contents of $this->result. Since that occurs inside the while loop where the previous result is being used, the loop exits because there are no further results to retrieve from the inner fetch.
User a different temporary result set inside teh getEventDetails() method.
function getEventDetails($id,$fieldname)
{
$get="Select * from sarnaevent where Id='$id'";
// Different variable name...
$temporary_result = mysqli_query($this->con,$get);
$row=mysqli_fetch_array($temporary_result);
return $row[$fieldname];
}
In general, I would question the need to be storing a transient result resource into the object's $this->result for most purposes. In any case where you're using that inside a method, you are probably better off using a variable scoped only to the method, which lives only for the lifetime that result set is being used.
Please use caution when sending $id directly into the query. Although I suspect it is known to be an integer variable, and therefore it won't break the SQL, it's a good idea to get into the habit of using prepare()/execute() to prevent SQL injection.
One final point of caution: When placing the string variable into your HTML markup, be sure to use htmlspecialchars() to escape it against malforming the HTML. (If the Id is known to be an integer, it isn't necessary there)
"...<a href='gallery.php?id=$row[Id]' style=margin-top:0px;>" . htmlspecialchars($row['Album_title']) . "</a>..."
Instead of using mysqli_fetch_array() try using mysqli_fetch_assoc (see: http://php.net/manual/en/mysqli-result.fetch-assoc.php); the returned array will be associative (key-value pairs) where the keys are the column names.
You're blowing out your original query.
First, you do a query, and assign its result to $this->result. You then iterate across those results. For the first row, you immediately make a new query, overwrite $this->result with the new results, and then try to continue... but you've just replaced the rest of your results with the single result from the event details query, so mysqli_fetch_array doesn't find any more results.
Solution: use a separate variable for that result. A local one should be fine, since you don't use it outside that function. You may also need to use a separate connection; I'm not sure of that. Try it with just changing $this->result in getEventDetails() to use something like $eventResult instead.

PHP/PDO: return query rows without foreach?

I am confused about this, I run a query such as
foreach($dbh->query("SELECT * FROM ...") as $row) {
...do something with row()
But when I var_dump $dbh it is a PDOstatement object.
This leads me to two questions:
How does foreach somehow resolve the object into separate rows?
How can I store all rows in an array, like $arr = $dbh->query(...)? This does not work because it is still an object
I can of course run under the foreach, and do $arr[] = $row, but that seems a bit silly..
PHP has some interesting interfaces that let you handle objects as arrays. In this case the PDOStatement class implements Traversable and this allows the use of foreach on it. See here http://www.php.net/manual/en/class.pdostatement.php
To get all your results in one array take a look at PDOStatement::fetchAll. And also in the future consider checking the PHP documentation on php.net if you run into problems. It's packed with examples and useful user comments.
Use PDOStatement::fetchAll() to get the entire result set as array. AS far as what PDO does internally it uses an iterator to access some representation of a recordset. This way you use less memory because youre not pulling the entire result set into php, youre using something resembling a resource thats internal to the implementation.

Categories