Get the Hang of PHP 7
Long before I started looking into PHP, I disliked it particularly for two main reasons; the supposed “shittiness” and the dynamic typing it offered, just like other languages like Javascript, ruby, etc. This particular bias was because I was coming from Java, where form and structure are “commandments” you have to obey or be marked for garbage collection(pun intended).
When I eventually started looking into PHP, I was struck by the close resemblance, except for a few adventurous design decisions it bore to Java. Some things were off though, I had a tough time designing my applications, when I knew I had to do without a few things like ‘return types’ for methods, ‘scalar types’ or ‘primitive types’ (like Java calls them). Dependency injection came in handy on some occasions, but wielding the power of ‘polymorphism’ seemed to be a Herculean task.
Enter PHP 7
When PHP announced the release of PHP7, I was particularly excited because of the new features that were added, feature like:
1. Combined comparison operator (<=>) a.k.a Spaceship Operator
2. The null coalescing operator ( ?? )
3. Namespace grouping
4. Anonymous Classes
5. Scalar type Declarations
6. Return type Declarations
7. Uniform Variable Syntax
8. Fatal Errors transformed to Exceptions
And more…
I will walk us through some of the most exciting features of the all new PHP7. Brace yourself for the awesomeness.
1. The Combined Comparison Operator ( <=> ) Spaceship Operator
Before PHP7, if you wanted to sort the values of an array of persons say
1 |
$users = ['Prosper', 'Bendozy', 'Yemisi', 'Kola', 'Dara', 'Verem']; |
You would probably do something like this:
1 |
$users = ['Prosper', 'Bendozy', 'Yemisi', 'Kola', 'Dara', 'Verem']; |
1 |
asort($users); |
1 |
arsort($user); //for reverse sort. |
In PHP7, you don’t have to use different functions for sorting in order and reverse order, better still, you can sort more than arrays. You would achieve the same thing like this;
1 2 3 4 5 6 7 |
$users = ['Prosper', 'Bendozy', 'Yemisi', 'Kola', 'Dara', 'Verem']; usort($users, function ($a, $b) { return $a <=> $b; }); |
To sort in reverse order, you just change the order of the arguments passed to the ‘spaceship’ operator, like so;
1 2 3 |
usort($users, function ($a, $b) { return $b <=> $a; }); |
Just to be very clear, if you really do not understand, this is the underlying principle
1 2 3 4 5 6 7 8 9 |
$a = 6, $b = 7; $a <=> $b = -1; $b <=> $a = 1; So if $a = 6 and $b = 6 $a <=> $b = 0 |
If the number on the right is greater, then the result of the evaluation is -1.
If the number on the left is greater, then the result of the evaluation is 1.
If the numbers are equal on both sides, then the result of the evaluation is 0.
2. The null coalescing Operator
The ‘null coalescing operator’ is used to test for the ‘nullity’ or not of a variable or object. Before PHP 7, you had to use the isset($var) to test for nulls.
If you had a variable say $age and you wanted to test if the variable had been set, you probably would do something like this:
1 |
isset($age) ? $age : 21; |
In PHP7, however, we can save some keystrokes with the null coalescing operator;
1 |
($age) ?? 21; |
That returns the age variable if it exists and is not null, otherwise it returns 21.
Pretty straightforward right?..Yes, it is
3. Namespace Grouping
It is now possible to group your namespaces. Assuming you had a number of namespaces that all have a common prefix, but you don’t want to write them all out on separate lines. You are welcome, PHP7 provides you with a namespace grouping functionality, where you can compress this;
1 2 3 4 |
use VeremContactEmail; use VeremContactPhone; use VeremContactAddressCode; use VerenContactAddressCity; |
will become:
1 |
use VeremContact{ Email, Phone, AddressCode, AddressCity }; |
4. Anonymous Classes
Just as the name implies, they are classes without names. This allows you to create classes on the fly, just like with closures, the instance is immediately created and assigned to a variable : the object.
Before now, you had no option but to write a piece of code that would look like this for a Logger.
1 2 3 4 5 6 7 8 9 10 11 12 |
class Logger { public static function write(Message $message) { return $message->getText(); } } interface Message { public function getText(); } |
1 2 3 4 5 6 7 8 9 |
class TextMessage implements Message { public function getText() { return 'Some random text'; } } Logger::write(new TextMessage()); |
In PHP7, you can skip naming the TextMessage class and simply assign its instance to an object at declaration time directly like so:
1 2 3 4 5 6 7 8 9 |
$message = (new class() implements Message { public function getText() { return 'Some random text'; } }); Logger::write($message); |
5. Scalar Type hints and Declarations
Before PHP7, You could type hint arrays, objects in methods and class constructors, a concept used by DI (Dependency Injection) containers, but we had no way of type hinting variables or ‘Scalar type hinting’, as it is called. PHP7 to the rescue. Now we can fortify our methods and variables, we can ensure that only what we intended our methods to be used for will be done. In other versions of PHP, you could declare a method add($a, $b) which will receive both doubles, floats and integers. This is a problem because the code could generate unpredictable results which could cause your software to be rickety, plus, you had to do additional error checking to make your software the least secure.
Before PHP7:
1 2 3 4 5 6 7 8 9 10 11 |
public class Arithmetic { public function add($a, $b) { return $a + $b; } } $arithmetic = new Arithmetic(); $arithmetic->add(2,4); // 6 $arithmetic->add(3.3,4); // 7.3 |
PHP7:
1 2 3 4 5 6 7 8 9 10 11 |
public class Arithmetic { public function add(int $a, int $b) { return $a + $b; } } $arithmetic = new Arithmetic(); $arithmetic->add(2,4); // 6 $arithmetic->add(3.3,4);// 7 The fractional part is truncated. |
Now, we have type-hinted the arguments to be integers. So if someone calls the add function and doesn’t pass integers as arguments, an exception would be thrown.
6. Enforcing Strict Type
In Javascript, when you want to enforce strict standards like always declaring a variable with var keyword and appending semicolons to the end of a statement, you can do something like this:
1 2 3 |
'use strict' var a = 5; |
In PHP 7:
You can now enforce strict standards like so:
1 2 3 4 5 6 7 8 |
<?php declare(strict_types=1); function add(int $a, int $b) { return $a + $b; } |
7. Return type declarations
Methods can now have return types using the scalar types. You could restrict the type returned by your methods. This takes care of surprise and unpredictable results.
Scalar type hints also work for return types.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 |
public class ElePHPant { private $name, $age, $cuteness, $evil; public function __construct(string $name, int $age, float $cuteness, bool $evil) { $this->name = $name; $this->age = $age; $this->cuteness = $cuteness; $this->evil = $evil; } public function getName(): string { return $this->name; } public function getAge(): int { return $this->age; } public function getCuteness(): float { return $this->cuteness; } public function getEvil(): bool { return $this->evil; } } |
When you set the declare(strict_types=1) on the above snippet, passing in the wrong argument types will cause a ‘catchable fatal error’.
1 2 3 4 5 6 7 |
<?php declare(strict_types=1); $ginger = new ElePHPant(12345, "7 years", "0.9", "1"); // Catchable fatal error: Argument 1 passed to ElePHPant::__construct() must be of the //type string, integer given |
8. Uniform variable syntax
Uniform variable syntax provides a simple way of directly accessing a closure within a function with one call. Say you have a function;
1 2 3 4 5 6 7 |
public function arithmetic() { return function(int $a, int $b) { return $a + $b; }; } |
You can call the closure like this:
1 |
arithmetic()(5,6); // 11 |
9. Throwable Interface
PHP7 has introduced exceptions as a replacement for fatal or recoverable fatal errors. These exceptions do not extend Exception but instead extend a new class BaseException. They include:
EngineException, ParseException and TypeException.
To use the exceptions, the proper type hint has to be provided. Consider the code snippet below:
1 2 3 4 |
public function add(int $a, int $b) { return $a + $b; } |
1 2 3 4 5 6 7 8 9 10 11 |
//use the method try{ echo add('a', 'b'); } catch (Exception $e) { //log the error. } |
The above TypeException will not be caught, instead a fatal error would be thrown like so:
//Fatal error: Uncaught TypeException: Argument 1 passed to add() must be of the type integer, //string given.
To catch the exception, the proper type hint has to be used;
1 2 3 4 5 6 7 |
try{ echo add('a', 'b'); } catch (Exception $e){ //handle exception. } catch (TypeException $te){ //handle type exception and end gracefully. } |
These and many more features have been added to PHP7. In future posts, We will explore more into the awesome world of PHP7. For now, keep the flame burning.
We earnestly wait for the official release on December 3, 2015.
Fire up your vagrant and use php7dev box to test everything and start basking in the euphoria of sweet goodness!!!
Please if you have any questions or observations, let me know in the comments section below.
- Get the Hang of PHP 7 - November 20, 2015