So what I am trying to do is process an array. The array contains one thing: photo urls.
When I use foreach()I get a limit error (500 internal error). It seems that it started happening after I rewrote the script. But that doesnt make any sense as there are no errors in the script and it was working perfectly before. The script still works, it can only process about 30 photos before the error pops up. Is it possible to use while() to process the array? Would it get rid of my 500 error for some reason?
Thanks for the input!
Brandon
If you're getting timeout (infinite loops) errors, neither while or foreach will do. You're better off looking at limiting how much your array is processed, and do it step by step (Pagination..?).
for ($i = 0; $i < 100; $i++)
{
//Do your thing. Don't use for each, use $array[$i]
}
if it's not numeric, use a while with two statements:
while ($test = current($array) && $i < 50)
{
//xxxx
next($array);
$i++;
}
For performance is better foreach cycle.
Visit this site with some benchmark of php and see which cycle is better for you:
http://www.phpbench.com/
Related
I am at a complete loss. I've searched this site extensively and others as to why my for loop, among many other working loops, will not execute, and tried many suggestions. I have checked that it is in fact not executing and not failing to meet a condition for its execution. This is the loop:
if (count($bunnyList)>100){
echo "Too many bunnies! Initiating mass cull.</br>";
for ($i=0; $i===50; $i++){
echo 'something';
unset ($bunnyList[rand(0,(count($bunnyList)))]);
array_values($bunnyList);
}
echo 'Number of bunnies: '.(count($bunnyList));
The if condition executes; the first echo statement executes, and then the echo statement following the loop also executes. If the loop had been executed, then I should get a number of "something"s printed to the page, and yet I never have, even after trying tons of suggestions for other people's failed for loops. After staring at this particular piece of code for hours I'm reasonably sure I haven't messed up a piece of syntax. Please help me, I've already pulled too many chunks of my hair ou
:(
The entire code is over a hundred lines long and I didn't think it prudent to post the whole thing. In addition, all the other for loops within the program work just fine, while endless variations of this one do not.
I apologize if this is a redundant question or if it has been asked before. Other answers to questions similar to mine were not able to fix the problem. Please help me D:
TL;DR Why does only this for loop not execute within my program containing many functioning loops? The echo statements within the if condition do execute.
Try:
for ($i = 0; $i < 50; $i++) {
Instead of:
for ($i = 0; $i === 50; $i++) {
In a for loop, the second part is NOT the ending condition, but the continuation condition. In your case it's checking if $i is equals to 50, and because it is not, it will never go in the loop.
I'm not too familiar with php, more java, but shouldn't it for each time 'I' is less than 50, increment by 1?
for ($i=0; $i < 50; $i++){
...
}
I am assuming that is the syntax.
Try like this:
for ($i=0; $i<=50; $i++){
echo 'something';
unset ($bunnyList[rand(0,(count($bunnyList)))]);
array_values($bunnyList);
}
I have a php script that loops many times. Is there a way in PHP to tell whether it was the last iteration ? Script is rather complex (1700 lines) and I can't locate the snippet responsible for running the script from the beginning.
Ideally I'm looking for a function (put in the end of the file) which predicts whether or not the script is going to run again from the beginning (as it does). Sure, other solutions are welcomed. The amount of iteration depends.
UPD:
Sorry, it's not loop that causes script to start over. There is something else (that I can't define) that makes the page to run from the beginning.
I assume you mean something like this:
$max = 10;
for($i = 0; $i <= $max; $i++) {
if($i == $max) {
//last iteration
}
}
I've never seen a SegFault in PHP before today, but apparently it's possible. At first I thought it was mysql driver, but it turned out it was my code ;).
I spent about 2 days debugging my code and finally tracked it down to it's cause (so to all you future PHP programmers who run into this, you are welcome!)
Long story short, you CAN'T do an unset() on the same array your are walking while you're doing array_walk().
The purpose is to eliminate all elements from $this->votes that don't exist in the $out array (where the key of $this->votes matches to the id property of one of the elements in $out).
The Problem I was having was about half the time the code would run fine, and the other half it would crash with a Segmentation Fault in the apache log (making it pretty hard to debug because it was a while until I noticed this error).
And yea, it's a pretty poorly thought out piece of code to begin with....
array_walk($this->votes, function(&$o, $key) use($that, $out) {
$found = array_filter($out, function($p) use($key) {
return $p['id'] == $key;
});
if(count($found) == 0) {
unset($this->votes[$key]); //very very bad!!!!
}
});
As I understand it, what ends up happening is unset() messes up the $this->votes array length. array_walk uses an iterator which expects the $this->votes array to remain the same length throughout the entire walk. If I wrote my own array_walk function (for ($i = 0; $i < count($this->votes); $i++) it would just throw an undefined index notice. But since we are using array_walk it will actually try to look in a location in memory which may or may not have some data. This can cause the unpredictability of the function (sometimes the code can run just fine, other times it will cause a seg fault).
So the RIGHT way to do it would be
$tmpVotes = array();
array_walk($this->votes, function(&$o, $key) use($that, $out, $tmpVotes) {
$found = array_filter($out, function($p) use($key, $that, $tmpVotes) {
return $p['id'] == $key;
});
if(count($found) > 0) {
$tpmVotes[$key] = $o;
}
});
$this->votes = $tmpVotes;
From PHP Manual:
Only the values of the array may potentially be changed; its structure cannot be altered, i.e., the programmer cannot add, unset or reorder elements. If the callback does not respect this requirement, the behavior of this function is undefined, and unpredictable.
If anyone has a better way of explaining what happens here, please post!
This happened to me a few years ago before I knew about SO, but I'm still curious. When I was still learning the basics of PHP, I accidentally typed $i = $i++; When I tested the webpage in the browser, The server crashed and it took a long time to get it back up. I've typed in some pretty stupid things before and created a bunch of infinite loops, but for some reason, that was the worst. Does anyone know why this line was so 'poisonous'
$i = $i++; is the same as $i = $i; essentially.
Unfortunately $i = $i++; is known as "undefined behavior".
Anything could happen simply because the compiler can't fully comprehend what is going on.
There's an excellent SO question covering similar undefined behavior here.
This should not crash anything.
$i = $i++;
var_dump($i); // NULL;
From the PHP Manual
It is not necessary to initialize
variables in PHP however it is a very
good practice. Uninitialized variables
have a default value of their type
depending on the context in which they
are used.
Also, by default, variables are always assigned by value and since you are using a Post Increment, the value of the uninitialized $i (NULL) is assigned first by copy to $i, effectively overwriting itself. See this code to see what happens:
$i = 0
$i = $i++;
var_dump($i); // int(0);
I don't know if PHP will still try to increment the right hand variable value after the assignment. If you are interested in that, install the PECL extension Parsekit and check the OP codes for further details.
So it was likely something else that crashed your server.
$ php -r '$i=0; $i = $i++; echo "=> ".$i."\n";'
=> 0
I recently ran across some code which the person did the first one. Would like some thoughts on if the top one is better or why a person would write it that way? Any positive reasons over the bottom way.
$result = mysql_query($query)or die("Obtaining location data failed!");
for ($i = mysql_num_rows($result) - 1; $i >=0; $i--)
{
if (!mysql_data_seek($result, $i))
{
echo "Cannot seek to row $i\n";
continue;
}
if(!($row = mysql_fetch_object($result)))
continue;
echo $row->locationname;
}
mysql_free_result($result);
vs
$result = mysql_query($query) or die("Obtaining location data failed!");
while($row = mysql_fetch_object($result)){
echo $row->locationname;
unset($row);
}
mysql_free_result($result);
It looks like the top code is iterating through the mysql result backwards, where the first one is going through it forwards.
The second code example looks cleaner, and there is probably a way to adjust the query to get the results in reverse order in the first place, instead of the somewhat convoluted way the top loop was performed.
Those two are not equivalent since only the first processes the result set in reverse order.
I'd do that with an ORDER BY x DESC clause if only to keep the code simple. When using mysql_query() the complete result set is transferred from the MySQL server to the php process before the function returns and mysql_data_seek() is only moving some pointer within the process' memory, so performace-wise it shouldn't matter much. But if you at some point decide to use an unbuffered query instead it might very well affect the performance.
Definitely the second one :
less code = less code to maintain =~ maybe less bugs !!
The top one has definite advantages when it comes to job security and 'lines of code' performance metrics. Apart from that there is no good reason to do what they did.