Skip to content


PHP landmines compiled

These are some gotchas and land-mines (re)discovered  while writing in one of the most loved and hated languages around the world. There are more, of course, and You are welcome to post those You experienced and let go the anger of those sleepless nights :)

Circular references

Create two objects, and have them store each other references as properties, and GC will never touch them. Example:

class Parent
{
    public function __construct()
    {
        $this->child = new Child($this);
    }
}

class Child
{
    public function __construct(
        Parent $parent
        )
    {
        $this->parent = $parent;
    }
}

There are a few user space solutions to this problem, such as creating a destructor for the parent class that will release the child object directly. It is fixed (they say) in 5.3, but major places run PHP <5.2.x  and there PHP is not as good as other languages for long running processes like daemons or workers.

Require_once performance hit

When running code requires/includes a file, PHP must call a realpath() for every require()-ed file and to that for every directory in current include_path. All these boil down to system calls that duplicate for every require_once() compared to just require()

Zero string and NULL comparison bite

if ("0" == false) //true
if ("0" == NULL)  //true
if ("0" == "NULL")//true

Solution is to use === and check for type.

Foreach side effects on array pointer

It IS in the manual, but nevetheless:

foreach has some side effects on the array pointer. Don’t rely on the array pointer during or after the foreach without resetting it.

Avoid silencer (@)

Try avoiding following example: @include ’somefile.php’ it will disable You from knowing of any errors in included file and the web page will silently die blank on you. There are good uses of @ silencer, but just when you really know what are you doing.

Lexical scoping

Let file include_this.php contains something like this:

...
$i = 33;
...

And main.php use it in a loop like this:

...
for ($i=0; $i<100; $i++) {
include include_this.php
}
...

This will cause endless loop. If $i should be greater than 100 (loops max) then the file would be includes only once. Not the original intention anyways. Huh?

Passed by value faster than passed by reference

If you have big array to iterate on, it is better (as in faster) to pass it by value as opposed to passing it bt reference. There is some inner magic that optimizes this internaly.


function t1(&$ary) {
    $ary = range(0, 100000);
    $startTime = microtime(true);
    for ($i= 0;$i< 1000; $i++) {
        $iC = count($ary);
    }
    $stopTime = microtime(true) - $startTime;
   print "took $stopTime seconds\n";
}
$ary = array();
t1($ary);

Workaround this is to use a temporary local variable inside the loop, and at the end copy it to the reference variable.

ERROR_ALL

While developing always set error reporting to ERROR_ALL. This will save you many many hours of debugging and wandering through the mysterious byte ways…

To avoid many of these problems You should (read: must) use debug and profile your code!

What are the problems You encountered while using PHP or anyother (programming) language in day-to-day work?

Posted in development. Tagged with , , , .

0 Responses

Stay in touch with the conversation, subscribe to the RSS feed for comments on this post.

Some HTML is OK

(required)

(required, but never shared)

or, reply to this post via trackback.


Premium Wordpress Plugin