PHP 7.1 : What got introduced?
17, January 2020

Nullable types

Nullable type means, If a function accepts string type, by marking it nullable we can accept both string and null as valid type.

To mark your type as nullable, just add a question mark (?) before your type definition.

<?php

function has_name(?string $name)
{
    // $name can be string or null
}

function return_score(): ?int 
{
   // we can return int or null here
}

Personal note: please avoid using nullable types as much as you can. Null can reduce type safety if used poorly.


Void return types

Sometimes, we use some method to only change the object state, these functions do not need to return anything. In such cases, we can use void as return type to restrict method returns.

If a method has a void return type, that method should not have any return statement, or we can only use an empty return statement without any value.

<?php

class Student {
   protected $name;
   protected $score;

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

    public function setScore(int $score): void{
       $this->score = $score;
       
        // we can use empty return statement herereturn;
        // notice how we didn't return any value.
    }
        
}

Note: Not even returning null is allowed in void return type.


Array destructuring

We all love that shorthand array syntax ([ ]), right? From now, we can use the same syntax to destructure our arrays too. This works the same as list() function.

<?php

$array ['John', 10];

// using list()
list($name, $class) = $array;

// we can do same with []
[$name, $class] = $array;

// we can use in foreach too
$students = [
   ['Alice', 8],
   ['Bob', 9]
];

foreach($students as [$name, $class]){
   // Both $name and $class is available here
}


Class constant visibility

Every project has some magic values that are fixed in the code base. Where do you define them? I love to store those hardcoded values in class constant. It keeps them defined in a clean manner so I can refactor them whenever I want.

PHP 7.1 lets us define visibility for those class constants. So our class constants now can be either public, protected or private, just like class properties.

<?php

class User {
   public ACTIVE_USER_STATUS = 1;
   public INACTIVE_USER_STATUS = 0;

   private PASSWORD_MIN_LENGTH = 15;
}



Iterable pseudo-type

We can now use the iterable type as a parameter or return type which accepts either array or objects that implement Traversable Interface.

<?php

class TraversableObj implements Traversable
{
   // implementation here
}

function lets_traverse(iterable $values)
{
   foreach ($values as $value){
      // some logic here
   } 
}


$object = new TraversableObj();
$array = [1.2.3.4.5];

// we can pass both $object and $array to lets_traverse();

lets_traverse($object);
lets_traverse($array);


Multi catch exception handling

Don't let your exceptions go uncaught, catch'em all. :p

Sometimes we call some functions which can throw multiple exceptions and we need to catch them. PHP 7.1 makes it easier by introducing multi catch block.

<?php

function connect_to_db(array $credentials){
   // If invalid credential array, we throw InvalidArgumentException

   // If username in credential is root, we throw RootNotAllowedException

   // If connection failed, we throw ConnectionFailedException
}

// lets now connect to db
try {
   connect_to_db($credentials);
} catch(ConnectionFailedException $ex){
   // connection failed, log the error and fallback to some other login
} catch(InvalidArgumentException | RootNotAllowedException $ex){
   // Multi catch exception handling here
}


Destructuring array with Key support

Wohooo, now we can destructure arrays with non-integer or non-sequential keys. Both list() and [ ] can be used with non-numeric keys.

<?php

$students = [
   ['id' => 1, 'name' => 'Alice'],
   ['id' => 2, 'name' => 'Brad'],
   ['id' => 3, 'name' => 'Chris'],
];

list('id' => $id, 'name' => $name) = $students[0];

['id' => $id, 'name' => $name] = $students[0];


Support for negative string offsets

string manipulation functions now can utilize negative offset. A negative offset is interpreted as being an offset from the end of the string.


<?php

$string = 'White Fox';

// we can get last character by using negative offset
echo $string[-1];
// Output: x

var_dump(strpos("Hello", "l", -2));
// int(3) 


Closure::fromCallable

Simple callbacks can now be converted to Closure with new static method Closure::fromCallable()

<?php

$closure = Closure::fromCallable('strtolower');
// invoking this closure will be same as invoking strtolower() function

$closure = Closure::fromCallable([$object, 'methodName']);
// invoking this closure will be same as invoking $object->methodName()

Personal Note: Please avoid using such callback as much as you can. Function/method names as string are harder to debug, track and refactor. If it is possble, please use Closure to achieve the same functionality. If I am doing OOP, Closure is a must for me.


Asynchronous signal handling

This one is my favourite. PHP is not a web-only language. PHP's CLI is a fairly powerful tool to maintain your background tasks with a long running life cycle.

I even automate some of my day-to-day desktop tasks with PHP CLI.

During CLI coding with PHP, often I need to handle inter-process signals (*nix only) asynchronously. Till now I had to use declare(ticks=1), but that comes with decent impact on execution performance.

But Fear not, with PHP 7.1 you can handle such signals in asynchronous manner, using pcntl_async_signals()

<?php
pcntl_async_signals(true);

pcntl_signal(SIGTERM, function ($signal) {
    echo 'You have been TERMINATED'; die;
});

while (true) {
    // Here is your long running logic
    usleep(500);
}

During running this script, if a SIGTERM signal is passed to the process (via kill PID), it will print out the message and exit.

to make CLI even better, Additional Context has been added in pcntl_signal Handler().