All you need to know about PHP 7.x — Part 2

Sandeep Kadam
May 6 · 12 min read
PHP 7

This is article Part 2 of “All you need to know about PHP7”. In Part 1 we covered the importance of PHP7 and why should we upgrade to latest PHP7 version. In Part 2, we are going to cover the below topics.

  • Features/functions removed/added in PHP 7

1) Features/functions removed/added in PHP 7

Following are some of the list of functions/features which are removed/added in PHP7.

  • PHP4 constructors now deprecated

PHP4 constructors are the methods that have the same name as the class they are defined in. PHP7 will emit an E_DEPRECATED when encountering a PHP4 constructor (in PHP8 this method will no longer be recognized as a constructor). This change may only produce problems with custom error handlers.

  • Multiple default cases disallowed in Switch case

The switch will no longer accept multiple default statements. In earlier PHP versions, switch() would have evaluated the final default in the example below.

switch ($expr) {
default:
neverExecuted();
break;
default:
executed();
}

But in PHP7, the result of this code will be: Fatal error: Switch statements may only contain one default

  • Removal of ASP and Script Tags

PHP7 will no longer recognize alternative tags such as <%, <%=, %>, and <script language=”php”>. PHP7 will only recognize the traditional <?php and ?>.

  • Regular expression, MySQL extensions, and features

The ereg extension and all ereg_* associated functions have been removed (deprecated in PHP 5.3) and replaced by the PCRE extension: preg_*.

A new preg_replace_callback_array() function has been added to perform a regular expression search and replace using callbacks. Check below example

$message = ‘Medium.com is faaantaaastic source of informaaation’;preg_replace_callback_array(
[
‘~[a]+~i’ => function ($match) {
echo strlen($match[0]), ‘ matches for “a” have been found’;
},
‘~[i]+~i’ => function ($match) {
echo strlen($match[0]), ‘ matches for “i” found’;
},
‘~[o]+~i’ => function ($match) {
echo strlen($match[0]), ‘ matches for “o” found’;
}
],
$message
);
// Result
3 matches for "a" have been found
3 matches for "a" have been found
3 matches for "a" have been found
1 matches for "i" found
1 matches for "i" found
1 matches for "i" found
1 matches for "i" found
1 matches for "i" found
1 matches for "o" found
1 matches for "o" found
1 matches for "o" found
1 matches for "o" found
1 matches for "o" found

The MySQL function (deprecated since PHP 5.5) has also been changed from mysql_* to mysqli_*.

The assignment of new by reference will now produce an error.

  • Hex string no longer recognized as numerical

To clear up inconsistent handling of hexadecimal numbers, PHP7 will no longer recognize a hex string as a number. This change will primarily affect the is_numeric() function and the mathematical operators (e.g., ==, +, -, *, /, %, **, ++, and –)

// In PHP5
var_dump(is_numeric(‘0x16a’));
// Return bool(true)
// In PHP7
var_dump(is_numeric(‘0x16a’));
// Return bool(false)
  • Division by zero results change

PHP7 adjusts how it reacts to situations in which it attempts to divide a value by zero. In previous versions, division by zero resulted in a boolean false. Now, dividing (/) by zero will return a float INF or NAN; using a zero divisor in a modulus (%) operation will return an error.

var_dump(5/0); // will result in float(INF)
var_dump(0/0); // will result in float(NAN)
var_dump(5%0); // will produce DivisionByZeroError
  • Invalid octal errors

An invalid octal literal (such as one containing a non-octal digit) will now produce an error, instead of making a best-effort to render the value.

// In PHP5
$octal = 0149;
echo $octal; // Display 12 (rendering octal value 0014)
// In PHP7
$octal = 0148;
echo $octal;
// Return: Parse Error: Invalid numeric literal…
  • Uniform variable syntax

Nested variables often resulted in code that was difficult to read as a variable assignment was read right-to-left. The variable resolution now happens left-to-right in an effort to make code-writing and -reading a simpler task.

// code                  // old evaluation         // new evaluation
$$varname[‘dot’][‘net’] ${$varname[‘dot’][‘net’]} | ($$varname)[‘dot’][‘net’]
$varname->$dot[‘net’] | $varname->{$dot[‘net’]} | ($varname->$dot)[‘net’]
$varname->$dot[‘net’]() | $varname->{$dot[‘net’]}() | ($varname->$dot)[‘net’]()
varname::$dot[‘net’]() | varname::{$dot[‘net’]}() | (varname::$dot)[‘net’]()

Old code can achieve the same effect in PHP7 with the use of braces ({}) as in the center column above.

  • Filtered unserialize()

The unserialize() function has been existing since PHP 4. It allows you to take a single serialized variable and convert back into a PHP value.

In PHP 7, the options parameter has been added. You can now whitelist classes that can be unserialized like so:

// converts all objects into __PHP_Incomplete_Class object
unserialize($obj, [“allowed_classes” => false]);
// converts all objects into __PHP_Incomplete_Class object except those of FirstClass and SecondClass
unserialize($obj, [“allowed_classes” => [“FirstClass”, “SecondClass”]]);
// default behaviour (same as omitting the second argument) that accepts all classes
unserialize($obj, [“allowed_classes” => true]);

It was introduced to enhance security when unserializing objects on untrusted data.

Note: In PHP 7.1, the allowed_classes element of the options parameter is now strictly typed. unserialize() returns false if anything other than an array or boolean is given.

  • Enhanced Unicode Support

In PHP 7, all you need is the hexadecimal code appended to “\u” and you’ll have your symbol/emoji as an output. An example is this:

function getMoneySymbol() {
echo “\u{1F4B0}”;
}
getMoneySymbol();// Result
💰

The enhancements were made possible from the Unicode codepoint escape syntax RFC.

Now, you can also get the name equivalent of the unicode character, say “\u{1F4B0}” via the new IntlChar class like so:

echo IntlChar::charName(“\u{1F4B0}”);
You can get the character from the name like so:

var_dump(IntlChar::charFromName(“LATIN CAPITAL LETTER A”));
var_dump(IntlChar::charFromName(“SNOWMAN”));
var_dump(IntlChar::charFromName(“TURTLE”));

Note: The IntlChar class contains about 600 constants and 59 static methods.

This was made possible from the IntlChar RFC. The PHP manual has extensive documentation on IntlChar class.

  • Null Coalescing Operator

The purpose of this new operator ?? is to allow developers to set values from user inputs without having to check if the value has been set. Before PHP 7, this is how you evaluate input. Check this out:

$article_source = isset($_GET[‘article_source’]) ? $_GET[‘article_source’] : ‘medium.com’;

If the value of $_GET[‘article_source’] exists, it returns the value else it assigns medium.com to the $article_source variable. In PHP 7, you can simply shorten that line of code using the ?? an operator like so:

// PHP 7
$article_source = $_GET[‘article_source’] ?? ‘medium.com’;

It automatically checks whether the value is set and assigns the value to $article_source variable if it is, else it returns medium.com.

The Null coalescing operator also allows you to chain expressions like so:

// PHP 7$_ENV[‘article_source’] = ‘medium.com’;$article_source = isset($_GET[‘article_source’]) ?? $_ENV[‘article_source’] ?? ‘medium’;// Result
medium.com

This will assign the first defined value to the $article_source variable.

  • Error Handling

Many fatal and recoverable fatal errors have been converted to exceptions in PHP 7. Most errors are now reported by throwing Error exceptions. The Exception class now implements a Throwable Interface.

You can catch specific Errors like so:

try {
// evaluate something
} catch (\ParseError $e) {
// do something
}

In PHP 7.1, you can catch multiple errors and exceptions in one catch block like so:

try {
// Some code…
} catch (ExceptionTypeA | ExceptionTypeB | ExceptionTypeC $e) {
// Code to handle the exception
} catch (\Exception $e) {
// …
}

This is particularly useful when one method throws a different type of exceptions that you can handle the same way.

Note: A new error_clear_last() method has been added to clear the most recent error. Once used, calling error_get_last() will be unable to retrieve the most recent errors.

Check out more about the Catching Multiple Exception Types RFC

  • Integer Division

PHP 7 introduced a new function intdiv() which returns the result of an integer division operation as int.

// PHP 7
$result = intdiv(10, 4);
// Result:
2
  • Constant Arrays Using define()

In PHP 7, you can also define the array as a constant by using define.
Example:

define(‘NAME’, array(‘john’,’doe’,’sandy’));
echo NAME[1]; // outputs “doe”
  • Spaceship Operator

The Spaceship operator is represented like this <=>. It is used to compare two expressions and return -1, 0, 1 when one variable is less than, equal to, or greater than, as compared to the other variable.
Example:

// Integers
echo 1 <=> 1; // 0
echo 1 <=> 2; // -1
echo 2 <=> 1; // 1
  • Typed properties (PHP 7.4)

With the introduction of scalar types and return types, PHP 7 greatly increased the power of PHP’s type system. However, it is currently not possible to declare types for class properties, forcing developers to use getter and setter methods instead to enforce type contracts. This requires unnecessary boilerplate, makes usage less ergonomic and hurts performance. This RFC resolves this issue by introducing support for first-class property type declarations.

The RFC provides an example where the goal is to enforce type-safety:

class User {
/** @var int $id */
private $id;
/** @var string $name */
private $name;
public function __construct(int $id, string $name) {
$this->id = $id;
$this->name = $name;
}
public function getId(): int {
return $this->id;
}
public function setId(int $id): void {
$this->id = $id;
}
public function getName(): string {
return $this->name;
}
public function setName(string $name): void {
$this->name = $name;
}
}

With the new accepted RFC, that code could be functionally equivalent as follows “without sacrificing type safety”:

class User {
public int $id;
public string $name;
public function __construct(int $id, string $name) {
$this->id = $id;
$this->name = $name;
}
}

Finally, here’s an example of all the valid types supported in runtime-enforced annotations for typed properties:

class Example {
// All types with the exception of “void” and “callable” are supported
public int $scalarType;
protected ClassName $classType;
private ?ClassName $nullableClassType;
// Types are also legal on static properties
public static iterable $staticProp;
// Types can also be used with the “var” notation
var bool $flag;
// Typed properties may have default values (more below)
public string $str = “foo”;
public ?string $nullableStr = null;
// The type applies to all properties in one declaration
public float $x, $y;
// equivalent to:
public float $x;
public float $y;
}

Learn more about Typed Properties RFC here

  • Session_start config enhancements

The session_start() method now accepts an array of values that can override the session config in php.ini file.

session.lazy_write which is on by default can be turned off by explicitly stating it in thesession_start() method like so:

session_start([
‘lazy_write’ => false,
‘cache_limiter’ => ‘private’
]);
  • Unpack objects with list()

The list() language construct now allows you to unpack objects implementing the ArrayAccess interface.

$fruits = new ArrayObject(['banana', 'mango', 'apple']);list($a, $b, $c) = $fruits;echo $a. PHP_EOL;
echo $b. PHP_EOL;
echo $c. PHP_EOL;
// Result
banana
mango
apple

Note: In PHP 7.0.0 list() expressions can no longer be completely empty. In PHP 5, list() assigns the values starting with the right-most parameter. In PHP 7, list() starts with the left-most parameter. This is true when working with arrays with indices.

  • dirname() enhancement

The dirname() in PHP 5 returns a parent directory’s path. In PHP 7.0.0, an optional levels parameter has been added to the function to allow you as developer determine how many levels up you want to go when getting a path.

$path = ‘/projectfolder/source/medium_project/drupal/modules’;dirname($path, 3);// Result
/projectfolder/source
  • More list of Deprecated Features

Static calls to methods that are actually not static are deprecated.

class Economy {
function affordTeslaCar() {
echo ‘I think I might not be able to afford tesla car with this economy’;
}
}
Economy::affordTeslaCar();// Result
Deprecated: Non-static method Economy::affordTeslaCar() should not be called statically in …

The salt option for the password_hash() function has been deprecated to prevent developers from generating their own salts which are most insecure.

The capture_session_meta SSL context option has been deprecated. stream_get_meta_data() can now be used to get SSL metadata.

The ldap_sort() function has been deprecated.

global can no longer accept variable variables unless you fake it by using the curly brace like so global ${$foo->bar}.

An E_WARNING will be emitted and NULL will be returned when internal functions try to perform float to integer automatic conversions.

Prefixing comments with # in php.ini file is no longer allowed. Only semi-colons(;) should be used.

Dividing by 0 will emit an E_WARNING and also one of either +INF, -INF, or NAN.

$HTTP_RAW_POST_DATA was deprecated in PHP 5.6.0 and finally removed in PHP 7.0.0. Use php://input as a replacement.

Switch statements can no longer have multiple default blocks. An E_COMPILE_ERROR will be triggered if you try to define more than one default block.

Functions can not have multiple parameters with the same name. function slap($hand, $hand, $strength). An E_COMPILE_ERROR will be triggered as a result of this function.

Static calls made to a non-static method with an incompatible context will now result in the called method having an undefined $this variable and a deprecation warning being issued.

  • Removed Extensions and SAPIs

The ext/mysql, ext/mssql, ereg and sybase_ct extensions have been removed. All the mysql_ functions have been removed! You should either use the ext/mysqli extension or use the ext/pdo extension which has an object-oriented API.

The aolserver, apache, apache_hooks, apache2filter, caudium, continuity, isapi, milter, nsapi, phttpd, pi3web, roxen, thttpd, tux and webjames SAPIs have been removed.

More detail list of PHP7 deprecated functions you can find on https://php.net/manual/en/migration70.incompatible.php

2) Miscellaneous information/tips for PHP 7

Below information will help you in building PHP7 application/websites and some handy tips.

  • PHP7 compatibility code validation

https://github.com/PHPCompatibility/PHPCompatibility this is a very handy library to check PHP cross-version compatibility code.

  • “Phan” static code analyzer

Phan looks for common issues and will verify type compatibility on various operations when type information is available or can be deduced.

  • Wordpress PHP compatibility checker

If your website is built using Wordpress, then this WordPress plugin “PHP compatibility checker” will be very handy for you in development.

  • Using PhpStorm IDE

Users who are using PhpStorm IDE can also make use of a “PHP 7 Compatibility Inspection”, which (now) can be found under “Language Level” in the settings. It works in rather different ways with different features and output. PHP IDE gives you the most comprehensive help in finding deprecated features and syntax in your code.

  • PHP 7 Migration Assistant Report (MAR)

PHP 7 MAR, or just “php7mar”, is a command line utility to generate reports on existing PHP 5 code to assist developers in porting their code quickly to PHP 7. It will run against individual files or entire project folders. Reports contain line numbers, issues noted and suggested fixes along with documentation links

php mar.php -f="/path/to/project/root/" -r="/path/to/output/"
  • PHPStan — PHP Static Analysis

PHPStan focuses on finding errors in your code without actually running it. It catches whole classes of bugs even before you write tests for the code.

  • PHP 7 Performance tips

Optimize & tweak php.ini file

[PHP]
engine = On
short_open_tag = off
precision = 14
output_buffering = off
zlib.output_compression = off
implicit_flush = off
implicit_flush = off
unserialze_callback_func =
serialize_precision = I7
;open_basedir =
disable_classes =
;ignore_user_abort = On
realpath_cahe_size = 256k
realpath_cache_ttl = 300
zend.enable_gc= On
expose_php = off
max_execution_time = 30
max_input_time = 60
;max_input_nesting_level = 64
;max_input_vars = 1000
memory_limit = 128M
error_reporting = E_ALL & ~E_DEPRECATED & ~E_STRICT
display_errors = Off
display_startup_errors = off
realpath_cache_size = 256k
realpath_cache_ttl = 300

For high traffic web servers running PHP, you can squeeze out additional throughput by setting PHP realpath_cache_size correctly.

mysqlnd.collect_statistics = Off
mysqlnd.collect_memory_statistics = Off

Check your php.ini and make sure on your production servers, both of these settings mysqlnd.collect_statistics & mysqlnd.collect_memory_statistics are disabled. Should be always disabled unless you have a specific reason to enable. You can view MySQL run-time statistics using the MySQL command line (ex. show status;). Also related to MySQL, depending on your scripts, it may help setup PHP Redis and/or Memcached to reduce MySQL queries.

output_buffering = Off

PHP’s output buffer controls how HTML is sent to the browser. When set to ‘Off’ (the default), HTML is sent to the browser immediately while PHP processes through your scripts. With output buffering set to ‘On’, PHP output buffer saves what would have otherwise hit the web browser into a single string in a buffer.

That’s the end of this article, hope you like it.


Conclusion

We have successfully covered all the new features of PHP 7 in Part 1 and this article. It might be overwhelming at first because it is a major version change with a lot of new features and lots of deprecations.

Going over the rundown of all these features as highlighted in this article series and using it as a handy reference will give you all the necessary information to migrate to PHP 7.

I hope the information given in both series will be useful and will help you.

The release of PHP 8.0 is not yet scheduled, but as it’s a major leap it will take some years. From now there is no details of the features either, but the schedule is estimated to be years away. Some speculation sets the release of PHP 8.0.0 to be in September 2021 by Lary Garfield:

Sandeep Kadam

Written by

Fullstack Developer, lover of PHP & Web Development