Articles on why PHP sucks are fairly common (PHP is a really easy target). So rather than repeat what’s already been said (lack of namespaces, function naming, and argument positions, etc), I though I’d try and come up some more obscure ‘features’ and ‘bugs’ in PHP that I hate.

create_function()

//  Actually creates a new named function, in the global namespace every
//  time it's called, even if it's called with the exact same arguments.
//  Syntax is pretty bad too, need to pay close attention to quoting strings

$args = '$r';
$body = 'return $r;'

$f1 = create_function($args, $body);
$f2 = create_function($args, $body);

// Displays false
var_dump($f1 == $f2);

Automatic creation of class members

//  This should throw a E_NOTICE, or E_STRICT (though I do believe that PHP needs a
//  way to add members,  as it is sometimes is useful.  Maybe allow it on stdclass,
//  and not user defined classes?)

// Completely valid code
$foo = new stdClass();
$foo->bar = "abc"

//  You can take this one step further (still valid PHP)
$bar->xyzzy = "abc";
echo $bar->xyzzy;

Scope, wonderful scope

$numbers = array(1,2,3);
foreach($numbers as $number)
{
    echo $number . "\n";
}

//  This should throw a error notice of Undefined variable
//  instead is prints 3
echo $number . "\n";

extract()

extract() works in a similar method to register.globals, while it’s safer (you can make sure it never overwrites existing variables) it still is a really bad idea.

Late static binding

class aParent
{
    static $phrase = "Goodbye";

    public static function SayHello()
    {
        printf("%s %s from class %s\n", self::$phrase, self::GetWorld(), get_class());
    }

    public static function GetWorld()
    {
        return "Universe";
    }
}

class aChild extends aParent
{
    static $phrase = "Hello";

    public static function GetWorld()
    {
        return "World";
    }
}

//  All good here...
//  Displays:       'Goodbye Universe from class aParent'
//  Should display: 'Goodbye Universe from class aParent'
aParent::SayHello();

//  Not so good here though...
//  Displays:       'Goodbye Universe from class aParent'
//  Should display: 'Hello World from class aChild'
aChild::SayHello();