Standing by for PHP8: Giving us the… JIT-ters



Author: Kostas Papanikolaou

Categories: Technology

Standing by for PHP8: Giving us the… JIT-ters

When PHP7 was officially released, it brought forth immense improvements over PHP5, both in terms of performance and speed. New features such as the scalar type hints which provided a better user experience set the bar even higher, and the overall quality of PHP7 even made most of us forget about the PHP6 “fiasco”. PHP6 was never released, creating quite the upheaval within the community, and even threatened the scripting language’s reputation, initially planned to be released in 2005 with UTF8/Unicode support, but failing to reach the public.

However, PHP7 rebuilt the trust of some in PHP, and as 2020 doesn’t seem “eager” to stop bringing bad news overall, developers can look forward to the much-anticipated release of PHP8 in December. Expectations are high and include a much-needed transition to real-time features which will unlock scarcely explored waters for PHP users. The entire digital world has already begun its transition to the real-time era, and PHP8 is allegedly one of the next, crucial steps towards that.

JIT-ters get a whole new meaning

The word “jitters” describes something negative, the feeling of extreme nervousness. Starting December 2020, developers around the globe and programming/scripting enthusiasts hope that word will have a whole new meaning for their sector when PHP8 arrives. Why? Because JIT is coming!

JIT, short for Just-In-Time, is by far the most highly-anticipated feature of PHP 8.0. The Just-In-Time compiler is a popular method that is already being used by the Java Virtual Machine (JVM), HHVM, as well as by the popular V8 JavaScript VM from Google. Before PHP 7.x, the PHP development used a JIT to improve performance. Improvements in the benchmarks thanks to JIT were important, but improvements in real-world apps like WordPress or Joomla were much smaller. But what does JIT do?

Speed + Performance = Instant Results

In March 2020, Nickolas Da Silva, Senior Software Engineer at ResearchGate, posted an article in “thePHP Website” where he explained in-depth about that the Just-In-Time compiler is, and how it will improve PHP 8.0.

Simply put by Da Silva himself, JIT will help so that “some Opcodes won’t need to be interpreted by Zend VM and such instructions will be executed directly as CPU level instructions.” When JIT works as intended, the code will not be executed through Zend VM but instead will be executed directly as a set of CPU-level instructions.

The Just-In-Time compiler generates a compiled code in runtime so PHP can gain performance from skipping the Zend VM. The implementation of JIT in PHP uses a library called DynASM (Dynamic Assembler), which maps a set of CPU instructions in one specific format into assembly code for many different CPU types. That way, JIT can transform Opcodes into architecture-specific machine code using DynASM.

Just-In-Time is coming to bring forth change -essentially- to anything that is not touching I/O. The JIT compiler will benefit anything that is not I/O bound, like machine learning or image processing. This will allow writing native PHP functions written in PHP, instead of C, according to developers, since such functions will be compiled either way thanks to JIT, and the overhead won’t be expressive.

Union types, nullsafe operator, and more

Apart from JIT, which has brought hype within the PHP community, several other features are scheduled to “drop” when PHP 8.0 is released. These include but are not limited to:

  • Union types
  • Nullsafe operator
  • Attributes
  • New static return type
  • New mixed type
  • Throw expression
  • Inheritance with private methods
  • Non-capturing catches
  • New stringable interface

Union types

PHP in its nature is dynamic, therefore union types can be useful. The addition of these in PHP 8.0 is expected to improve things since union types are a collection of two or more types which indicate that either one of those can be used.

public function foo(Foo|Bar $input): int|float;

“Void” can never be part of a union type since it indicates “no return value at all”. Also, nullable unions can be written using |null, or by using the existing “?” notation:

public function foo(Foo|null $foo): void;
 
public function bar(?Bar $bar): void;

Nullsafe operator

The null coalescing operator has been available since PHP 7.0. It is similar to the ternary operator but behaves like isset on the lefthand operand instead of just using its Boolean value. This makes this operator especially useful for arrays and assigning defaults when a variable is not set. The null coalescing operator does not work on method calls currently.

$startDate = $dateAsString = $booking->getStartDate();
 
$dateAsString = $startDate ? $startDate->asDateTimeString() : null;

PHP 8.0 will change that with the nullsafe operator, which will allow null coalescing-like behavior on methods.

$dateAsString = $booking->getStartDate()?->asDateTimeString();

Attributes

Commonly known as annotations in other scripting/programming languages, attributes offer a way to add meta data to classes, without the need of parse docblocks. Below, you will find an example of what attributes look like, from the RFC. In the original RFC, this base Attribute was called PhpAttribute, but was changed later.

use App\Attributes\ExampleAttribute;
 
@@ExampleAttribute
class Foo
{
    @@ExampleAttribute
    public const FOO = 'foo';
 
    @@ExampleAttribute
    public $x;
 
    @@ExampleAttribute
    public function foo(@@ExampleAttribute $bar) { }
}
@@Attribute
class ExampleAttribute
{
    public $value;
 
    public function __construct($value)
    {
        $this->value = $value;
    }
}

New static return type

The current version of PHP makes it possible to return “self”, but not “static”. PHP 8.0 will change that, and offer several developers a great solution.

class Foo
{
    public function test(): static
    {
        return new static();
    }
}

New mixed type

The “mixed” type has been the center of debate for many years, with some developers calling it “a necessary evil”. A missing type can mean multiple different things in PHP, such as that a function returns nothing or null, that the developer expects one of several types, or that we expect a type that can’t be type hunted in PHP.

PHP 8.0 adds the “mixed” type, which means one of the following types:

 
array
 
bool
 
callable
 
int
 
float
 
null
 
object
 
resource
 
string

“Mixed” already includes “null”, and therefore is not allowed to make it nullable. The following triggers an error:

// Fatal error: Mixed types cannot be nullable, null is already part of the mixed type.
function bar(): ?mixed {}

Throw expression

“throw” will change in PHP 8.0 from being a statement to being an expression, making it possible to throw exception in many new places:

$triggerError = fn () => throw new MyError();
 
$foo = $bar['offset'] ?? throw new OffsetDoesNotExist('offset');

Inheritance with private methods

When it comes to inheritance checks regarding public, protected, and private methods, PHP applies the same checks. Private methods should follow the same method of signature rules as protected and public methods. We know, this never made sense, and in PHP 8.0 it will change. The upcoming RFC changed that behavior, for these inheritance checks are not performed on private methods anymore. The use of “final private function” will now trigger the following warning:

Warning: Private methods cannot be final as they are never overridden by other classes

Non-capturing catches

Currently, PHP requires you to store an exception in a variable if you want to catch it, regardless whether you used the variable or not. The introduction of non-capturing catches allows developers to omit that variable.

Instead of this:

try {
    // Something goes wrong
} catch (MySpecialException $exception) {
    Log::error("Something went wrong");
}

Developers can do this:

try {
    // Something goes wrong
} catch (MySpecialException) {
    Log::error("Something went wrong");
}

Specifying the type is still required, and developers are not allowed to have an empty “catch”. Using “Throwable” as the catching type catches all exceptions and errors.

New stringable interface

This is a new feature that will allow developers to type-hint anything that is considered a string or implements “__toString()”. Also, when a class implements “__toString()”, it will automatically implement the interface behind the scenes, and as a result, there will be no need for manual implementation.

class Foo
{
    public function __toString(): string
    {
        return 'foo';
    }
}
 
function bar(Stringable $stringable) { /* … */ }
 
bar(new Foo());
bar('abc');

Tags: JIT, Just-In-Time, Just-In-Time PHP, PHP, PHP 7.0, PHP 8.0, PHP7, PHP8