Upcoming features in PHP 5.3

PHP 5.3 alpha1 just got released yesterday, and I thought this might be a good time to list some of the new things that are coming, and how it could benefit you. Even though its a minor release, a lot of new features made it in and from a marketing standpoint it should have really been 6.0, if you'd ask me.

Namespaces

A subject touched and trialed many times in PHP, namespaces. This feature has been responsible for the longest discussions on PHP-DEV, but finally a consensus has arrived on how this is going to work.

The biggest benefit namespaces will provide is shortening of long classnames. To make sure that your class libraries can plug into foreign code, it has always been recommended to prefix your classes, for example "Zend_DB_Connection". This can however lead to very long names. Namespaces fixes this by grouping classes together. The full-on classname becomes Zend::DB:Connection, and by placing 'use Zend::DB' on top of your code, the 'Connection' class can be referenced with just that name.

Example:

<?php

// The class file
namespace Zend::DB;

class Connection {

   function foo() {

      echo 'bar';

   }

}
?>
<?php

require 'Zend/DB/Connection.php';

use Zend::DB::Connection;

$connection = new Connection();
$connection->foo();

?>

Using namespaces, its also possible to alias classnames.

<?php

use Zend::DB::Connection as MyConnection;

$connection = new MyConnection();

?>

Furthermore, constants and functions can also be namespaced, but they cannot be directly imported. This means that if you create a function 'myFunction' in the 'Connection' file mentioned earlier, you cannot import Zend::DB:myFunction, but you can import Zend::DB and reference the function as DB:myFunction().

It is recommended to always place your 'use' statements on the beginning of any file, and they will be in effect for the complete file. Note that (AFAIK) this is the first language feature in PHP where the filename holds relevance to the execution, and this can cause some issues for people who like to concatenate their sourcefiles for faster loading. This holds true for both the 'namespace' and the 'use' statements.

Documentation is available, but it is warned it could be out of date.

Late static bindings

Not a really descriptive name from an end-user point of view, but this feature adds some more flexibility in class inheritance.

In short: when you reference a different method or property in a class belonging to a parent class using the self:: keyword the called class would no longer have a static reference to the calling class, as self:: references the current class and not the class from which it was called from. This basically adds method overriding to static methods calls. If this is still kind of cryptic, the best example can be found in the manual.

__callStatic

Using the magic function __call, calls to undefined methods could be intercepted and handled in a different way. PHP 5.3 adds __callStatic, which adds the same functionality to static method calls.

Example:

<?php

class MyClass {

  static function __callStatic($name, $arguments) {

    echo "Hi! You just called the method '$name', but it doesn't exist. Perhaps you mistyped";

  }

}

MyClass::unknownMethod('hii!');

?>

Of course, there's better usages than lame error messages. (documentation)

Closures

My personal favourite. Closures (or: Lambda functions) allow you to create in-line functions. Many languages already have this feature, and if you ever did any javascript programming, you probably already used it without knowing about it.

Example:

<?php

$myFunction = function() {

  echo "Hello world!";

}

$myFunction();

?>

Before, this could only be achieved with create_function, which is pretty much an eval() function with lipstick (and a really bad idea).

The variable type of a closure is an object of the class 'Closure', so it can also be used for type-hinting and validation.

<?php

  function setSomeEvent(Closure $myClosure) {

  }

?>

PHP closures also allow referencing variables from the namespace it was created, with the 'use' keyword.

<?php

  $prefix = 'hello';

  $myClosure = function($name) use ($prefix) {

     echo $prefix, ' ', $name;

  }

  $myClosure('your mom'); // Guess the output doesn't actually makes sense, but you get the idea

?>

Documentation is not part of the manual yet, but can be found on the php wiki

__invoke

PHP 5.3 also adds another magic method, allowing you to treat your own objects as if they were closures.

<?php

class MyCustomClosure {

   function __invoke() {

      echo "I'm not really a closure, but you can treat me as such\n";

   }

}

$closure = new MyCustomClosure();
$closure();

?>

My #1 feature request is to make sure both classes using __invoke and actual closures implement an interface, this would allow us to easily identify an object as invokable. (e.g.: an Invokable or Callable inteface). This has been requested on the PHP internals mailing list, as we speak.

Phar

Phar is PHP's answer to java's JAR files. A PHAR file is a compressed archive and can contain a complete PHP application. This is really cool, as it would allow utilities like PHPMyAdmin to be distributed and used as a single file.

I'm quite excited to use this and see widespread adoption across ISP's. The best part is that you don't need the extension to make use of it, but it will run better and faster if it is.

When it is installed, it will allow referencing files from the phar using for example:

<?php

  file_get_contents('phar:/full/path/to/pharfile.phar/mydata');
  require 'phar:/full/path/to/pharfile.phar/myscript.php';

?>

More extensions

  • intl, an internationalization library (not enabled by default).</a>
  • fileinfo, has been around for a while, but because its enabled by default now we can finally rely on it being there.
  • sqlite3, enabled by default! yay!</p>
  • MySQLND, which is a drop-in replacement for the common MySQL driver for PHP. The 'ND' stands for 'Native Driver', which means its tightly built around the PHP engine and can give you some performance boosts.
  • </ul>

    Other language improvements

    The ternary (?:) operator's 'true' clause is now optional, this means that:

    ```php ```

    Can be shortened to:

    ```php ```

    Also, 'NOWDOC' is introduced. NOWDOC works like HEREDOC, except that variables aren't evaluated and is treated as a 'single quoted string' in PHP.

    ```php ```

    Other significant additions

    • date_add(), date_sub(), date_diff() and their OOP equivalents.
    • A garbage collector! No documentation on this yet.
    • Lots of new SPL classes, such as SplStack, and SqlQueue.
    • The __DIR__ constant, which can be used as a replacement to the often used: dirname(__FILE__). This allows for example easy file-inclusion and could be optimized by for example APC, which was not easily possible with dirname(__FILE__).
    • New process control functions, for example allowing you to catch process signals from the operation systems while avoiding the (now depreciated) declare(ticks=1) statement.

    Conclusion

    Its great to see PHP is an alive language, and especially language improvements such as closures and namespaces bring PHP on par with other popular scripting languages. This stuff definitely makes me a happy person. We won't be using 5.3 in production, as we'll want to wait till 5.3.1 for things to stabilize a little bit, but I hope that day arrives soon.