Haven’t you switched to PHP7 yet? If not, you should read “How Badoo saved one million dollars switching to PHP7” and consider to change your version. Moreover, remind to update at least to 5.6 version: it’s now the only minor 5.x release that will be supported and not dismissed.
http://php.net/supported-versions.php
Ok, maybe (probably) you’re not going to save one million dollars by switching PHP version, but you can still take advantage of PHP7 optimizations. Check out here some metrics presented by Rasmus Lerdorf himself during PHPDay 2016 in Verona, Italy.
Here I’m going to recap some of the new PHP7 features before switching to 7.1 ones.
Scalar type declarations
This is the main feature along with return type declarations (we’ll talk about it next) of this new major version. From now on you can integrate function declared types (which consist from php5.4 on of Class/Interface names, self
, array, callable) with primitive types such as bool, float, int, string. You have two ways to use this feature: coercive (default) and strict. You can see the differences in the snippets below
1 2 3 4 5 6 7 8 9 10 11 12 |
// coercive <?php function foo(int $a) { echo $a; } foo(1); // 1 foo("2"); // 2 foo(2.5); // 2 foo("foo"); // FATAL ERROR Uncaught TypeError |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
// strict <?php declare(strict_types=1); function foo(int $a) { echo $a; } foo(1); // 1 foo("2"); // FATAL ERROR Uncaught TypeError foo(2.5); // FATAL ERROR Uncaught TypeError foo("foo"); // FATAL ERROR Uncaught TypeError |
You have might noticed that declare(strict_types=1);
is written directly into the file we would like to have a strict type check on. If you’re wondering about a “global directive to activate this feature” I’m afraid to disappoint you: there’s not. The main reason behind this choice is due to third-party libraries: if you write a library (or use it) you want to be free to choose between week type hinting (“old one”), coercive type hinting or strict type hinting. You can read more on official RFC
Return type declarations
You can now specify a return type of a function call. Rules are the same as scalar type declarations explained above.
1 2 3 4 5 6 7 8 9 10 |
<?php function foo(int $a): int { return $a; } echo foo(1); // 1 echo foo("2"); // 2 echo foo(2.5); // 2 |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 |
<?php declare(strict_types=1); function foo(int $a): int { return $a; } function bar(int $a): int { return (string) $a; } function foobar(int $a): int { return (float) $a; } echo foo(1); // 1 echo bar(2); // FATAL ERROR Uncaught TypeError echo foobar(3); // FATAL ERROR Uncaught TypeError |
Null coalescing operator
Please welcome null coalescing operator: ??
Do you recognize this?
1 |
return isset($foo['bar']) ? $foo['bar'] : null; |
with ??
(that is basically only syntactic sugar) you can collapse your code
1 |
return $foo['bar'] ?? null; |
Awesome, isn’t it? And you can also chain them
1 |
return $foo['bar'] ?? $foo['foobar'] ?? null; |
Spaceship operator
Helpful to compare some expression in one line
1 2 3 |
echo 1 <=> 1; // 0 echo 1 <=> 2; // -1 echo 2 <=> 1; // 1 |
returns 0 if comparison operands are equals, -1 if second one is greater than first, 1 if first is greater than second.
Anonymous classes
If you need an object instance of a class that does not exist, you can use anonymous classes
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
<?php $bar = 'bar'; $foo = new class($bar) { private $bar; public function __construct($bar) { $this->bar = $bar; } public function getBar() { return $this->bar; } }; echo $foo->getBar(); // 'bar' |
What I would have expected from this feature is some kind of reusability of the anonymous class
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 |
<?php $bar = 'bar'; $c = class($bar) { private $bar; public function __construct($bar) { $this->bar = $bar; } public function getBar() { return $this->bar; } }; $foo = new $c('bar'); echo $foo->getBar(); $foobar = new $c('foobar'); echo $foobar->getBar(); |
But sadly this results in a
1 |
FATAL ERROR syntax error, unexpected 'class' (T_CLASS) on line number 4 |
So this feature seems to be pretty useless if you look at above examples but one situation where it can be very useful is testing: you can test interfaces by providing a mock on-the-fly and without using complex thirdparty libraries.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
<?php interface Foo { public function getBar(): string; } $foo = new class implements Foo { public function getBar(): string { return 'mock implementation'; } }; echo $foo->getBar(); // 'mock implementation' |
Final thoughts
Above are listed only a subset of features of PHP7 (most interesting ones, imho). Sometimes migrating from one major version to another can be painful but if you are at 5.6 it should not be a big issue. However you can follow this guide. Last, if you need a full list of new features, you can visit this page.
Next post we’ll consider PHP7.1 changes as they seem to be very interesting.
Stay tuned!