What's new and changed in PHP 8

botond published 2021/02/02, k - 18:20 time

Content

 

Introductory

PHP On November 2020, 26, it released its latest major version of PHP 8 (8.0.0), and since then on January 2021, 7, PHP 8.0.1, so it's time to deal with it here on the site as well. In this shorter article, we review the major innovations and changes in PHP 8.

 

 

What's new in PHP 8

PHP 8 has been expanded with many new features and many changes have been made to it.

RFCs

Az RFC (Abbreviation for Request For Comments in English) is a document that is published when a new Internet standard is introduced. The first draft of the new standard will be made available to the public with its own number, and anyone can comment within a certain period of time. These comments are systematized and, after several amendments, the draft standard is adopted or discarded. Source

In the case of PHP, RFCs are used to gather designs that will become the standard for the PHP language over time. On this page we can see the current RFCs that are still in the voting phase, or under discussion, or in a draft, or in an accepted state, or in an implemented state.

Here, interestingly, we can follow live which RFC has how many votes, etc .: php-rfc-watch.beberlei.de

In the next section, we will review some of the more important ones without claiming to be exhaustive.

Union types (RFC)

A union types (union types) we can specify two or more types of variables as acceptable types. Examples:

// Példa #1
class Number {
    private int|float $number;
 
    public function setNumber(int|float $number): void {
        $this->number = $number;
    }
 
    public function getNumber(): int|float {
        return $this->number;
    }
}

// Példa #2
// phpdoc jelöléssel:
class Number {
    /**
     * @var int|float $number
     */
    private $number;
 
    /**
     * @param int|float $number
     */
    public function setNumber($number) {
        $this->number = $number;
    }
 
    /**
     * @return int|float
     */
    public function getNumber() {
        return $this->number;
    }
}

Named argument (RFC)

A named arguments  (in English: named parameters) allow you to give parameters to a function based on their names, not their positions. This makes the parameters sequence independent and also allows you to omit the default / optional values. Examples:

// Példa #1:
// Hagyományos paraméterek használata:
array_fill(0, 100, 50);
 
// Named arguments használata:
array_fill(start_index: 0, num: 100, value: 50);

// A nevezett argumentumok átadásának sorrendje nem számít.
// A fenti példa ugyanabban a sorrendben adja át őket, mint amelyet a függvény aláírásában deklaráltunk, 
// de bármilyen más sorrend is lehetséges:
array_fill(value: 50, num: 100, start_index: 0);


// Példa #2:
function foo(string $a, string $b, ?string $c = null, ?string $d = null) 
{ /* … */ }

foo(
    b: 'value b', 
    a: 'value a', 
    d: 'value d',
);

JIT (RFC)

A JIT (Just In Time compilation) is a runtime compilation method that is a technique for increasing the performance of bytecode-compiled systems. Compiles the bytecode to native code at runtime. For PHP 8, it can result in up to a threefold increase in performance when running parts that perform purely mathematical calculations, but other web applications produce similar performance as its predecessor, PHP 7.4.

 

 

Attributes (RFC)

Az attributes (attributes), commonly known in other languages ​​as comments, offer the ability to add metadata to classes without having to process docblock-ok. Attributes allow you to define configuration policies that are directly embedded in the code declaration.

Similar solutions exist in other programming languages: Annotations in Java, Attributes in C #, C ++, Rust, Hack, and Decorators in Python and Javascript . PHP example:

// PHP 7-ben:
class PostsController
{
    /**
     * @Route("/api/posts/{id}", methods={"GET"})
     */
    public function get($id) { /* ... */ }
}

// PHP 8-ban:
class PostsController
{
    #[Route("/api/posts/{id}", methods: ["GET"])]
    public function get($id) { /* ... */ }
}

Instead of PHPDoc comments, we can now use structured metadata with the native syntax of PHP. Source

Constructor Property Promotion (RFC)

Constructor Property Promotion, also known as a simplified constructor, simplifies the process of creating objects. Instead of specifying the class properties and the constructor separately, PHP 8 now combines these into one. Examples:

// Példa #1:
// Korábbi PHP-k esetén:
class Point {
  public float $x;
  public float $y;
  public float $z;

  public function __construct(
    float $x = 0.0,
    float $y = 0.0,
    float $z = 0.0
  ) {
    $this->x = $x;
    $this->y = $y;
    $this->z = $z;
  }
}

// PHP 8-ban ugyanez:
class Point {
  public function __construct(
    public float $x = 0.0,
    public float $y = 0.0,
    public float $z = 0.0,
  ) {}
}



// Példa #2:
// Korábbi PHP-k esetén:
class Money 
{
    public Currency $currency;
 
    public int $amount;
 
    public function __construct(
        Currency $currency,
        int $amount,
    ) {
        $this->currency = $currency;
        $this->amount = $amount;
    }
}

// PHP 8-ban:
class Money 
{
    public function __construct(
        public Currency $currency,
        public int $amount,
    ) {}
}

Match (RFC)

 

 

A match term is actually a Switch smarter version of the term: The match structure can have a return value, it does not require break expressions, apply strict type comparisons, and do not perform any type constraints. Examples:

// Példa #1:
// PHP 7-ben:
switch (1) {
    case 0:
        $result = 'Foo';
        break;
    case 1:
        $result = 'Bar';
        break;
    case 2:
        $result = 'Baz';
        break;
}
 
echo $result;
//> Bar


// PHP 8-ban
echo match (1) {
    0 => 'Foo',
    1 => 'Bar',
    2 => 'Baz',
};
//> Bar


// Példa #2:
// PHP 7-ben:
switch ('foo') {
    case 0:
      $result = "Oh no!\n";
      break;
    case 'foo':
      $result = "This is what I expected\n";
      break;
}
echo $result;
//> Oh no!

// PHP 8-ban:
echo match ('foo') {
    0 => "Oh no!\n",
    'foo' => "This is what I expected\n",
};
//> This is what I expected

More reasonable string number comparison (RFC)

Saner string to number comparisons corrects an old PHP oddity: in earlier versions of PHP, when the command processor compared strings and numbers using "==" and other non-strict comparison operators, the he first converted the string to a number and then compared it as integers or floating-point numbers. This led to unexpected results in many cases, as in this case: 0 == "foobar" , the value of which was true. This RFC requires that non-strict comparisons be made more useful and less prone to error by performing a comparison as a number only if the string to be compared is actually a numeric number. Otherwise, have the numbers converted to strings, and then perform a string comparison on them. Example:

// PHP korábbi változataiban:
0 == 'foobar' // true

// PHP 8-ban:
0 == 'foobar' // false



Összehasonlítás	| Korábban	| PHP 8-ban
----------------------------------------
 0 == "0"		| true		| true
 0 == "0.0"		| true		| true
 0 == "foo"		| true		| false
 0 == ""		| true		| false
42 == "   42"	| true		| true
42 == "42foo"	| true		| false

The nullsafe operator (RFC)

A nullsafe operator using the null instead of control conditions, the call chain can now be used with the new nullsafe operator. If the evaluation of one element of the chain fails, the execution of the entire chain is interrupted and the entire chain is evaluated to zero. Example:

// PHP korábbi verzióiban:
$country =  null;

if ($session !== null) {
  $user = $session->user;

  if ($user !== null) {
    $address = $user->getAddress();
 
    if ($address !== null) {
      $country = $address->country;
    }
  }
}


// PHP 8-ban:
$country = $session?->user?->getAddress()?->country;

Throw expression (RFC)

 

 

This RFC changes the previous throw statement, which it converts into an expression, allowing exceptions to be thrown in new places, making it more flexible to use. Example:

// Korábbi PHP változatokban használható throw minta:
// függvény létrehozáűsa egy kivétellel
function checkNum($number) {
  if($number>1) {
    throw new Exception("Az értéknek 1-nek vagy akatta kell lennie");
  }
  return true;
}


// PHP 8-ban használható minták, amik ezelőtt nem voltak lehetségesek:
// Ez korábban nem volt lehetséges, mivel a (PHP 7.4-ben bevezetett) nyíl függvények  csak egyetlen kifejezést fogadtak el, míg a throw korábban  egy utasítás volt.
$callable = fn() => throw new Exception();
 
// $value is non-nullable.
$value = $nullableValue ?? throw new InvalidArgumentException();
 
// $value is truthy.
$value = $falsableValue ?: throw new InvalidArgumentException();
 
// $value is only set if the array is not empty.
$value = !empty($array)
    ? reset($array)
    : throw new InvalidArgumentException();


$triggerError = fn () => throw new MyError();

Uj str_starts_with () and str_ends_with () string search functions (RFC)

Checking the beginning and end of strings is a very common task that should be simple. This task is not easy to accomplish, so many frameworks have chosen to incorporate it. Several high-level programming languages ​​have implemented this feature, such as JavaScript, Java, Haskell, and Matlab. Checking the beginning and end of a string cannot be a task that requires indenting a PHP framework or developing a potentially suboptimal (or worse, faulty) function in the programming language.

Az str_starts_with () checks if a string starts with another string and returns the correct logical value (true / false)
Az str_ends_with () checks if a string ends with another string and returns the correct logical value (true / false)

str_starts_with('abcdefgh', 'abc'); // igaz
str_ends_with('abcdefgh', 'fgh'); // igaz

 

Deprecated

Listed here are things that worked in previous versions of PHP without any bugs, but have been declared obsolete in PHP 8. Deprecated things are usually not removed from the given version yet, so they don't throw Fatal errors yet, but they already throw PHP notices of the "Deprecated" type and then they will be permanently removed in a future PHP version.

Reflection API Some methods of the ReflectionMethod class

PHP reflection API ReflectionMethod Some of the methods in this class are deprecated, so those who use the following methods will receive notices:

  • ReflectionParameter::getClass()
  • ReflectionParameter::isArray()
  • ReflectionParameter::isCallable()

Source: https://php.watch/versions/8.0/deprecated-reflectionparameter-methods

I highlighted this here because, for example, phpMyAdmin Version 4.9.x also throws such notices when running on PHP 8, so this branch is not yet 100% compatible with PHP 8.

Error message displayed by phpMyAdmin:

Deprecation Notice in ./libraries/classes/Di/ReflectorItem.php#82
 Method ReflectionParameter::getClass() is deprecated

 

Other changes

Changes and novelties not classified in the above groups are listed here.

New default Error reporting level

In PHP 8, the default has changed Error reporting level. Instead of the previous default setting (error_reporting = E_ALL & ~ E_NOTICE & ~ E_STRICT & ~ E_DEPRECATED), PHP 8 error_reporting = E_ALL setting has taken effect. Source

// PHP 8 előtti verzióban az alapértelmezett error_reporting érték:
// php.ini beállítás:
// error_reporting = E_ALL & ~E_NOTICE & ~E_STRICT & ~E_DEPRECATED
// PHP script beállítás:
error_reporting(E_ALL & ~E_NOTICE & ~E_STRICT & ~E_DEPRECATED);

// A PHP 8-ban pedig:
// php.ini beállítás:
// error_reporting = E_ALL
// PHP script beállítás:
error_reporting(E_ALL);

As a result, PHP 8 displays by default all bugs that were ignored in previous versions of PHP. Therefore, in case of sharp use, it is advisable to set the appropriate value manually, if you do not want all the small errors to appear on our websites.

Revealing fatal errors

The '@' operators placed in front of the instructions in the source code no longer suppress fatal errors in PHP 8, so they are revealed that were not previously visible. For live server environments, ensure that the "display_errors = Off" setting is in effect so that fatal errors that you want to hide remain hidden.

 

Installing and configuring PHP 8

For more information on installing and configuring PHP 8, see:

 

 

Conclusion

These would be the most important changes in PHP 8. Of course, there are many more novelties than these, to find out more about them visit the links below. I’ll expand on this article little by little as I stumble upon more PHP 8 curiosities.

 

 

Tags