Translate: 
EnglishFrenchGermanItalianPolishPortugueseRussianSpanish

What’s new in PHP 5.4? A huge list of major changes!

The PHP 5.4 is now available.

As you probably know, the updates that were intended for postponed PHP 6 were added to PHP 5.4.0 instead, so now PHP includes a huge set of new language features and removes several legacy behaviors.

Because of that I created a list of major changes since PHP 5.3 ,along with some examples and brief descriptions of these changes…

Major PHP improvements

Changes since PHP 5.3 version include:

  1. Added class member access on instantiation.

    Now you can use fluent interfaces like in Java:

    $myCar = (new Car)->setSpeed(100)->setColor('blue');
  2. Added callable typehint.

    This typehint allows a string with a function name, a closure, and an array composed of classname (or object) with method name.

    <?php
    function foo(callable $cb) {
        $cb();
    }
    ?>
  3. Added closure rebinding as parameter to bindTo.

    Closure::bindTo() has been modified so now it accepts another argument that defines the new scope. This can either be an object if its class is used as the scope, or a class name.

    class A {
        private $x;
     
        public function __construct($v) {
            $this->x = $v;
        }
     
        public function getIncrementor() {
            return function() { return ++$this->x; };
        }
    }
     
    class B extends A {
        private $x;
     
        public function __construct($v) {
            parent::__construct($v);
            $this->x = $v*2;
        }
    }
     
    $a = new A(0);
    $b = new B(10);
     
    $ca = $a->getIncrementor();
    var_dump($ca());
     
    echo "Testing with scope given as object", "\n";
     
    $cb = $ca->bindTo($b, $b);
    $cb2 = Closure::bind($ca, $b, $b);
    var_dump($cb());
    var_dump($cb2());
     
    echo "Testing with scope as string", "\n";
     
    $cb = $ca->bindTo($b, 'B');
    $cb2 = Closure::bind($ca, $b, 'B');
    var_dump($cb());
    var_dump($cb2());
     
    $cb = $ca->bindTo($b, NULL);
    var_dump($cb());

    Result:

    int(1)
    Testing with scope given as object
    int(21)
    int(22)
    Testing with scope as string
    int(23)
    int(24)
  4. Added short array syntax.

    Makes PHP code more readable and maintainable.

    $a = [1, 2, 3];
    $b = ['foo' => 'orange', 'bar' => 'apple', 'baz' => 'lemon'];
  5. Added binary value format.

    Now it’s possible to use binary values directly in the PHP code:

    $x = 0b001110;
    echo $x;
  6. Added support for Class::{expr}() syntax.

    Makes PHP more flexible, when calling class/object methods.

    $method = 'method';
     
    $test = new Test();
     
    $test->method();
    $test->$method();
    $test->{'method'}();
     
    Test::method();
    Test::$method();
    Test::{'method'}();

    Result:

    method
    method
    method
    method
    method
    method
  7. Added support for Traits.

    A Trait is intended to reduce some limitations of single inheritance by enabling a developer to reuse sets of methods freely in several independent classes living in different class hierarchies.

    class Base {
        public function sayHello() {
            echo 'Hello ';
        }
    }
     
    trait SayWorld {
        public function sayHello() {
            parent::sayHello();
            echo 'World!';
        }
    }
     
    class MyHelloWorld extends Base {
        use SayWorld;
    }
     
    $o = new MyHelloWorld();
    $o->sayHello();

    Result:

    Hello World!
  8. Added closure $this support back.

    Now you have an access to every object property (be it public or not).

    class A {
        private $value = 1;
     
        function firstGetter($name) {
            return function() use ($name) {
                return $this->$name;
            };
        }
     
        function secondGetter() {
            return function($name)  {
                return $this->$name;
            };
        }
    }
     
    $a = new A();
    $firstGetter = $a->firstGetter('value');
    echo $firstGetter();
    $secondGetter = $a->secondGetter();
    echo $secondGetter('value');

    Result:

    1
    1
  9. Added array dereferencing support.

    Provides the implementation of array dereferencing of method/function return.

    function fruit () {
        return array('a' => 'apple', 'b' => 'banana');
    }
     
    echo fruit()['a'];

    Result:

    apple
  10. Added indirect method call through array.

    Now $foo() also works in the cases where $foo is a callable array or Closure object.

    class Hello {
        static public function world($x) {
            echo "Hello, $x\n";
        }
    }
     
    function helloWorld($x) {
        echo "Hello, $x\n";
    }
     
    $callbacks = array(
        array('Hello', 'world'),
        function ($x) { echo "Hello, $x\n"; },
        'helloWorld'
    );
     
    foreach ($callbacks as $k => $callback) {
        if (is_callable($callback)) {
            $callback($k);
        }
    }

    Result:

    Hello, 0
    Hello, 1
    Hello, 2
  11. Changed $GLOBALS into a JIT autoglobal.

    $GLOBALS array is initialized only if it’s used. This is a performance/memory optimization, it can however break some of the existing scripts or opcode caches.

  12. Improved performance of @ (silence) operator.

    This can speed up PHP scripts which rely heavily on a silence operator, for example:

    $x = @file_get_contents('/etc/passwd');
    echo $x;
  13. Added multibyte support by default.

    Previously php had to be compiled with –enable-zend-multibyte. Now it can be enabled or disabled through zend.multibyte directive in php.ini.

  14. Added built-in web server that is intended for testing purpose.

    The following command will open a web server on the port 8000.

    php -S localhost:8000
  15. Lots of performance and memory usage improvements

Removed major PHP features

  1. Removed break/continue $var syntax.

    You can no longer use variable to tell PHP how many levels of enclosing loops it should skip to the end of.

  2. Removed safe mode and all related ini options.

    Functionality described in this article and marked as depreciated in PHP 5.3 has now been removed

  3. Removed register_globals and register_long_arrays ini options.

    If enabled, register_globals injected PHP scripts with all sorts of variables, like request variables from HTML forms or values from GET requests. Now, every request/environment variable must be fetched from an appropriate PHP array.

  4. Removed allow_call_time_pass_reference option.

    Passing arguments by reference at function call time was deprecated for code-cleanliness reasons. A function can modify its arguments in an undocumented way if it didn’t declare that the argument shall be passed by reference. To prevent side-effects it’s better to specify which arguments are passed by reference in the function declaration only.

For a full list of changes in PHP 5.4, see the ChangeLog. For source downloads please visit php.net QAT downloads page, Windows binaries can be found here.

13 Responses to “What’s new in PHP 5.4? A huge list of major changes!”

  1. That seems like a massive progress, that’s great!
    Thank you for the useful information.

  2. Satish Maurya says:

    I guess your version of traits is different from PHP.net, could you please check.

  3. RF says:

    Thanks for this list.

    Shouldn’t the result of the example code in “7. Added support for Traits.” be “Hello Universe!” rather than “Hello World!”?

  4. Artur Graniszewski says:

    Yes, you’re right. I fixed this just a moment ago. Thanks for the info.

  5. RF says:

    Sorry for nitpicking again, but you the example code too. Now “Hello World!” would be the right output. :-)

  6. Artur Graniszewski says:

    Thx:) I forgot to change the output also.

  7. anse says:

    Seems traits are again a way to get behind object oriented code, rendering objects useless, similar to calling object methods statically.

  8. [...] mark those new features as syntax errors but I hope that they will support them soon. More info here LD_AddCustomAttr("AdOpt", "1"); LD_AddCustomAttr("Origin", "other"); [...]

  9. Bud Manz says:

    Thanks for the list, I am wondering how much more efficient the silence operator (@) is… I know it is pretty costly in 5.3 and back

    Bud

  10. These are really cool features. PHP rocks!!!

  11. Tom Wardrop says:

    It’s funny. I left PHP for Ruby almost two years ago, mostly because of PHP’s sloppiness when it came to it’s syntax limitations and API’s, compounded by the developers seemingly lack of care to change this. Looking at these changes, it seems a lot of the things that use to frustrate me have been fixed. Changes 1, 2, 4, 6, 7, 9, and 14 are all things which were long overdue. I’m grateful they’ve finally been implemented, but at the same time saddened by how long it has taken PHP to drop its past and catch up to other modern languages like Ruby.

    Ever since moving to Ruby, touching any PHP has been a real dampener. These changes in 5.4 may be enough to motivate me to write my latest project in PHP, as surprisingly, the project I have in mind suits itself to PHP’s environment more so than Ruby’s.

  12. Mike Graf says:

    @Tom

    I was thinking just like you were. Many of these changes feel Ruby (or Rails) -ish … Like the built in testing web server (webrick?), traits give us even more Duck Typing feel etc.

    Thanks for this list, it was a good summary
    -Mike Graf

  13. Ayesh says:

    Thanks!
    Good bye, register globals!

Leave a Reply