The most talked-about cool new feature in PHP 8 is JIT, the just-in-time compiler. You can enable JIT by simply adding this command at the top of any PHP code file you want to speed up:
01<?php
02 // core_cool_JIT_with.php
03 // uses Mandelbrot implementation seen here:
04 // https://gist.github.com/dstogov/12323ad13d3240aee8f1
05 ini_set('opcache.jit_buffer_size', '256M');
06 include __DIR__ . '/includes/Mandelbrot.php';
07 ob_start();
08 $m = new Mandelbrot();
09 $m->render();
10 ob_end_flush();
More information: https://wiki.php.net/rfc/jit
See for yourself: core_cool_JIT_with.php
PHP 8 array handling gives you a dramatic boost in performance. In this case there's no specific tip other than to upgrade to PHP 8!
In the example shown here, an array of 6 million elements is scanned. array_slice()
is used to grab a subset of the array using large random offsets.
In PHP 7 and below, the entire array up to the offset position had to be scanned! This wastes a tremendous amount of time.
01<?php
03 ini_set('memory_limit', '1G');
04 // other code not shown
27 for ($x = 0; $x < $iters; $x++ ) {
28 $offset = rand(999999, $max);
29 $slice = array_slice($arr, $offset, 4);
30 if ($x % $drip === 0) {
31 printf($pattern, $offset, $arr[$offset]);
32 }
33 }
34 // other code not shown
PHP 7: Elapsed Time: 7.4599778652191 seconds
PHP 8: Elapsed Time: 1.4884932041168 seconds
See for yourself: core_imp_array_slice.php
It seems there's a never-ending need to check for things at the beginning or end of a string. One example concerns checking an incoming request URL to see if it's http or https. You might also need to check a specific pattern at the end. Here's how you used to have to write this:
01<?php
02 // core_cool_starts_with.php
03 $url = 'http://phptraining.net/logout';
04 $check_url_old = function ($url, $start, $end)
05 {
06 $msg = '';
07 if (substr($url, 0, strlen($start)) !== $start) {
08 $msg .= "URL does not start with $start\n";
09 }
10 if (strpos(strrev($url), strrev($end)) !== 0) {
11 $msg .= "URL does not end with $end\n";
12 }
13 return $msg;
14 };
16 $msg = $check_url_old($url, 'https', 'login');
17 echo ($msg) ? $msg : "Proceeding with login\n";
18
35
36
Using substr()
and strlen()
is quite common, but is a waste of resources (and thus drags down performance).
The second expression uses strrev()
to reverse both the URL and the search string, doubling-down on inefficiency.
The bottom line is: these functions are not designed to check to see if something exists in the string!
In PHP 8, two excellent new functions str_starts_with
and str_ends_with
have been added that do not drain resources in this manner at all.
Here's the same block of code rewritten using the new functions:
More information: https://wiki.php.net/rfc/add_str_starts_with_and_ends_with_functions
See for yourself: core_cool_starts_with.php
The bane of any developer's existence is the awkward switch
statement. PHP 8 introduces the lean and mean match
statement as a replacement.
Here's how you used to have to write a simple function capable of performing simple arithmetic:
01
<?php
02 // core_cool_match_exp.php
04 function math_old($a, $b, $op)
05 {
06 switch ($op) {
07 case '+' :
08 $result = $a + $b;
09 break;
10 case '-' :
11 $result = $a - $b;
12 break;
13 case '*' :
14 $result = $a * $b;
15 break;
16 case '/' :
17 $result = $a / $b;
18 break;
19 default :
20 $result = 0;
21 }
22 return $result;
23 }
24 echo "Using switch\n";
25 echo math_old(2, 2, '+');
Can anybody say awkward? In PHP 8, here's exactly the same thing:
27 // exactly the same thing using `match` expression:
29 echo "\nUsing match expression\n";
30
31 function math_new($a, $b, $op)
32 {
33 return match ($op) {
34 '+' => $a + $b,
35 '-' => $a - $b,
36 '*' => $a * $b,
37 '/' => $a / $b,
38 'default' => 0
39 };
40 }
41 echo math_new(2, 2, '+');
More information: https://wiki.php.net/rfc/match_expression_v2
See for yourself: core_cool_match_exp.php
Another really really cool feature added with PHP 8 is _constructor argument promotion_.
What in heck is that you might ask?
In brief: this new feature allows you to define properties, default values and visibility ... all in the __construct()
method signature!
First, have a look at the conventional way of defining a class. We show public
properties for the sake of brevity:
01
<?php
02 // core_cool_attr_misc.php
03 class Test
04 {
05 public $id;
06 public $name;
07 public $request;
08 public function __construct(
09 int $id = 0,
10 string $name = '',
11 iterable $request = [])
12 {
13 $this->id = $id;
14 $this->name = $name;
15 $this->request = $request;
16 }
17 }
18 $test = new Test(111, 'Doug', new ArrayIterator($_SERVER));
19 var_dump($test);
Although this feature will not speed up your website, it will definitely shorten the amount of time you spend writing code! Have a look at the same thing rewritten in PHP 8:
01
<?php
02 // core_cool_construct_new.php
03 class Test
04 {
05 public function __construct(
06 public int $id = 0,
07 public string $name = '',
08 public iterable $request = [])
09 {}
10 }
11 $test = new Test(111, 'Doug', new ArrayIterator($_SERVER));
12 var_dump($test);
More information: https://wiki.php.net/rfc/match_expression_v2
See for yourself: core_cool_match_exp.php