1. Home
  2. Technical
  3. PHP
  4. How to test and update servers with deprecated PHP versions?

How to test and update servers with deprecated PHP versions?

Testing PHP version

If some of your virtual servers are using deprecated versions of PHP, a warning will appear on the My Zones Overview page.

 

 

Clicking the View button at the top of the page will take you to an overview page showing the deprecated PHP hosts (main and subdomains) on the server.

As PHP version changes can cause error messages to appear on the website and version changes can take up to 3 minutes, it is recommended to test the functionality of the website before making a change.

In order to test, click on the desired address in the list:

 

 

A test page will open with a selection of PHP versions in the header. Choosing between them will show you the result with different PHP versions. For example:

PHP 5.6:

PHP 8.1:

 

The minimum version of PHP that Zone allows you to choose is PHP 5.6, but be aware that it is also deprecated – it no longer has any developer patches for security vulnerabilities, although it can still technically be supported. It is recommended to upgrade to PHP 8.0, as PHP 5.6 is also outdated and no longer receiving security updates.

Modern web applications like WordPress supports latest PHP versions and upgrading to PHP 8.0 or 8.1 is suggested after updating WordPress plugins and themes.

Upgrading non-updated web applications to to PHP 8.x can be tricky as the differences between 5.6 and 7.x are large.

Known upgrade issues

Umlauts replaced with question marks

 

Default PHP 5.6 configuration adds UTF-8 encoding to HTTP response header and older websites that use other encodings in website text or meta may need to remove this header.

Easiest solution is adding .user.ini with following setting to webservers root folder htdocs:

default_charset = ''

Error message Fatal error […]

The website is not displayed and there is a message at the top of the page, for example:

Fatal error: Call to undefined function session_register() in [...]
Fatal error: Call to undefined function sqlite_open() in [...]
Fatal error: Call to undefined function wp_script_add_data() in [...]
Fatal error: Call-time pass-by-reference has been removed in [...]

This is a call to a function that has been removed from the PHP language, or that cannot be registered due to an update problem.

The exception is Call-time pass-by-reference has been removed, which has been removed due to a change in PHP syntax.

In order to update the application to a newer version of PHP, the exact cause of the error has to be determined and the code has to be fixed.

Error message Fatal error: Incompatible file format

The website is not displayed and an error message appears at the top of the page:

Fatal error: Incompatible file format: The encoded file has
format major ID 1, whereas the Loader expects 7
in /data[...]/htdocs/index.php on line 0

May occur with applications encrypted/licensed with Zend Guard, especially Saurus. PHP to version 5.6 is only possible by replacing and updating the application code (Saurus paid support is provided by Bonefarm). The web can be converted to static HTML, or migrated to modern content management like WordPress.

Error message: Cannot modify header information […]

This warning is displayed if other warnings or error messages are generated during page generation, which cannot be used to send HTTP request headers:

Warning: Cannot modify header information -
headers already sent by (output started at [...]wp-db.php:57)
in [...]

It has no independent meaning, can be ignored.

Error message Warning […]

When you open a webpage, a message appears at the top of the page or in one of its components:

Warning: Creating default object from empty value in [...]
Warning: file_put_contents(): Filename cannot be empty in [...]
Warning: get_class() expects parameter 1 to be object, string given in [...]
Warning: getimagesize(): Filename cannot be empty in [...]
Warning: Illegal string offset 'face' in [...]
Warning: Invalid argument supplied for foreach() in [...]

The parameter type or value of some functions does not match the expected one, which means that some of the functionalities of a web application may work differently than intended (mostly by simply not delivering the desired content).

If the functionality is not important you can ignore and disable Warning messages by adding a .user.ini file to your web root directory htdocs with the with following settings:

error_reporting = E_ALL & ~E_NOTICE & ~E_STRICT & ~E_DEPRECATED & ~E_WARNING

Zone default setting is: error_reporting = E_ALL & ~E_NOTICE & ~E_STRICT & ~E_DEPRECATED

Error message Deprecated […]

When you open a website, a message appears at the top of the page or in one of its components:

Deprecated: Assigning the return value of new by reference is deprecated in [...]
Deprecated: Function set_magic_quotes_runtime() is deprecated in [...]
Deprecated: mysql_connect(): The mysql extension is deprecated and will be removed in the future: use mysqli or PDO instead in [...]
Deprecated: preg_replace(): The /e modifier is deprecated, use preg_replace_callback instead in [...]

The referenced function, parameter or syntax will disappear in subsequent versions of PHP, but this will not affect the operation of the selected version.

In Zone Virtual Servers, the output of Deprecated messages is disabled by default, most likely due to a configuration change in the application code, less likely via global php.ini or .user.ini (see the example in the Warning message).

A command line search can be used to locate the setup location:

grep -r E_ALL .

For example, in the case of OpenCart 1.5, this will result in the following files:

./vqmod/vqcache/vq2-system_startup.php:error_reporting(E_ALL);
./system/startup.php:error_reporting(E_ALL);
./php.ini:;error_reporting = E_ALL;

The PHP code should be changed to error_reporting( E_ALL & ~E_NOTICE & ~E_STRICT & ~E_DEPRECATED ); and .ini in files error_reporting = E_ALL & ~E_NOTICE & ~E_STRICT & ~E_DEPRECATED

Database connection fails

If, after changing PHP to version 5.6+, the connection to the database fails, check that the database user is not using the old 6-digit password (the old cryptographic password).

The solution is to change the password of the database user. The new password will also work retroactively with PHP versions older than 5.6.

Navigation does not work

If navigation between pages does not work, or the requested action does not occur after submitting a form, this may be due to the assumption that the super-global GET, POST, Cookie (EGPCS) arrays are registered as normal variables.

This PHP feature was deprecated in PHP 5.3.0 and removed in PHP 5.4.0.

For example, a web page menu has links in the query string of the form domeen.ee/?lk=1 and in the PHP file that contains the page load logic, the $lk variable is used instead of the super-global $_GET['lk'] array.
Similarly for form submission, where the form element name <input type="submit" name="form_1" value="Saada"> is not checked against the super-global $_POST['form_1'] array, but directly against the $form_1 variable.

How to test which PHP version is in use?

Changing PHP version in server takes up to 3 minutes. To verify which version is currently in use add a .php file with random name to your websites’s root folder htdocs, containing:

<?php
phpinfo();

You can view the output by visiting example.com/random-name.php (for security reasons we recommend deleting this file).

PHP 5.6 → PHP 7.0

Changed error and exception handling

<?php
// PHP 5 era code that will break.
function handler(Exception $e) { ... }
set_exception_handler('handler');

// PHP 5 and 7 compatible.
function handler($e) { ... }

// PHP 7 only.
function handler(Throwable $e) { ... }
?>

Deprecated PHP 4 style construktors

Methods cannot have the same name as the class they are defined in.

<?php
class foo {
    function foo() {
        echo 'I am the constructor';
    }
}
?>

The above example will output:

Deprecated: Methods with the same name as their class will not be constructors in a future version of PHP; foo has a deprecated constructor in example.php on line 3

list() no longer assigns variables in reverse order

<?php
list($a[], $a[], $a[]) = [1, 2, 3];
var_dump($a);
?>

PHP 5.6 output:

array(3) {
  [0]=>
  int(3)
  [1]=>
  int(2)
  [2]=>
  int(1)
}

PHP 7.0 output:

array(3) {
  [0]=>
  int(1)
  [1]=>
  int(2)
  [2]=>
  int(3)
}

Learn more about 5.6 → 7.0 migration in PHP documentation

PHP 7.0 → PHP 8.0

PHP 7.0 → PHP 7.1

Previously, a warning would be emitted for invoking user-defined functions with too few arguments. Now, this warning has been promoted to an Error exception.

<?php
function test($param){}
test();
?>

The above example will output something similar to:

Fatal error: Uncaught ArgumentCountError: Too few arguments to function test(), 0 passed in %s on line %d and exactly 1 expected in %s:%d

Starting from PHP 7.1 it’s possible to mark return values as nullable by prefixing the type name with a question mark. This signifies that as well as the specified type, null can be passed as an argument, or returned as a value, respectively.

Additionally a void type has been introduced.

Learn more about 7.0 → 7.1 migration in PHP documentation

PHP 7.1 → PHP 7.2

Previously, it was possible for the number_format() function to return -0. Now it has been fixed and return value of -0.01 now outputs “0” instead of “-0”.

Deprecated parse_str() function without a second argument.

New type called object was added.

Shared extensions no longer require their file extension (.so for Unix or .dll for Windows) to be specified. This is enabled in the php.ini file, as well as in the dl() function.

Learn more about 7.1 → 7.2 migration in PHP documentation

PHP 7.2 → PHP 7.3

The declaration of case-insensitive constants has been deprecated. Passing true as the third argument to define() will now generate a deprecation warning.

Due to the introduction of flexible heredoc/nowdoc syntax, doc strings that contain the ending label inside their body may cause syntax errors or change in interpretation. For example in:

<?php
$str = <<<FOO
    abcdefg
    FOO
FOO;
?>

the indented occurrence of FOO did not previously have any special meaning. Now it will be interpreted as the end of the heredoc string and the following FOO; will cause a syntax error. This issue can always be resolved by choosing an ending label that does not occur within the contents of the string.

Learn more about 7.2 → 7.3 migration in PHP documentation

PHP 7.3 → PHP 7.4

Class properties now support type declarations:

<?php
class User {
    public int $id;
    public string $name;
}
?>

Deprecated nested ternary operators without explicit parentheses:

<?php
1 ? 2 : 3 ? 4 : 5; // deprecated
(1 ? 2 : 3) ? 4 : 5; // ok
1 ? 2 : (3 ? 4 : 5); // ok
?>

Parentheses are not required when nesting into the middle operand, as this is always unambiguous and not affected by associativity:

<?php
1 ? 2 ? 3 : 4 : 5 // ok
?>

The array and string offset access syntax using curly braces is deprecated. Use $var[$idx] instead of $var{$idx}.

PHP Fatal error: Array and string offset access syntax with curly braces is no longer supported in

The is_real() function is also deprecated, use is_float() instead.

Learn more about 7.3 → 7.4 migration in PHP documentation

PHP 7.4 → PHP 8.0

Non-strict comparisons between numbers and non-numeric strings now work by casting the number to string and comparing the strings. Comparisons between numbers and numeric strings continue to work as before. Notably, this means that 0 == "not-a-number" is considered false now.

Comparison Before After
0 == "0" true true
0 == "0.0" true true
0 == "foo" true false
0 == "" true false
42 == " 42" true true
42 == "42foo" true false

Reserved new words: match and mixed.

Methods with the same name as the class are no longer interpreted as constructors. The __construct() method should be used instead.

The ability to define case-insensitive constants has been removed. The third argument to define() may no longer be true.

Learn more about 7.4 → 8.0 migration in PHP documentation

PHP 8.0 → PHP 8.3

PHP 8.0 → PHP 8.1

When a method using static variables is inherited (but not overridden), the inherited method will now share static variables with the parent method:

<?php
class A {
    public static function counter() {
        static $counter = 0;
        $counter++;
        return $counter;
    }
}

class B extends A {}
var_dump(A::counter()); // int(1)
var_dump(A::counter()); // int(2)
var_dump(B::counter()); // int(3), previously int(1)
var_dump(B::counter()); // int(4), previously int(2)
?>

Learn more about 8.0 → 8.1 migration in PHP documentation

PHP 8.1 → PHP 8.2

Added attribute to hide sensitive parameters

Added the #[\SensitiveParameter] attribute to redact sensitive data in backtraces.

Learn more about 8.1 → 8.2 migration in PHP documentation

PHP 8.2→ PHP 8.3

php.ini now supports fallback/default value syntax:

<?php
/*
/path/to/user.ini contains the following settings:

listen = localhost:${DRUPAL_FPM_PORT:-9000}
*/

$user_ini = parse_ini_file('/path/to/user.ini');
echo $user_ini['listen']; // localhost:9000
?>

Learn more about 8.2 → 8.3 migration in PHP documentation

Updated on 26. Apr 2024

Was this article helpful?

Related Articles