PHP 7.1 introduces several backward incompatible changes and new features. Backward incompatible changes include removing extensions like ereg and functions like call_user_method(). New features include functions like intdiv() and random_bytes(). Static analysis tools can help find issues during migration by checking for syntax, linting errors, and semantically analyzing code without execution. Exceptions are also upgraded from notices/warnings to fatal errors in several cases. Developers should test their code using different PHP versions to locate and fix migration issues.
7. Living on the edge
http://php.net/manual/en/migration70.php
Online
UPGRADING TO PHP 7
Free Book, PDF
Davey Shafik is RM for PHP 7.1
Lots of blogs and articles
8. Living on the bleeding edge
https://github.com/php/php-src/blob/master/
UPGRADING
https://github.com/php/php-src/blob/master/
NEWS
https://wiki.php.net/rfc
http://bugs.php.net/
9.
10.
11.
12.
13.
14. PHP has 3 phases
syntax
definitions
execution
Where does code break?
Checked with phplint
Checked with tests
Checked code review
24. Switch statements may only
contain one default clause
<?php
switch($x) {
case '1' :
break;
default :
break;
default :
break;
case '2' :
break;
}
25. Switch statements may only
contain one default clause
switch($x) {
case 1 :
break;
case 0+1 :
break;
case '1' :
break;
case true :
break;
case 1.0 :
break;
case $y :
break;
}
26. Deprecated features
Not happening if a parent case has a __constructor()
Not happening if the class is in a namespace
Use the E_DEPRECATED error level while in DEV
Methods with the same name as their class
will not be constructors in a future
version of PHP; foo has a deprecated
constructor
27. php -l with other versions
syntax error, unexpected 'new' (T_NEW)
Assigning the return value of new by reference is
deprecated (PHP 5.6)
PHP 7 -> PHP 5.6
$o =& new Stdclass();
34. Grep on PHP code
1318 reports
doc/_ext/configext.py: parts = text.split("']['")
js/codemirror/lib/codemirror.js: var change = {from: pos, to: pos, text: splitLines(t
po/zh_CN.po:"example: address can be split into street, city, country and
libraries/Advisor.php: public static function splitJustification($rule)
libraries/plugins/ImportCsv.php: $tmp = preg_split('/,( ?)/', $csv_columns);
libraries/Config.php: // split file to lines
39. PHP7cc
PHP 7 Compatibility Checker
Authored by sstalle
https://github.com/sstalle/php7cc
PHP 5, works with "nikic/php-parser": "~1.4"
Display to stdout
40. 8.506s 3 results 27 analysis
php ~/.composer/vendor/bin/php7cc library/
File: /Users/famille/Desktop/analyze/library/Analyzer/Analyzer.php
> Line 231: Function argument(s) returned by "func_get_args" might have been modified
func_get_args();
File: /Users/famille/Desktop/analyze/library/Analyzer/Functions/MarkCallable.php
> Line 32: Nested by-reference foreach loop, make sure there is no iteration over the same array
foreach ($lists as $id => &$function) {
}
File: /Users/famille/Desktop/analyze/library/Tasks/Analyze.php
> Line 118: Possible adding to array on the last iteration of a by-reference foreach loop
$dependencies[$v] = $dep;
Checked 873 files in 8.506 seconds
41. PHAN
Static analysis for PHP
Inited by Rasmus, under work at Etsy
https://github.com/etsy/phan
PHP 7 only, with ext/ast
php ~/.composer/vendor/bin/phan -f phan.in -3
vendor -o phan.out
42.
43. 11.244s 333 results
PhanUndeclaredProperty Reference to undeclared property processed
PhanUndeclaredProperty Reference to undeclared property stdclass->results
PhanNonClassMethodCall Call to method relateTo on non-class type null
PhanStaticCallToNonStatic Static call to non-static method loadercypher::saveTokenCounts() defined at library//L
PhanAccessPropertyProtected Cannot access protected property tokenizertoken::$alternativeEnding
PhanTypeMismatchArgument Argument 1 (atom) is string but analyzerstructuresuseconstant::atomfunctionis() t
PhanUndeclaredClassMethod Call to method __construct from undeclared class reportsxmlwriter
PhanUndeclaredVariable Variable $r is undeclared
84 analysis
44. Exakat
Static analysis engine for PHP
https://github.com/exakat/exakat
PHP 5.2 to 7.2; Uses Neo4j 2.3 and Gremlin 3
php exakat.phar project -p name
46. PHP inspections
Static analysis engine for within the IDE
Vladimir Reznichenko
https://bitbucket.org/kalessil/phpinspectionsea
Written in Java
Runs from within PHPstorm
60. Where to look for ?
default_charset
Search for ini_set, ini_get, ini_get_all, ini_restore,
get_cfg_var
Search in php.ini, .htaccess
Search for htmlentities(), html_entity_decode() and
htmlspecialchars()
64. Can't call dynamically!
• $func()
• call_user_func()
• array_map()
• or similar
extract()
compact()
get_defined_vars()
func_get_args()
func_get_arg()
func_num_args()
parse_str() with one argument
mb_parse_str() with one argument
assert() with a string argument
70. Invalid octals are invalid
Upgraded from silent to Fatal error
PHP Parse error: Invalid numeric literal in test.php
<?php
$x = 0890;
71. More invalid octals in strings
<?php
var_dump("000" === "400");
PHP 7.1
https://wiki.php.net/rfc/octal.overload-checking
72. Invalid numeric are signaled
PHP 7.1
Notice: A non well formed numeric value encountered in
<?php
echo "1 monkey" + "2 bananas";
73. More reserved keywords
bool, int, float, string, null, true, false
are no more available for class / interface / traits
names
mixed, numeric, object, resource
are reserved for future use
void
is reserved in 7.1
74. More relaxed keywords
Almost all PHP keywords are now authorized inside
classes
Methods and constants
Except for class, which can't be a class constant
name.<?php
class foo {
const instanceof = 1;
function use() {
$this->while(4) + foo::instanceof;
}
}
75. Upgraded to Fatal error
Strings may be invalid
<?php
echo "u{1F418}n";
> php56 test.php
u{1F418}
> php70 test.php
🐘
<?php
echo "u{65B0}u{52A0}u{5761}n";
//
76. Strings may be invalid
Upgraded to Fatal error
<?php
echo "u{Yes}n";
PHP Parse error:
Invalid UTF-8 codepoint escape sequence
in test.php on line 3
u{
80. Exceptions
Exception is not the top exception type anymore
It is now the 'throwable' interface
Impact on Exception handler
Avoid type hinting until moved to PHP 7
Impact on Error handler
Impact on catch() clauses
81. More catching exceptions
Parser errors now throw a ParseError object.
Error handling for eval()
<?php
try {
eval($somePHPcode);
} catch( ParseError $e) {
log($e->getMessage());
// attempt to fix this or error handling
}
90. Call-time pass-by-reference
References are in the
function signature
Deprecated warnings until
PHP 7
Upgraded to Parse error in
PHP 7
<?php
$a = 3;
function f($b) {
$b++;
}
f(&$a);
print $a;
?>
PHP Parse error: syntax error, unexpected '&' in …
92. Easy to spot
Strict Standards: Non-static method A::f()
should not be called statically in test.php on
line 6
Deprecated: Non-static method A::f() should
not be called statically in test.php on line 6
97. Automatically fixed
It is not safe to rely on the system's timezone
settings. You are required to use the
date.timezone setting or the
date_default_timezone_set() function. In case
you used any of those methods and you are
still getting this warning, you most likely
misspelled the timezone identifier.
102. Don't hide in parentheses
<?php
function getArray() {
return [1, 2, 3];
}
function squareArray(array &$a) {
foreach ($a as &$v) {
$v **= 2;
}
}
// Generates a warning in PHP 7.
squareArray((getArray()));
?>
Parenthesis in
arguments won't
mask error anymore
103. Constant arrays
Lots of properties should be constants
<?php
class Version {
const SUPPORTED = ['1.0', '1.1', '2.0', '2.1'];
private $an_array = [1,2,3,4];
public function isSupported($x) {
return isset(Version::SUPPORTED[$x]);
}
}
111. Parameters evolution (7.1)
get_headers() has an extra parameter
Passing a custom stream context
getenv() doesn't need parameter
all the current environment variables will be returned
113. Null-coalesce
Shorter way to give a test for NULL and failover
<?php
// PHP 5.6
$x = $_GET['x'] === null ? 'default' : $_GET['x'];
// PHP 7.0
$x = $_GET['x'] ?? 'default';
?>
114. Spaceship operator
Very Cute <=>
Replaces a lot of code
Mainly useful for usort()
<?php
// PHP 5.6
if ($a > $b) {
echo 1;
} elseif ($a < $b) {
echo -1;
} else {
echo 0;
}
// PHP 7.0
echo $a <=> $b; // 0
117. Scalar typehint
Whenever type is tested =>
<?php
function foo($x) {
if (!is_string($x)) {
throw new Exception('Type error while calling ' .
__FUNCTION__);
} ...
}
<?php
function foo(string $x) {
...
}
118. Scalar typehint back in 5.6
<?php
function foo(string $x) { }
foo('that');
Catchable fatal error: Argument 1 passed to
foo() must be an instance of string,
string given, called in file..
122. Minimum args in custom
functions is Fatal error
<?php
function foo(?int $a, float $b, float $c) {
return $a + $b + $c;
}
echo foo(2, 1);
Minimum args number Fatal error: Uncaught Error:
Too few arguments to function foo(), 2 passed in