Enable strict types in PHP

Strict mode can be enabled to enforce type hinting for scalar types; strict mode can be enabled with a declare directive at the top of your index.php, ans will also apply to included files.

960 views
d

By. Jacob

Edited: 2021-02-14 01:50

Strict mode can be enabled in order to enforce type hinting for scalar types; traditionally PHP has been a weakly typed language, meaning taht a string could be used as an interger and vice versa, without halting the execution of the script. With strict mode enabled PHP will instead throw an error and halt script execution.

The strict_types=1 declaration can be added at the top of your composition root (I.e. your index.php) to apply the directive on a global scale for your project, this is done by using PHP's declare construct.

To enable strict mode for scalar types, you will need to include a single declare directive at the top of your index.php:

<?php
declare(strict_types=1);

include 'function.php';

echo say_hallo(200);

And the functions.php:

<?php

function say_hallo(string $string) {
  return $string;
}

The above will result in a type error:

Fatal error: Uncaught TypeError: say_hallo(): Argument #1 ($string) must be of type int, string given, called in /var/www/this.php on line 4 and defined in /var/www/functions.php:3 Stack trace: #0 /var/www/index.php(4): say_hallo() #1 {main} thrown in /var/www/functions.php on line 3

There rarely seem to be any problems associated with casting of scalar types, so the benefits of including the declaration to enable strict mode is equally minor.

How type hinting works in PHP

PHP is has traditionally been a weakly typed language, meaning that the four scalar type's is casted (converted) automatically by PHP when it encounters an unexpected type. For a long time this has even been the preferred behavior.

Think about it. Is there really a benefit in having your script halted just because you used a string in a function that expected an integer? Many developers prefer to follow strict rules when coding as it helps to prevent errors in the code and enforce good coding practices.

Since PHP is weakly typed, an integer passed on to a function or method that expects a string will just be cast (converted) to a string. In the vast majority of cases, this is totally fine, and maybe even the desirable thing to have happen, since it will give developers some leverage as to how functions can be used.

This is also called type juggling in PHP. But, while some might find this behavior useful, it might also have the undesired side-effect that developers do not think about the difference between a string and an integer, or a float; some might even be unaware that there is a difference, and that could lead to some confusion.

Classes used as types

In PHP any named class can also be used as a type, so when declaring dependencies, you can restrict the type of objects that are passed on in parameters.

When taking an object orientated approach, it is often preferred to use objects instead of arrays for passing on data via dependency injection to other objects. One of the primary benefits to using objects instead of arrays is that your code editor will give auto-complete suggestions for object properties, and, of course, another benefit is found in type hinting.

Because classes may be used as types in PHP, you can leverage them to ensure that the correct data-format is passed on to an object or function that depends on specific data.

Here is a "user" class used for creating new user objects:

$some_user = new user('Jacob', '[email protected]', 'Earth');

class user {
  public $name;
  public $email;
  public $address;

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

}

Then simply use the user class in the definition of a class or function that depends on this data:

class show_user {
  public $name;
  public $email;
  public $address;

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

     echo $this->user->name;
     exit();
  }

}

Now, if a developer tries to pass a wrong object to the show_user class, PHP will throw an error to alert the developer of the problem.

It may not seem like much, but making use of type hinting on this level will help developers catch errors early on — and it will also make the code more self-documenting.

Should you use strict mode?

strict_types=1 is only needed if you want strict type checking for scalar types, but there are still some clear benefits to enabling strict mode; for one, enforcing a strict coding style tends to make better developers, and that might be sufficient to warrant its inclusion.

Unlike what is stated in other articles on the internet, you do not actually need to include it in every single file. Enabling strict mode is a simple matter of including the directive once, at the top of your index.php or other, key, composition root's in your project.

Links

  1. declare - php.net

Tell us what you think:

  1. In this Tutorial, it is shown how to redirect all HTTP requests to a index.php file using htaccess or Apache configuration files.
  2. How to create a router in PHP to handle different request types, paths, and request parameters.
  3. Tutorial on how to use proxy servers with cURL and PHP
  4. When using file_get_contents to perform HTTP requests, the server response headers is stored in a reserved variable after each successful request; we can iterate over this when we need to access individual response headers.
  5. How to effectively use variables within strings to insert bits of data where needed.

More in: PHP Tutorials