I have a question about PHP foreach loops. I'm using it in Codeigniter.
Basically I have a list of items in a db and I'm using a foreach loop to run a script on each item in the db until the script has been run on every item.
My question is: If I had, for example, 45 items in the database and then initiated the loop, what would happen if additional items were added to the database list while the loop was still running, thus making a bigger list of items to be looped over?
Would it either:
Run all the items that were in the loop when it was initiated (in this case, 45).
or
Run all the items in the loop and when it gets down to the end (at number 45) continue to run the script on the additional ones I added after the loop was initiated.
I can't seem to find any answers for this, any info is most appreciated
When you fetch all items from the db with CodeIgniter, it puts the results in an result object or array, depending if you use $this->db->result(); or $this->db->result_array();
So when you loop over this result, any new records won't show up in this object or array. Only when you fire a new query, any new rows will be added to the result.
Initially when you fired a query their was 45 records in db and then record has been added , so there will be only 45 records which will be displayed
When a php script run for extracting records from DB table, it actually extract all the records from table according to u'r query & save it in a PHP variable. After that, foreach loop extract data one by one from that variable & execute it.
At the execution time, if any more records comes to u'r DB table then that'll get store in u'r table not in u'r PHP array. So, forloop execution will not get effected by those extra rows.
If u want to execute, all those extra records.. then again u've to make SELECT query to the DB table & extract those additional records.. Need to keep them a PHP array & execute them by foreach.
Related
The task is to find difference between 2 lists of items.
First list is located in MySQL table in the indexed integer field. So we can easily get it with SELECT myfield FROM mytable WHERE otherfield = mycondition. Let's imagine query result is about 5000 rows.
Second list is located in my PHP script, I just downloaded it from web. Let it be 2000 rows.
Most of list items are duplicated and should not be inserted in database.
Way 1: select 5000 rows from MySQL, compare it with second list using array_diff PHP function and make mass query INSERT (field1,field2,field3) VALUES (1,2,3),(2,3,4),(3,4,5)....;. So we have less MySQL queries but they are enough heavy.
Way 2: make foreach loop for my second list and check if every key exists in MySQL and insert if not.
Question is what way is more correct and cheaper for server?
Im asking because comparing process starts like every 30 minutes.
I've got two while loops that I'm using to run through some MySQL data.
The first while loop runs through a bunch of reports and checks the 'state' (as in United States) that is stored in the table.
Within that loop, I'm checking a second table with a while loop for 'state' as well and if the states match then I push some info to an array. I got rid of the other code for simplicity's sake here.
Basically, I started with the first while loop and logged all the info to the console and it successfully looped through all the entries in the table.
I then put the nested while loop in there and when I try to alert or log it to the console, it's only looped through the instances of the first entry in the parent loop.
What I mean is that in the $row_wind loop, the first entry is CT (Connecticut). When I log out the parent loop, it logs everything in that table (with CT being the first one). When I use the below code it's logging just CT and then all the entries in the child loop but doesn't counter the parent loop after that. Am I not able to nest while loops?
while($row_wind = mysqli_fetch_array($sql_wind_result)){
while($row_alert = mysqli_fetch_array($result_user_alerts)){
echo "<script>alert('".$row_wind['state']." ".$row_alert['state']."');</script>";
}
}
mysqli_fetch_array is similar to array_pop() in that once it fetches a result, it's not going to fetch that result again.
So my guess is that your $row_wind loop is actually running through just fine, but the second time through the $row_alert loop looks for more results, finds that it's already run through them (in the loop where $row_wind = 'CT').
If you put some debug info inside the $row_wind loop but outside the $row_alert loop you should see the difference.
To fix this, you'll either have to re-run the $result_user_alerts query before the inner loop, or - probably better if the inner query isn't dependent on the state - run mysqli_fetch_all() beforehand to fetch all your results for the inner loop up front, and then loop through the resulting array with your inner loop with a foreach() or while(). That way you only have to fetch them once.
If you don't have mysqli_fetch_all() avaialble, you can just manually loop through:
$user_alerts = array();
while($row_alert = mysqli_fetch_array($result_user_alerts)){
$user_alerts[] = $row_alert;
}
A cautionary note: The way this is structured, however, seems like it could be better-executed with some better queries - I don't know the details of your application, but when you're matching values from two SQL queries in a PHP loop, that matching can usually be done more quickly and efficiently by the database.
I am having trouble with ezpdf. it works fine for first row of recordset, however I am unable to get all rows of the recordset in ezpdf. it seems that ezpdf somehow ends working after the first record and just creates the pdf file anyway.
Here is what I am doing.
Getting order details from a transaction table and generating tickets based on the quantity in the order. So let's say it has 3 tickets to generate in an order, the pdf will only generate the ticket for first row. It does not accumulate the data of 2nd and 3rd row.
Here is my code.
http://pastebin.com/DMaZUpqw
Please help.
Thanks
Ali
Well if I got that correctly it is supposed to print multiple of those tickets onto on pdf document. Why is this line commented out?:
#$pdfid = $pdf->newPage(1, $pdfid, 'after');
wouldn't you have to add another page before going on printing stuff there?
If $RowsTkt actually returns multiple rows, there is no way, it only iterates once.
Have you checked (by dumping an index or such) that the loop actually does not execute three times as you implied?
Regards
STEFAN
I have run into this problem multiple times, and I cannot figure out why it happens. When I build a MySQL statement like the following it works just fine:
$sql=mysql_query("SELECT * FROM table WHERE id='$something'");
while($row=mysql_fetch_array($sql)){
$someVar=$row['whatever'];
//and so on
}
But when I combine the first two statements to the following:
while($row=mysql_fetch_array(mysql_query("SELECT * FROM table WHERE id='$something'")))
and try to loop through them, the page seems to loop infinitely without loading or returning an error. Why doesn't the second statement work?
mysql_query executes the query and returns a record id which mysql_fetch_array uses to fetch the next row. When you chain them together like you've tried doing, each iteration of the while loop will exectute the query, return a new record id and fetch the first row. As long as there's at least one row, it'll end up doing this in an infinite loop.
I have a friend who's using FluxBB and he has just installed a modification for this forum software. The viewtopic.php file has a while-loop which does a mysql_fetch_assoc() on a result object. Inside of this loop there's a second mysql_fetch_assoc() on a second result object.
The reason for the nested while loop is that there are many posts, and each posts HasMany thank-you's.
Here's some code to better illustrate what I mean:
$result = mysql_query("some-query");
while($cur_post = mysql_fetch_assoc($result)) {
// For every post, execute this second query
$secondResult = mysql_query("some-query that uses the $cur_post id");
while($thank_you = mysql_fetch_assoc($secondResult)) {
// Display the thank_you
}
}
The problem is that the outer-most while loop stops after just one iteration when using the second mysql_query. It does work if the first query is run again, which is a ridiculously dirty hack that works fine with OFFSET.
To me it seems that when the second mysql query is run, whatever $result is pointing at is invalidated. However, I barely know PHP so that's why I've come to SO with this problem.
How would you go about solving this issue? Is it correct that the $result pointer is affected by the second mysql query?
mysql_query() sends a unique query
(multiple queries are not supported)
to the currently active database on
the server that's associated with the
specified link_identifier.
Youll have to grab all your posts (or a batch of them) and store the ids or whatever other data you need into an array or object and then iterate over it making the appropriate query and displaying output.
Or you could use some sql like this:
SELECT thank_you.* FROM thank_you, post WHERE post.id = thank_you.post_id ORDER BY thank_you.post_id;
Of course with this you lose grouping youd have to add some extra logic to build the proper presentation structures based on if the post_id has changed within the loop.