migrating to php 7

27
Migrating to PHP 7 John Coggeshall – International PHP Conference, 2016 Berlin, Germany @coogle, [email protected]

Upload: john-coggeshall

Post on 21-Jan-2017

809 views

Category:

Internet


0 download

TRANSCRIPT

Page 1: Migrating to PHP 7

Migrating to PHP 7John Coggeshall – International PHP Conference, 2016

Berlin, Germany@coogle, [email protected]

Page 2: Migrating to PHP 7

Who’s This Guy?

• The Author of ext/tidy• (primary) Author in (almost) 5 books on PHP going from

PHP 4 to PHP 7• Speaking at conferences for a long time

!!!!!

circa 2004

today

Page 3: Migrating to PHP 7

Major Concerns when Migrating to PHP 7

• Error Handling• Variable Handling• Control Structure Changes• Removed Features / Changed Functions• Newly Deprecated Behaviors

• This talk will not cover every single detail of the changes in PHP 7. That’s what Migration Documentation is for:

http://php.net/manual/de/migration70.php

Page 4: Migrating to PHP 7

Error Handling

• One of the biggest breaks you may have to deal with migrating to PHP 7 will be error handling• Especially when using Custom Error Handlers

• Many fatal / recoverable errors from PHP 5 have been converted to exceptions

• Major Break: The callback for set_exception_handler() is not guaranteed to receive \Exception objects

Page 5: Migrating to PHP 7

Fixing Exception Handlers

<?php

function my_handler(\Exception $e) {

/* ... */

}

<?php

function my_handler(Throwable $e) {

/* ... */

}

PHP 5

PHP 7

Page 6: Migrating to PHP 7

Other Internal Exceptions

• Some internal class constructors in PHP 5 would create objects in unusable states rather than throw exceptions• In PHP 7 all class constructors throw exceptions• Notably this was a problem in some of the Reflection

Classes

You should always be prepared to handle an exception thrown from PHP 7 internal classes in the event something

goes wrong

Page 7: Migrating to PHP 7

Parser Errors

• In PHP 5, parsing errors (for instance, from an include_once statement) would cause a fatal error• In PHP 7 parser errors throw the new ParseError exception

Again, your custom error handlers and exception handlers may need updating to reflect this new behavior

Page 8: Migrating to PHP 7

E_STRICT is Dead

Situation New BehaviorIndexing by a Resource E_NOTICEAbstract Static Methods No Error”Redefining” a constructor No ErrorSignature mismatch during inheritance E_WARNINGSame (compatible) property used in two traits

No Error

Accessing a static property non-statically

E_NOTICE

Only variables should be assigned by reference

E_NOTICE

Only variables should be passed by reference

E_NOTICE

Calling non-static methods statically E_DEPRECATED

Page 9: Migrating to PHP 7

Indirect Variables, Properties, Methods

• In PHP 5 complex indirect access to variables, properties, etc. was not consistently handled.• PHP 7 addresses these inconsistencies, at the cost of

backward compatibility

Typically most well-written code will not be affected by this. However, if you have complicated indirect accesses you may

hit this.

Page 10: Migrating to PHP 7

Indirect Variables, Properties, Methods

Expression PHP 5 PHP 7$$foo[‘bar’][‘baz’] ${$foo[‘bar’][‘baz’]} ($$foo)[‘bar’][‘baz’]$foo->$bar[‘baz’] $foo->{$bar[‘baz’]} ($foo->$bar)[‘baz’]$foo->$bar[‘baz’]() $foo->{$bar[‘baz’]}() ($foo->$bar)[‘baz’]()Foo::bar[‘baz’]() Foo::{$bar[‘baz’]}() (Foo::$bar)[‘baz’]()

If you are using any of the expression patterns on the left column the code will need to be updated to

the middle “PHP 5” column to be interpreted correctly.

Page 11: Migrating to PHP 7

list() Mayhem

• There is a lot of code out there that takes the assignment order of the list() statement for granted:

<?php

list($x[], $x[]) = [1, 2];

// $x = [2, 1] in PHP 5

// $x = [1, 2] in PHP 7

• This was never a good idea and you should not rely on the order in this fashion.

Page 12: Migrating to PHP 7

list() Mayhem

• Creative use of the list() statement with empty assignments will also now break

<?php

// Both will now break in PHP 7

list() = $array;

list(,$x) = $array;

Page 13: Migrating to PHP 7

list() Mayhem

• Finally, list() can no longer be used to unpack strings.

<?php

list($a, $b, $c) = “abc”;

// $a = “a” in PHP 5, breaks in PHP 7

Page 14: Migrating to PHP 7

Subtle foreach() changes – Array Pointers• In PHP 5 iterating over an array using foreach() would

cause the internal array pointer to move for each iteration<?php

$a = [1, 2]

foreach($a as &$val) { var_dump(current($a));

}

// Output in PHP 5:

// int(1)

// int(2)

// bool(false)

<?php

$a = [1, 2]

foreach($a as &$val) { var_dump(current($a));

}

// Output in PHP 7:

// int(1)

// int(1)

// int(1)

Page 15: Migrating to PHP 7

Subtle foreach() changes – References

This subtle change may break code that modifies arrays by reference during an iteration of it

<?php

$a = [0];

foreach($a as &$val) {

var_dump($val); $a[1] = 1;}

// Output in PHP 5

// int(0)

<?php

$a = [0];

foreach($a as &$val) {

var_dump($val); $a[1] = 1;}

// Output in PHP 7

// int(0)

// int(1)

In PHP 5 you couldn’t add to an array, even when passing it by reference and iterate over them in the same block

Page 16: Migrating to PHP 7

Integer handler changes

• Invalid Octal literals now throw parser errors instead of being silently ignored• Bitwise shifts of integers by negative numbers now throws

an \ArithmeticError• Bitwise shifts that are out of range will now always be int(0)

rather than being architecture-dependent

Page 17: Migrating to PHP 7

Division By Zero

• In PHP 5 Division by Zero would always cause an E_WARNING and evaluate to int(0), including attempting to do a modulus (%) by zero• In PHP 7

• X / 0 == float(INF)• 0 / 0 == float(NaN)

• Attempting to do a modulus of zero now causes a \DivisionByZeroError exception to be thrown

Page 18: Migrating to PHP 7

Hexadecimals and Strings

• In PHP 5 strings that evaluated to hexadecimal values could be cast to numeric values• I.e. (int)“0x123” == 291

• In PHP 7 strings are no longer directly interpretable as numeric values• I.e. (int)”0x123” == 0

• If you need to convert a string hexadecimal value to its integer equivalent you can use filter_var() with the FILTER_VALIDATE_INT and FILTER_FLAG_ALLOW_HEX options to convert it to an integer value.

Page 19: Migrating to PHP 7

Calls from Incompatible Contexts

• Static calls made to a non-static method with an incompatible context (i.e. calling a non-static method statically in a completely unrelated class) has thrown a E_DEPRECATED error since 5.6• I.e. Class A calls a non-static method in Class B statically

• In PHP 5, $this would still be defined pointing to class A• In PHP 7, $this is no longer defined

Page 20: Migrating to PHP 7

yield is now right associative

• In PHP 5 the yield construct no longer requires parentheses and has been changed to a right associative operator

<?php // PHP 5

echo yield -1; // (yield) – 1;

yield $foo or die // yield ($foo or die)

<?php // PHP 7

echo yield -1; // yield (-1)

yield $foo or die // (yield $foo) or die;

Page 21: Migrating to PHP 7

Misc Incompatibilities

• There are a number of other (smaller) incompatibilities between PHP 5 and PHP 7 worth mentioning • ASP-style tags <% %> have been removed• <script language=“php”> style tags have been removed• Assigning the result of the new statement by reference is now fatal error• Functions that have multiple parameters with the same name is now a

compile error• switch statements with multiple default blocks is now a compile error• $HTTP_RAW_POST_DATA has been removed in favor of php://input• # comments in .ini files parsed by PHP are no longer supported (use

semicolon)• Custom session handlers that return false result in fatal errors now

Page 22: Migrating to PHP 7

Removed Functions

• Numerous functions have been removed in PHP 7 and replaced with better equivalents where appropriateVariable Functions

call_user_method()call_user_method_array()

Mcrypt

mcrypt_generic_end()mcrypt_ecb()mcrypt_cbc()mcrypt_cfb()mcrypt_ofb()

Intl

datefmt_set_timezone_id()IntlDateFormatter::setTimeZoneId()

System

set_magic_quotes_runtime()magic_quotes_runtime()set_socket_blocking()dl() (in PHP-FPM)

=

GD

imagepsbbox()imagepsencodefont()imagepsextendfont()imagepsfreefont()imagepsloadfont()imagepsslantfont()imagepstext()

• Removed Extensions: ereg, mssql, mysql, sybase_ct

Page 23: Migrating to PHP 7

Removed Server APIs (SAPIs) and extensions• Numerous Server APIs (SAPIs) have been removed from

PHP 7:• aolserver• apache• apache_hooks• apache2filter• caudium• continunity• isapi

• milter• nsapi• phttpd• pi3web• roxen• thttpd• tux• webjames

Page 24: Migrating to PHP 7

Deprecated Features

• A number of things have been deprecated in PHP 7, which means they will now throw E_DEPRECATED errors if you happen to be using them in your code• PHP 4 style constructors• Static calls to non-static methods• Passing your own salt to the password_hash() function• capture_session_meta SSL context option

• For now these errors can be suppressed (using the @ operator) but the code should be updated as necessary.

Page 25: Migrating to PHP 7

Changes to Core Functions

• When migrating from PHP 5 to PHP 7 there are a few functions that have changed behaviors worth noting• mktime() and gmmktime() no longer accept the $is_dst parameter• preg_replace() no longer supports the /e modifier and preg_replace_callback() must now be used

• setlocale() no longer accepts strings for the $category parameter. The LC_* constants must be used

• substr() now returns an empty string if then $string parameter is as long as the $start parameter value.

Page 26: Migrating to PHP 7

Name Conflicts

• There are a lot of new things in PHP 7 that didn’t exist in PHP 5• New Functions • New Methods• New Classes• New Constants• New Exceptions

• You should review the PHP Migration documentation for what’s been added to determine if any code you’ve written now conflicts with something internal to PHP 7• For example, do you have an IntlChar class in your application?

Page 27: Migrating to PHP 7

Thank you!John [email protected], @coolge