PHP: $i = $i++ crashed the server - php

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

Related

PHP: For loop will not execute

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

will White Spaces, Comments, Empty Lines increase PHP excution time? [duplicate]

This question already has answers here:
Commenting interpreted code and performance
(9 answers)
Closed 9 years ago.
i have this doubt from many days. in every PHP code i write, i will write many comments, leave many white spaces and leave 4 to 5 empty lines between section and section (to make it clear for me)
will all these empty spaces, comments, empty lines make my PHP code to run slow ?
personal experiences are much appreciated :)
This is really a matter of IO and hard drive speed. If your bare file is 10KB and comments and line breaks add 4KB then the extra time that the hard drive spends reading more KB is what you need to benchmark (it's negligible by the way), not even worth your time.
If you start getting into micro-optimization then you run the risk of making your code absolutely horrid to read and maintain.
The best way to speed up your code is to re-factor code where necessary and don't do silly things that obviously hog resources like this crude example:
<?php
$arr = array(); // pretend it has 50,000 items
//GOOD IDEA: count the array once and reference that number
$arr_count = count($arr);
for($i=0; $i < $arr_count; $i++){
echo $arr[$i];
}
//BAD IDEA: re-counting the array for every iteration
for($i=0; $i < count($arr); $i++){
echo $arr[$i];
}
?>
Also unsetting a large array after you are done using it is better than waiting for the Garbage Collector to kick in. For example: pulling data from DB and looping through it. Unset the data when done and keep coding.
Comments and white space are completely ignored when the code is run. You can think of all that extra stuff as being completely wiped away once your done and the code is doing its thing.
Extra white space and comments are solely there for you and fellow coders to be better able to read and understand your code. In fact, if you don't use extra white space and comments, coders will get angry with you for writing and providing terrible code!
Consider the following code.
<?php
$time = round(microtime(true) * 1000);
for($i = 0; $i < 1000000; $i++) {
/*
*/
}
echo (round(microtime(true) * 1000) - $time) . "<br/>";
$time = round(microtime(true) * 1000);
for($i = 0; $i < 1000000; $i++) {
}
echo (round(microtime(true) * 1000) - $time) . "<br/>";
?>
There are times that the first is faster and others that the second is fast. So comments do not affect the speed.
Not really, is the simple answer for general scripts and coding.
It's likely that if you were having to consider gaining a few milliseconds here and there, and removing comments was affective, A) you have too many comments, and B) you'd already know about it all and be performing benchmarks etc.
The amount of comments is usually proportionate to the amount of code you have. ie a line or two of comments for a load of IF/ELSE, setting vars to POST or SESSIONS etc, and DB queries etc. And as the majority of PHP's time parsing a script is opening the file, accessing memory, checking thousands of things including cache etc, reading and executing the code, accessing database etc, the time taken to ignore your comments is probably .001%
Comments are used by you, and possibly other developers, to understand the code. Just keep them neat and try to keep them as short as possible while remaining concise, factual and useful.

Determining if next iteration is going to happen

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

Foreach or While -- Best for processing array?

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/

PHP Shorthand Addition Operator - Undefined Offset

I'm using the PHP shorthand addition operator to tally the number of times a specific id occurs within a multidimensional array:
$source['tally'] = array();
foreach ($items as $item) {
$source['tally'][$item->getId()] += 1;
}
The first time it hits a new id, it sets its 'tally' value to 1 and then increments it each time it's found thereafter.
The code works perfectly (I get the correct totals), but PHP gives me an "Undefined Offset" notice each time it finds a new id.
I know I can just turn off notices in php.ini, but figured there must be a reason why PHP doesn't approve of my technique.
Is it considered bad practice to create a new key/offset dynamically like this, and is there a better approach I should take instead?
Please Note: To help clarify following initial feedback, I do understand why the notice is being given. My question is whether I should do anything about it or just live with the notice. Apologies if my question didn't make that clear enough.
You have to understand that PHP notices are a tool. They exist so you have additional help when writing code and you are able to detect potential bugs easily. Uninitialized variables are the typical example. Many developers ask: if it's not mandatory to initialize variables, why is PHP complaining? Because it's trying to help:
$item_count = 0;
while( do_some_stuff() ){
$iten_count++; // Notice: Undefined variable: iten_count
}
echo $item_count . ' items found';
Oops, I mistyped the variable name.
$res = mysql_query('SELECT * FROM foo WHERE foo_id=' . (int)$_GET['foo_id']);
// Notice: Undefined index: foo_id
Oops, I haven't provided a default value.
Yours is just another example of the same situation. If you're incrementing the wrong array element, you'd like to know.
If you simply want to hide the notice, you can use the error control operator:
$source['tally'] = array();
foreach ($items as $item) {
#$source['tally'][$item->getId()]++;
}
However, you should generally initialize your variables, in this case by adding the following code inside the loop:
if (!isset( $source['tally'][$item->getId()] ))
{
$source['tally'][$item->getId()] = 0;
}
Using += (or any of the other augmented assignment operators) assumes that a value already exists for that key. Since this is not the case the first time the ID is encountered, a notice is emitted and 0 is assumed.
It's caused because you don't initialize your array to contain the initial value of 0. Note that the code would probably work, however it is considered good practice to initialize all the variable you are about to preform actions upon. So the following code is an example of what you should probably have:
<?php
$source['tally'] = array();
foreach ($items as $item) {
//For each $item in $items,
//check if that item doesn't exist and create it (0 times).
//Then, regardless of the previous statement, increase it by one.
if (!isset($source['tally'][$item->getID()]) $source['tally'][$item->getID()] = 0;
$source['tally'][$item->getId()] += 1;
}
?>
The actual reason why PHP cares about it, is mainly to warn you about that empty value (much like it would if you try to read it). It is a kind of an error, not a fatal, script-killing one, but a more subtle quiet one. You should still fix it though.

Categories