What’s new in PHP 5.4

<?= — short echo syntax always works

Wiki: https://wiki.php.net/rfc/shortags

The short syntax being discussed is <?= instead of <?php echo.

For the long and short syntax to work in versions below 5.4, the short_open_tag option in php.ini had to be enabled.

Example of long and short syntax:

<a href="#"><?php echo $page ?></a>
<a href="#"><?= $page ?></a>

[1,2] — array syntax, without the word array

wiki: Short syntax for arrays

$a = [ 1, 2, 3, 4 ];
$a = [ 'one' => 1, 'two' => 2, 'three' => 3, 'four' => 4 ];

trait Class {} — traits

A trait is an analogue of a class that contains methods. It is needed for “mixin” into an existing class so that the trait’s methods become methods of the class to which it is added.

Several traits can be specified separated by a comma:

trait TR_A {
	public $var = 'var';
	function foo() { return 'foo'; }
}

trait TR_B {
	function bar() { return 'bar'; }
}

class A {
	use TR_A, TR_B; // mix in

	function hello() { return 'hello A'; }
}

$A = new A();
echo $A->foo();   // foo
echo $A->bar();   // bar
echo $A->hello(); // hello A
echo $A->var;     // var

class B extends A {
	use TR_A, TR_B;

	function hello() { return 'hello B'; }
}

$B = new B();
echo $B->foo();   // foo
echo $B->bar();   // bar
echo $B->hello(); // hello B

Trait precedence

When property/method names collide, the priorities are as follows: the current class has the highest priority, then the trait, and then the extended class. In other words: elements from the current class override elements in the trait, which in turn override inherited elements.

Static access to a trait’s method from a class

When a trait is mixed into a class, its methods become class methods, including static and static access:

trait A {
	static function func(){ echo 'A'; }
}

class B {
	use A;
}

B::func(); //> A

Read more about traits in the documentation

http://php.net/manual/ru/language.oop5.traits.php

foo()[0] — fast array access

Now there is no need to store the array returned by a function/method in a variable and access an element of the array from that variable. You can directly access an element from a function/method:

$foo = func()[0];
$foo = Class::func()[0];

(new Foo)->method() — object element access at creation

$foo = (new Foo)->method();
$foo = (new Foo)->property;
$foo = (new Foo)[0];

// previously it was like
$obj = new Foo;
$foo = $obj->method();

Class::{ 'foo' }() — dynamic method invocation

To call a static class method/property without storing it in a separate variable:

class A {
	static function foo() {
		echo "Hello world!";
	}
 }
 $x = "f";
 A::{ $x .'oo' }();

callable — new type for function/method arguments

Auto-check of transferred data in functions/methods, known as type hinting, continues to develop and now understands the word callable.

Previously, for automatic type checking of a parameter, in the function/method arguments you could specify only: array or the class name.

Now you can also specify: callable — means that the passed argument must be callable, i.e. satisfies is_callable( $arg, false ).

Example:

function func( callable $callback ){
	return true;
}

func('trim'); //> true

func( function(){} ); //> true

$db = new wpdb();
func( array($db, 'query') ); //> true

func('my_trim'); //> fatal error: Argument 1 passed to func() must be callable, string given

@ — improved performance

The @ operator is used to suppress errors of any level. It is generally not recommended to use it, but sometimes it is shorter:

if( @ $_GET['foo'] ) echo 'OK';

// or like this
if( isset($_GET['foo']) && $_GET['foo'] )  echo 'OK';
// used to work faster by about 20 times, now about 5 times

Use @ as rarely as possible and very carefully, because notes and warnings often indicate that the code logic is not correct. For example, I’ve had occasions where I tried to fix a seemingly harmless NOTICE, but analysis shows the error appeared due to incorrect logic that changed during code expansion...