PHP... what to say?
It's not uncommon to hear people complain about all sorts of things. After all, it's what most people do best. However, hearing experienced PHP developers complain about PHP is something that worries me. It worries me because it's not just one developer who's complaining, but multiple independent people. Unfortunately, I'm beginning to become one of those developers.Back in the days when I first discovered web programming, PHP was the language of choice for anyone who wanted to do more with their "homepage" than just displaying some dead HTML. It must've been around the time when PHP 4 was brand new. Of course there was Perl, but for a lot people my age - myself included - this was just too complicated. PHP has come a long way since that initial 4.0 release. Among many things, PHP 5 finally provided a somewhat decent object model, which was a welcome addition for a lot of people.
As PHP 5 matures, so does it's object model. The upcoming PHP 5.3 release will provide a lot of cool new things that were originally planned for PHP 6.
So, how does this relate with the complaints about PHP? Even though PHP 5.3 and PHP 6.0 will be a great step forward, it seems that the language itself is extremely divided. On the one hand, it tries to please the procedural programmers with the trusted PHP functions. On the other, Zend is trying to please Object Oriented programmers with Zend Framework. Then there is the group of legacy apps. Unfortunately, PHP is trying to please these as well. It looks like maintaining compatibility with old and badly written scripts is still a goal of PHP 6.
In my opinion PHP 6 will make or break PHP as a language. For PHP to make it, it needs a clear vision of what it wants to be. Trying to maintain compatibility with ancient and mostly poorly written scripts can't be part of this vision. Both PHP 5.3 and the Zend Framework indicate to me that PHP wants to become a more mature OO language. A lot of the new features that support this vision and were supposed to appear in PHP 6 have already appeared in PHP 5.3. This is a good thing, because it allows more room for changes in PHP 6. Also, it makes PHP 6 a good candidate to finally break some BC if this should be needed. I compiled a list of things I'd like to see in PHP 6. Hopefully it will be of some use in order to prepare PHP 6 for the future.
A String object
There has been a lot of complaining about the parameter order of some string functions. Solving this problem by re-ordering the parameters would mean a lot of BC breakage. In my opinion this shouldn't be needed. Instead I'm going one step further:
Deprecate the string functions in favor of a string object.
Using the string functions in PHP 6 should throw an E_NOTICE (or E_DEPRECATED, thanks Matthew) explaining that these functions have been deprecated. The lack of a string object has caused me duplicate code more than once. Also, it just makes sense to say:
$string = 'Hello World!'; echo $string->subString(0, 5); // echos Hello
This doesn't only make sense, it is done in virtually every other mature OOP language out there.
Traits
Quoted from a PHP RFC about Traits: "Traits is a mechanism for code reuse in single inheritance languages such as PHP." Read this page, it gives a much better explanation on traits than I'll be able to post here.
Method overloading
Even though PHP is a dynamic language, it can still benefit from method overloading. In some situations it can save some nasty if statements. Let's have a look at a snippet that should look somewhat familiar to most PHP programmers:
public function getMagicNumber($var)
{
if ($var instanceof Some_Class)
{
$magicNumber = $var->getNumber();
}
else
{
$magicNumber = (int) $var;
}
return $magicNumber;
}
With method overloading this could be rewritten to:
public function getMagicNumber($arg)
{
return (int) $arg;
}
public function getMagicNumber(Some_Class $arg)
{
return $arg->getNumber();
}
Notice the lack of an if statement? This is in my opinion a much cleaner way to make sure you get your magic number.
To make this problem more complicated, we want to provide a seed to the getMagicNumber() method which accepts the Some_Class instance. The normal PHP way of solving this would look something like this:
public function getMagicNumber(Some_Class $arg, $seed = null)
{
if ($seed != null) {
$arg->setSeed($seed);
}
return $arg->getNumber();
}
With method overloading, it could look like this:
public function getMagicNumber(Some_Class $arg)
{
return $arg->getNumber();
}
public function getMagicNumber(Some_Class $arg, $seed)
{
$arg->setSeed($seed);
return $arg->getNumber();
}
Again, this removes a nasty if statement. It may not seem like much in a small example like this, but when you get more complicated method signatures or when it's hard to decide in what order optional arguments should appear it's a life saver.
Mirmo suggested a different approach to the problem where no seed was required. The specific problem in this example could also be solved by creating additional magic methods. Currently there's a __toString() method. Additionally, these methods could be added to allow more control over your objects when typecasting them:
__toInt() __toFloat() __toBool() __toArray()
This could make the above example work with just the non-strict method.
Properties
This is something that could be already vaguely described in the PHP 6 TODO list. It mentions "Property overloading RFC aka abstract/virtual properties and get/set handlers". The way I see properties implemented for PHP 6 looks a lot like C#'s solution:
// Variable
private $_myCollection = array();
// Property
public $myCollection
{
__get
{
return $this->_myCollection;
}
__set
{
$this->_myCollection = value;
}
}
For a PHP programmer this will look familiar, because of the use of magic method naming. This allows more fine-grained control than the current __get and __set magic methods. Of course, these should remain available as well.
Improved type hinting
It is possible to type-hint classes and arrays in methods, but it's not possible to type-hint things like integers or strings. The PHP 6 TODO list shows a done item called "optional typehinted parameters". Hopefully this will cover all sort of parameters. Also, type hinted attributes would be really useful:
private array $_myCollection = array();
To preserve a bit of BC and to not force strict typing on people, all type hinting should remain optional.
Conventions
All naming method arguments, naming of classes, naming of variables, indentation and everything related to writing code should be supported by a well defined, consistent set of conventions. Zend Framework already has a set of conventions. In my opinion it's a good thing to improve these conventions even further and make them apply not only for Zend Framework, but for PHP as a whole. Regardless of whatever framework people use, they should be stimulated to code using one true, official standard. At the moment I can only dream of how much more readable independent software projects would become.
With this I want to end this post. Hopefully PHP 6 will incorporate these and maybe other great features and stop the migration of the more experienced developers to other languages.
Edit, 12 June 2008: Added mirmo's suggestions May 27th, 2008 / Tags: PHP / Trackback