Introduction To PHP 7: What's New And What's Gone
One of the most exciting events in 2015 in the PHP world was the release of PHP 7, 10 years on from the release of the last major version, PHP 5. With a major step forward, PHP 7 introduces plenty of new features and performance upgrades.
However, it also removes old, deprecated functionality, which introduces some compatibility breaks, making it harder for older applications to migrate to the new version. This guide should serve as a quick tour on what to expect if you plan on moving your existing applications, or building new ones, on top of PHP 7.
But Wait, Where Did PHP 6 Go?
If you haven’t been working with PHP lately, you might wonder what happened to PHP 6, why the skip from PHP 5 to PHP 7? Well, long story short, PHP 6 was a failure. The main feature of version 6 was native support for Unicode characters since PHP is used mainly in web development and the web needs Unicode, so the move to bring Unicode to PHP made sense.
The idea was to bring complete support for Unicode to the core itself. It would have brought extended capabilities to the language, from the ability to use silly emojis as variable and function names, to powerful international string functionality. For instance, when another language uses upper and lower case letters differently from English, or when a name in Chinese characters needs to be converted to English.
Unfortunately, this ambitious plan proved to be a bigger problem than anticipated. Much of the codebase had to be ported to support Unicode for both core and important extensions, which proved tedious and tricky. This slowed down development of other features in the language, frustrating many PHP developers in the process. Additional hurdles showed up, which resulted in less interest in developing a native Unicode support, ultimately leading to the project being abandoned.
Since resources, such as books and articles, had been written for PHP 6 and its Unicode support, the new version would be renamed PHP 7 to avoid confusion.
Anyway, enough dwelling in the sad past, let’s see what PHP 7 brings to the party.
Performance Battle, PHP 7 vs. PHP 5
With virtually all updates, minor performance upgrades are to be expected. However, this time PHP brings a significant improvement over earlier versions making sheer performance one of PHP 7’s most attractive features. This comes as part of the “PHPNG” project, which tackles the internals of the Zend Engine itself.
By refactoring internal data structures and adding an intermediate step to code compilation in the form of an Abstract Syntax Tree (AST), the result is superior performance and more efficient memory allocation. The numbers themselves look very promising; benchmarks done on real world apps show that PHP 7 is twice as fast as PHP 5.6 on average, and results in 50 percent less memory consumption during requests, making PHP 7 a strong rival for Facebook’s HHVM JIT compiler. Have a look at this infographic from Zend depicting performance for some common CMS and Frameworks.
The decrease in memory consumption also allows smaller machines to handle requests better along with the opportunity for building micro services around PHP. The internal changes, in particular the AST implementation, also opens possibilities for future optimisations that could push performance even further. A new, in-house implementation of a JIT compiler is being considered for future versions.
PHP 7 Syntactic Sugar
PHP 7 comes with new syntax features. While not extending the capabilities of the language itself, they provide a better, or easier, way of making your code more enjoyable to write and pleasing to the eye.
Group Import Declarations
Now, we can group import declarations for classes originating from the same namespace into a single
use
line. This should help aligning declarations in a meaningful way or simply save some bytes in your files.use Framework\Module\Foo;
use Framework\Module\Bar;
use Framework\Module\Baz;
With PHP 7 we can use:
use Framework\Module\{Foo, Bar, Baz};
Or, if you prefer a multi-line style:
use Framework\Module{
Foo,
Bar,
Baz
};
Null Coalescing Operator
This solves a common problem in PHP programming, where we want to assign a value to a variable from another variable, if the latter is actually set, or otherwise provide a different value for it. It’s commonly used when we work with user-provided input.
Pre-PHP 7:
if (isset($foo)) {
$bar = $foo;
} else {
$bar = 'default'; // we would give $bar the value 'default' if $foo is NULL
}
After PHP 7:
$bar = $foo ?? 'default';
This can be also chained with a number of variables:
$bar = $foo ?? $baz ?? 'default';
Spaceship Operator
The spaceship operator
<=>
allows for a three way comparison between two values, not only indicating if they are equal, but also which one is bigger, on inequality by returning 1,0 or -1.
Here we can take different actions depending on how the values differ:
switch ($bar <=> $foo) {
case 0:
echo '$bar and $foo are equal';
case -1:
echo '$foo is bigger';
case 1:
echo '$bar is bigger';
}
The values compared can be integers, floats, strings or even arrays. Check the documentation to get an idea of how different values are compared to each other. [https://wiki.php.net/rfc/combined-comparison-operator]
New Features In PHP 7
But of course PHP 7 also brings new and exciting functionality with it.
Scalar Parameter Types & Return Type Hints
PHP 7 extends the previous type declarations of parameters in methods ( classes, interfaces and arrays) by adding the four scalar types; Integers (
int
), floats (float
), booleans (bool
) and strings (string
) as possible parameter types.
Further, we can optionally specify what type methods and functions return. Supported types are bool, int,float, string, array, callable, name of Class or Interface, self and parent ( for class methods )
class Calculator
{
// We declare that the parameters provided are of type integer
public function addTwoInts(int $x, int $y): int {
return $x + $y; // We also explicitly say that this method will return an integer
}
}
Type declarations allow the building of more robust applications and avoid passing and returning wrong values from functions. Other benefits include static code analyzers and IDEs, which provide better insight on the codebase if there are missing DocBlocks.
Since PHP is a weakly typed language, certain values for parameter and return types will be cast based on the context. If we pass the value “3” in a function that has a declared parameter of type
int
, the interpreter will accept it as an integer and not throw any errors. If you don’t want this, you can enable strict mode
by adding a declare
directive.declare(strict_types=1);
This is set in a per-file basis, as a global option would divide code repositories to those that are built with global strictness on and those that are not, resulting in unexpected behavior when we combine code from both.
Engine Exceptions
With the addition of engine exceptions, fatal errors that would have resulted in script termination can be caught and handled easily.
Errors such as calling a nonexistent method won’t terminate the script, instead they throw an exception that can be handled by a try catch block, which improves error handling for your applications. This is important for certain types of apps, servers and daemons because fatal errors would otherwise require them to restart. Tests in PHPUnit should also become more usable as fatal errors drop the whole test suite. Exceptions, rather than errors, would be handled on a per test case basis
PHP 7 adds a number of new exception classes based on the type of errors that might be encountered. In order to maintain compatibility between versions, a new
Throwable
interface has been added that can be implemented from both engine exceptions and user exceptions. This was necessary in order to avoid engine exceptions to extend the base exception class, resulting in older code- catching exceptions that were not there before.
Before PHP 7 this would have terminated the script with a fatal error:
try {
thisFunctionDoesNotEvenExist();
} catch (\EngineException $e) {
// Clean things up and log error
echo $e->getMessage();
}
Anonymous Classes
Anonymous classes are cousins of anonymous functions that you might use in a simple short-term instance. Anonymous classes are easily created and used just like a regular object. Here is an example from the docs.
Pre-PHP 7
class MyLogger {
public function log($msg) {
print_r($msg . "\n");
}
}
$pusher->setLogger( new MyLogger() );
With anonymous class:
$pusher->setLogger(new class {
public function log($msg) {
print_r($msg . "\n");
}
});
Anonymous classes are useful in unit testing, particularly in mocking test objects and services. This helps us avoid heavy mocking libraries and frameworks by creating a simple object that provides the interface we want to mock.
CSPRNG Functions
Two new functions for generating cryptographically secure string and integers were added.
random_bytes(int $len);
Returns a random string with length
$len
.random_int(int $min, int $max);
Returns a number between
$min
and $max
.Unicode Codepoint Escape Syntax
Unlike many other languages, prior to PHP 7, PHP did not have a way to escape a Unicode codepoint in string literals, . This functionality adds the escape
\u
sequence to produce such characters using their UTF-8 codepoint. This is better than inserting the characters directly, allowing better handling of invisible characters as well as characters that have the same graphical representation but differ in meaning.echo "\u{1F602}"; // outputs 😂‚
Note that this breaks existing code with the
\u
sequence because it changes the behaviour.
Post a Comment