Please shake your head in sympathy at this bit of terrible design in PHP’s class handling. The code below is a simplified sample version of some real code I was working on last night.

$ cat foo.php
error_reporting( E_ALL ^ E_STRICT );
class Dog {
protected $_bark;
function __construct() {
$this->_bark = 'Generic woof';
function speak() {
print $this->_bark . "n";
class Chihuahua extends Dog {
function set_bark() {
$this->_bark = 'Yip yip';
$doggie = new Chihuahua();
$doggie->speak(); // Generic bark
$doggie->speak(); // Specialized bark
$ php foo.php
Generic woof
Yip yip

That’s about what you’d expect, right? Call a method in the subclass to modify something in the parent class, and then print it out. Nothing goofy, right?

Last night, I spent at least an hour figuring out why my code was still printing “Generic woof” instead of “Yip yip.” Finally, I tried printing out my $doggie object with print_r, PHP’s dumper mechanism, and it all became clear.

$ php foo.php
Generic woof
Generic woof
Chihuahua Object
[_bark:private] => Generic woof
[_bark] => Yip yip

It turns out that at some point I had made $_bark private in the Dog base class, thus breaking the ->set_bark() method. What is so infuriating is that instead of telling me that I was trying to modify a private class member, PHP decided to make a separate class member that Chihuahua could see, different from the member in the base class. It created a class member that I did not declare myself.

I’d love to know the logic behind this design decision. Best I can figure, it was to allow future modifications of base classes without causing name conflicts, but as far as I’m concerned, silently letting people do The Wrong Thing, even with warnings maximized is exactly the wrong behavior. PHP’s tendency to silently ignore problems has always frustrated me.

As programmers, we should optimize for telling other programmers that something is wrong, rather than sweeping it under the carpet. Naked Perl doesn’t do this, of course, but that’s why we have warnings and strict.