PHP 7 vs. PHP 5.6

Type Hinting & Mutators

TL; DR

PHP 7's type hints allow one to skip the filter_var() step on bool, float, and int. When using scalar type hints, be sure to catch TypeError in the calling code.

PHP 7 added the ability to type hint anything. PHP 5.6 was limited to type hinting only classes, arrays, and callables. The new type hinting feature allows us to simplify the mutators for numerics since it will take over the role of manually using filter_var(). It is VERY important the caller catch TypeError when using PHP 7 enhanced mutators. This will be thrown in case the type hint fails. Also, prevent the default TypeError messsage from being displayed to the user. The default error message is very technical and not useful to an end user. Instead of directly using $typeError->getMessage(), a custom error message should be used.

PHP 5.6 Mutator

<?php
class PHP56Mutator {
	// rest of class omitted for brevity

	/**
	 * mutator method for profile id
	 *
	 * @param int $newProfileId new value of profile id
	 * @throws InvalidArgumentException if $newProfileId is not an integer or not positive
	 * @throws RangeException if $newProfileId is not positive
	 **/
	public function setProfileId($newProfileId) {
		// verify the profile id is valid
		$newProfileId = filter_var($newProfileId, FILTER_VALIDATE_INT);
		if($newProfileId === false) {
			throw(new InvalidArgumentException("profile id is not a valid integer"));
		}

		// verify the profile id is positive
		if($newProfileId <= 0) {
			throw(new RangeException("profile id is not positive"));
		}

		// convert and store the profile id
		$this->profileId = intval($newProfileId);
	}
}

PHP 7 Mutator

<?php
class PHP7Mutator {
	// rest of class omitted for brevity

	/**
	 * mutator method for profile id
	 *
	 * @param int $newProfileId new value of profile id
	 * @throws \RangeException if $newProfileId is not positive
	 * @throws \TypeError if $newProfileId is not an integer
	 **/
	public function setProfileId(int $newProfileId) {
		// verify the profile id is positive
		if($newProfileId <= 0) {
			throw(new \RangeException("profile id is not positive"));
		}

		// convert and store the profile id
		$this->profileId = $newProfileId;
	}
}

Errors vs. Exceptions

PHP 5.6 raised errors and warnings when code had a logical or syntax error. PHP 7 throws errors when logical or syntax errors occur. Errors implement Throwable, which is the base contract for Exception. While Error is not an exception, it can still be caught in a try…catch block. In particular, catch TypeError whenever a type hint is used. Catching TypeError is a necessary part of input sanitization in PHP 7.

Figure 1: PHP 5.6 & 7 Exception Tree
Figure 2: PHP 7 Error Tree

Null Coalescing Operator

PHP 7 added a null safe operator to handle when a variable is null. This operator will always return its first operand if it's not null, or the second operand if it is null. This is similar to what databases have been doing for years with functions such as mySQL's IFNULL() or Oracle's NVL() function.

PHP 5.6 Comparison

<?php
$foo = isset($bar) === true ? $bar : 42;

PHP 7 Comparison

<?php
$foo = $bar ?? 42;

Generating Hashes & Salts

PHP 7 includes a standardized function for generating cryptographically secure random pseudo bytes. Previous PHP 5.6 implementations were using openssl_random_pseudo_bytes(), which requires the OpenSSL extension to be installed. Although very common, the OpenSSL extension is not universally installed on all web hosts. PHP 7's new functions are a part of PHP 7 core and included in all installations.

PHP 5.6 Hash & Salt

<?php
$password = "abc123";
$salt = bin2hex(openssl_random_pseudo_bytes(16));
$hash = hash_pbkdf2("sha512", $password, $salt, 262144);

PHP 7 Hash & Salt

<?php
$password = "abc123";
$salt = bin2hex(random_bytes(16));
$hash = hash_pbkdf2("sha512", $password, $salt, 262144);