PHP 8 Execution :
As of PHP 5.5, the Zend OPcache extension is available by default,
The PHP execution is a 4 stage process:
- Lexing/Tokenizing: First, the interpreter reads the PHP code and builds a set of tokens.
- Parsing: The interpreter checks if the script matches the syntax rules and uses tokens to build an Abstract Syntax Tree (AST), a hierarchical representation of the structure of source code.
- Compilation: The interpreter traverses the tree and translates AST nodes into low-level Zend opcodes, which are numeric identifiers determining the type of instruction performed by the Zend VM.
- Interpretation: Opcodes are interpreted and run on the Zend VM.
PHP 8 Features :-
1.Constructor Property Promotion
Ex: PHP 7
class Point {
public int $x;
public int $y;
public int $z;
public function __construct( int $x = 0,int $y = 0,int $z = 0 ) {
$this->x = $x;
$this->y = $y;
$this->z = $z;
}
}
========After PHP 8.0 ===================
class Point {
public function __construct(
public int $x = 0,
public int $y = 0,
public int $z = 0, ) {
}
}
2.Validation for Abstract Trait Methods
A trait can also contain abstract methods. These methods simply declare the method’s signature, but the method’s implementation must be done within the class using the trait. PHP 8 should not allow different signature.
trait T {
abstract public function test(int $x);
}
class C {
use T; // Allowed, but shouldn't be due to invalid type.
public function test(string $x) {
}
}
// Fatal error: Declaration of C::test(string $x) must be compatible with T::test(int $x)
Above code gives fattal error in PHP8 version. It executes in php 7.4
3.Incompatible Method Signatures
The class implementing the interface must use a method signature which is compatible with LSP (Liskov Substitution Principle). Not doing so will result in a fatal error. Below code executes in PHP7.4 with an warning but its not in PHP8
class C1 {
public function method(array $a) {}
}
class C2 extends C1 {
public function method(int $a) {}
}
4.Arrays Starting With a Negative Index
With PHP 8, arrays starting with a negative index.
$a = array_fill(-5, 4, true);
print_r($a);
PHP 8
Array
(
[-5] => 1
[-4] => 1
[-3] => 1
[-2] => 1
)
Array
(
[-5] => 1
[0] => 1
[1] => 1
[2] => 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; } }
var_dump(strlen(new stdClass));
In PHP 8, the code above throws the following error
Fatal error: Uncaught TypeError: strlen(): Argument #1 ($str) must be of type string, object given in
7.Throw Expression
$callable = fn() => throw new Exception();
// $value is non-nullable.
$value = $nullableValue ?? throw new InvalidArgumentException();
// $value is truthy.
$value = $falsableValue ?: throw new InvalidArgumentException();
8.Weak Maps
9.Trailing Comma allowed in Parameter List
function foo(string $foo, string $bar,) {
echo " Variables - $foo - $bar ";
}
foo('foo','bar');
10.Allow ::class syntax on objects
$object = new stdClass;
var_dump($object::class); // "stdClass"
$object = null;
var_dump($object::class); // TypeError
We can access object class name with ::class in PHP8. If the object is null then its returns Type Error.
11.Attributes v2
12.Named Arguments
Named arguments allow passing arguments to a function based on the parameter name, rather than the parameter position.
array_fill(start_index: 0, num: 100, value: 50);
Named arguments are order-independent. This means that we are not forced to pass arguments to a function in the same order as the function signature:
array_fill(value: 50, num: 100, start_index: 0);
Ex:
function calculateTotal($price, $quantity, $discount = 0) {
$total = $price * $quantity * (1 - $discount);
return $total;
}
// Mix positional and named arguments
$subtotal = calculateTotal(10, quantity: 5, discount: 0.2);
13.Nullsafe Operator
PHP 7
$country = null;
if ($session !== null) {
$user = $session->user;
if ($user !== null) {
$address = $user->getAddress();
if ($address !== null) {
$country = $address->country;
}
}
}PHP 8 :
$country = $session?->user?->getAddress()?->country;
14.Saner String to Number Comparisons
Comparison | Before | After
--------------------------------------
0 == "0" | true | true
0 == "0.0" | true | true
0 == "foo" | true | false
0 == "" | true | false
42 == " 42" | true | true
42 == "42foo" | true | false
16.Match Expression v2
echo match (8.0) {
'8.0' => "Oh no!",
8.0 => "This is what I expected",
};
//> This is what I expected
The new match is similar to switch and has the following features:
- Match is an expression, meaning its result can be stored in a variable or returned.
- Match branches only support single-line expressions and do not need a break; statement.
- Match does strict comparisons.
17.Stricter Type Checks for Arithmetic/Bitwise Operators
PHP 8 brings several new functions to the language:
Anonymous classes
In PHP7, Anonymous classes are those classes that don’t have any name. These
anonymous classes are defined using the new class. It can replace full-class
definition. When simple, one-off objects are created then anonymous classes are
useful. They are internally generated names so we don’t have to give names to
these classes. Objects created by same anonymous class are instances of that
class
Below three examples describe anonymous class with very simple and basic but quite understandable example
<?php
// First way - anonymous class assigned directly to variable
$ano_class_obj = new class{
public $prop1 = 'hello';
public $prop2 = 754;
const SETT = 'some config';
public function getValue()
{
// do some operation
return 'some returned value';
}
public function getValueWithArgu($str)
{
// do some operation
return 'returned value is '.$str;
}
};
echo "\n";
var_dump($ano_class_obj);
echo "\n";
echo $ano_class_obj->prop1;
echo "\n";
echo $ano_class_obj->prop2;
echo "\n";
echo $ano_class_obj::SETT;
echo "\n";
echo $ano_class_obj->getValue();
echo "\n";
echo $ano_class_obj->getValueWithArgu('OOP');
echo "\n";
echo "\n";
// Second way - anonymous class assigned to variable via defined function
$ano_class_obj_with_func = ano_func();
function ano_func()
{
return new class {
public $prop1 = 'hello';
public $prop2 = 754;
const SETT = 'some config';
public function getValue()
{
// do some operation
return 'some returned value';
}
public function getValueWithArgu($str)
{
// do some operation
return 'returned value is '.$str;
}
};
}
echo "\n";
var_dump($ano_class_obj_with_func);
echo "\n";
echo $ano_class_obj_with_func->prop1;
echo "\n";
echo $ano_class_obj_with_func->prop2;
echo "\n";
echo $ano_class_obj_with_func::SETT;
echo "\n";
echo $ano_class_obj_with_func->getValue();
echo "\n";
echo $ano_class_obj_with_func->getValueWithArgu('OOP');
echo "\n";
echo "\n";
// Third way - passing argument to anonymous class via constructors
$arg = 1; // we got it by some operation
$config = [2, false]; // we got it by some operation
$ano_class_obj_with_arg = ano_func_with_arg($arg, $config);
function ano_func_with_arg($arg, $config)
{
return new class($arg, $config) {
public $prop1 = 'hello';
public $prop2 = 754;
public $prop3, $config;
const SETT = 'some config';
public function __construct($arg, $config)
{
$this->prop3 = $arg;
$this->config =$config;
}
public function getValue()
{
// do some operation
return 'some returned value';
}
public function getValueWithArgu($str)
{
// do some operation
return 'returned value is '.$str;
}
};
}
echo "\n";
var_dump($ano_class_obj_with_arg);
echo "\n";
echo $ano_class_obj_with_arg->prop1;
echo "\n";
echo $ano_class_obj_with_arg->prop2;
echo "\n";
echo $ano_class_obj_with_arg::SETT;
echo "\n";
echo $ano_class_obj_with_arg->getValue();
echo "\n";
echo $ano_class_obj_with_arg->getValueWithArgu('OOP');
echo "\n";
echo "\n";
No comments:
Post a Comment