What’s new in PHP 7.0

New features:

Scalar type declarations

Scalar type declarations come in two flavours: coercive (default) and strict. The following types for parameters can now be enforced (either coercively or strictly): strings (string), integers (int), floating-point numbers (float), and booleans (bool). They augment the other types introduced in PHP 5: class names, interfaces, array and callable.

<?php
// Coercive mode
function sumOfInts(int ...$ints)
{
    return array_sum($ints);
}

var_dump(sumOfInts(2, '3', 4.1));

Return type declarations

Null coalescing operator

<?php
// Fetches the value of $_GET['user'] and returns 'nobody'
// if it does not exist.
$username = $_GET['user'] ?? 'nobody';
// This is equivalent to:
$username = isset($_GET['user']) ? $_GET['user'] : 'nobody';

// Coalescing can be chained: this will return the first
// defined value out of $_GET['user'], $_POST['user'], and
// 'nobody'.
$username = $_GET['user'] ?? $_POST['user'] ?? 'nobody';
?>

Spaceship operator

<?php
// Integers
echo 1 <=> 1; // 0
echo 1 <=> 2; // -1
echo 2 <=> 1; // 1

// Floats
echo 1.5 <=> 1.5; // 0
echo 1.5 <=> 2.5; // -1
echo 2.5 <=> 1.5; // 1
 
// Strings
echo "a" <=> "a"; // 0
echo "a" <=> "b"; // -1
echo "b" <=> "a"; // 1
?>

Constant arrays using define()

<?php
define('ANIMALS', [
    'dog',
    'cat',
    'bird'
]);

echo ANIMALS[1]; // outputs "cat"
?>

Anonymous classes

<?php
// Using an explicit class - default
class Logger
{
    public function log($msg)
    {
        echo $msg;
    }
}

$util->setLogger(new Logger());

// Using an anonymous class - anonymus class
$util->setLogger(new class {
    public function log($msg)
    {
        echo $msg;
    }
});

Unicode codepoint escape syntax

$unicode= 0x1f606;
echo mb_chr($unicode);

Closure::call()

<?php
class Value {
    protected $value;

    public function __construct($value) {
        $this->value = $value;
    }

    public function getValue() {
        return $this->value;
    }
}

$three = new Value(3);
$four = new Value(4);

$closure = function ($delta) { var_dump($this->getValue() + $delta); };
$closure->call($three, 4);
$closure->call($four, 4);

Filtered unserialize()

<?php

// converts all objects into __PHP_Incomplete_Class object
$data = unserialize($foo, ["allowed_classes" => false]);

// converts all objects into __PHP_Incomplete_Class object except those of MyClass and MyClass2
$data = unserialize($foo, ["allowed_classes" => ["MyClass", "MyClass2"]]);

// default behaviour (same as omitting the second argument) that accepts all classes
$data = unserialize($foo, ["allowed_classes" => true]);

IntlChar – The new IntlChar class seeks to expose additional ICU functionality. The class itself defines a number of static methods and constants that can be used to manipulate unicode characters.

<?php
printf('%x', IntlChar::CODEPOINT_MAX);
echo IntlChar::charName('@');
var_dump(IntlChar::ispunct('!'));

Expectations

Expectations are a backwards compatible enhancement to the older assert() function. They allow for zero-cost assertions in production code, and provide the ability to throw custom exceptions when the assertion fails.

While the old API continues to be maintained for compatibility, assert() is now a language construct, allowing the first parameter to be an expression rather than just a string to be evaluated or a bool value to be tested.

public function __construct(array $data)
{
    assert(isset($data['type']) && is_string($data['type']), '"type" not set/wrong');

    assert(isset($data['title']) && is_string($data['title']), '"title" not set/wrong');

    assert(isset($data['status']) && is_int($data['status']), '"status" not set/wrong');

    assert(isset($data['detail']) && is_string($data['detail']), '"detail" not set/wrong');

    $this->data = $data;
}

Group use declarations

use com\India\{ClassX, ClassY, ClassZ as Z};
use function com\India\{fn_x,fn_y, fn_z};
use const com\India\{ConstX, ConstY, ConstZ};

Generator Return Expressions

https://www.youtube.com/watch?v=A81TAMMb3sk
https://www.youtube.com/watch?v=xH3snMmgDWg
<?php
   function gen(){
      yield 'A';
      yield 'B';
      yield 'C';
      return 'gen-return'; // <<<<<
   }
   $generator = gen();
   var_dump($generator);
   foreach ($generator as $letter){
      echo $letter;
   }
   var_dump($generator->getReturn());

https://subscription.packtpub.com/book/application_development/9781785882814/1/ch01lvl1sec11/generator-delegation

Generator delegation

Integer division with intdiv() 

Session options

preg_replace_callback_array()

Two new functions have been added to generate cryptographically secure integers and strings in a cross-platform way: random_bytes() and random_int().

list() can always unpack objects implementing ArrayAccess 

Class member access on cloning has been added, e.g.

(clone $foo)->bar()

New functions ¶

Closure ¶

CSPRNG ¶

Error Handling and Logging ¶

Generator ¶

GNU Multiple Precision ¶

Math ¶

PCRE ¶

PHP Options/Info ¶

POSIX ¶

Reflection ¶

Zip ¶

Zlib Compression ¶

Braking changes:

Changes to error and exception handling

Changes to the handling of indirect variables, properties, and methods

Code that used the old right-to-left evaluation order must be rewritten to explicitly use that evaluation order with curly braces (see the above middle column). This will make the code both forwards compatible with PHP 7.x and backwards compatible with PHP 5.x.

This also affects the global keyword. The curly brace syntax can be used to emulate the previous behaviour if required:

<?php
function f() {
    // Valid in PHP 5 only.
    global $$foo->bar;

    // Valid in PHP 5 and 7.
    global ${$foo->bar};
}
?>

Changes to list() handling

list() no longer assigns variables in reverse order

foreach by-value operates on a copy of the array ¶

When used in the default by-value mode, foreach will now operate on a copy of the array being iterated rather than the array itself. This means that changes to the array made during iteration will not affect the values that are iterated.

foreach by-reference has improved iteration behaviour ¶

When iterating by-reference, foreach will now do a better job of tracking changes to the array made during iteration. For example, appending to an array while iterating will now result in the appended values being iterated over as well

Iteration of non-Traversable objects ¶

Iterating over a non-Traversable object will now have the same behaviour as iterating over by-reference arrays. This results in the improved behaviour when modifying an array during iteration also being applied when properties are added to or removed from the object.

What’s new in PHP 7.1

New features:

Nullable Types.

/**
* @param ?string x Function can take null value or string
* 
* @return ?string x returns null or string (don't get mistaken with void)
*/
function testReturn(?string $x): ?string
{
    return x;
}

Void Returns.

A void return type has been introduced. Functions declared with void as their return type must either omit their return statement altogether, or use an empty return statement. null is not a valid return value for a void function.

/**
* Example of void return type (no return or empty return statement)
*/
function swap(&$left, &$right): void
{
    if ($left === $right) {
        return;
    }

    $tmp = $left;
    $left = $right;
    $right = $tmp;
}

$a = 1;
$b = 2;
var_dump(swap($a, $b), $a, $b);

Multi-Catch Exception Handling

From PHP 7.1 you can catch multiple pipe separated exceptions class in one statement

try {
    // some code
} catch (FirstException | SecondException $e) {
    // handle first and second exceptions
}

Iterables

The Iterable pseudo class may be used in parameter and return types, where it accepts either arrays or objects that implement the Traversable interface.

/**
* Example of use of Iterable pseudo class
*/
function iterator(iterable $iter)
{
    foreach ($iter as $val) {
        //
    }
}

Symmetric array destructuring

$data = [
    [1, 'Tom'],
    [2, 'Fred'],
];

// list() style
list($id1, $name1) = $data[0];

// [] style
[$id1, $name1] = $data[0];

// list() style
foreach ($data as list($id, $name)) {
    // logic here with $id and $name
}

// [] style
foreach ($data as [$id, $name]) {
    // logic here with $id and $name
}

Keys Can Now Be Used in Lists

<?php
$data = [
    ["id" => 1, "name" => 'Tom'],
    ["id" => 2, "name" => 'Fred'],
];

// list() style
list("id" => $id1, "name" => $name1) = $data[0];

// [] style
["id" => $id1, "name" => $name1] = $data[0];

// list() style
foreach ($data as list("id" => $id, "name" => $name)) {
    // logic here with $id and $name
}

// [] style
foreach ($data as ["id" => $id, "name" => $name]) {
    // logic here with $id and $name
}

Class constant visibility 

Support for specifying the visibility of class constants has been added.

class ConstDemo
{
    const PUBLIC_CONST_A = 1;
    public const PUBLIC_CONST_B = 2;
    protected const PROTECTED_CONST = 3;
    private const PRIVATE_CONST = 4;
}

More Negative String Offsets.

Number Operators And Malformed Numbers.

Support for negative string offsets ¶

Convert callables to Closures with Closure::fromCallable() ¶

<?php
class Test
{
    public function exposeFunction()
    {
        return Closure::fromCallable([$this, 'privateFunction']);
    }

    private function privateFunction($param)
    {
        var_dump($param);
    }
}

$privFunc = (new Test)->exposeFunction();
$privFunc('some value');

What’s new in PHP 7.2

New features:

What’s new in PHP 7.3

New features:

More Flexible Heredoc and Nowdoc Syntax ¶

The closing marker for doc strings is no longer required to be followed by a semicolon or newline. Additionally, the closing marker may be indented, in which case the indentation will be stripped from all lines in the doc string.

Array Destructuring supports Reference Assignments ¶

Array destructuring now supports reference assignments using the syntax [&$a, [$b, &$c]] = $d. The same is also supported for list().

Instanceof Operator accepts Literals ¶

instanceof now allows literals as the first operand, in which case the result is always false.

Braking changes:

What’s new in PHP 7.4

https://www.php.net/manual/en/migration74.new-features.php

New features:

Typed properties 

Arrow functions

Limited return type covariance and argument type contravariance

Null coalescing assignment operator

Unpacking inside arrays

New functions:

There will be no PHP 7.5!

What’s new in PHP 8.0

https://www.php.net/manual/en/migration80.php

Changes String to Number Comparison results.

Braking changes:

  • The ability to use array_key_exists() with objects has been removed. isset() or property_exists() may be used instead.
  • The default error_reporting level is now E_ALL. Previously it excluded E_NOTICE and E_DEPRECATED.

New features:

  1. Named Arguments
  2. array_fill(start_index: 0, count: 100, value: 50);
  3. Attributes
  4. #MyClass
  5. Constructor Property Promotion
  6. Union Types
  7. Match Expression
<?php
$expressionResult = match ($condition) {
    1, 2 => foo(),
    3, 4 => bar(),
    default => baz(),
};
?>

Nullsafe Operator

<?php

// As of PHP 8.0.0, this line:
$result = $repository?->getUser(5)?->name;

// Is equivalent to the following code block:
if (is_null($repository)) {
    $result = null;
} else {
    $user = $repository->getUser(5);
    if (is_null($user)) {
        $result = null;
    } else {
        $result = $user->name;
    }
}
?>

What’s new in PHP 8.1

Integer Octal Literal Prefix

Array Unpacking with String Keys

<?php
$arr1 = [1, 'a'];
$arr2 = [...$arr1, 'c' => 'd']; //[1, 'a', 'c' => 'd']
?>

Enumerations  – Enum support

https://www.youtube.com/watch?v=5Cgio2OfOYk
enum Colors
{
    case Red;
    case Blue;
    case Green;

    public function getColor(): string
    {
        return $this->name;
    }
}

function paintColor(Colors $colors): void
{
    echo "Paint : " . $colors->getColor() . PHP_EOL;
}

paintColor(Colors::Red);
paintColor(Colors::Green);
paintColor(Colors::Blue);

/*
    output :
    ------------------------
    Paint : Red
    Paint : Green
    Paint : Blue
*/
?>

Fibers where added

<?php
$fiber = new Fiber(function (): void {
   $value = Fiber::suspend('fiber');
   echo "Value used to resume fiber: ", $value, PHP_EOL;
});

$value = $fiber->start();

echo "Value from fiber suspending: ", $value, PHP_EOL;

$fiber->resume('test');
?>
1
0
Would love your thoughts, please comment.x
()
x