preparing for the next php version
TRANSCRIPT
![Page 1: Preparing for the next php version](https://reader037.vdocuments.mx/reader037/viewer/2022103010/588a1bdd1a28abb21f8b46d1/html5/thumbnails/1.jpg)
MIGRATING TO NEW PHP VERSIONS
Washington DC, USA
![Page 2: Preparing for the next php version](https://reader037.vdocuments.mx/reader037/viewer/2022103010/588a1bdd1a28abb21f8b46d1/html5/thumbnails/2.jpg)
TOWARDS PHP 70
Changing version is always a big challenge
Backward incompatibilities
New features
How to spot them ?
![Page 3: Preparing for the next php version](https://reader037.vdocuments.mx/reader037/viewer/2022103010/588a1bdd1a28abb21f8b46d1/html5/thumbnails/3.jpg)
SPEAKER
Damien Seguy
CTO at exakat
Static code analysis for PHP
![Page 4: Preparing for the next php version](https://reader037.vdocuments.mx/reader037/viewer/2022103010/588a1bdd1a28abb21f8b46d1/html5/thumbnails/4.jpg)
PHP LINTING
command line : php -l filename.php
Will only parse the code,
not execution
Will spot compilation problems
![Page 5: Preparing for the next php version](https://reader037.vdocuments.mx/reader037/viewer/2022103010/588a1bdd1a28abb21f8b46d1/html5/thumbnails/5.jpg)
![Page 6: Preparing for the next php version](https://reader037.vdocuments.mx/reader037/viewer/2022103010/588a1bdd1a28abb21f8b46d1/html5/thumbnails/6.jpg)
![Page 7: Preparing for the next php version](https://reader037.vdocuments.mx/reader037/viewer/2022103010/588a1bdd1a28abb21f8b46d1/html5/thumbnails/7.jpg)
![Page 8: Preparing for the next php version](https://reader037.vdocuments.mx/reader037/viewer/2022103010/588a1bdd1a28abb21f8b46d1/html5/thumbnails/8.jpg)
PHP -L WILL FIND
Short array syntax
Function subscripting
Code that won’t compile anyway
![Page 9: Preparing for the next php version](https://reader037.vdocuments.mx/reader037/viewer/2022103010/588a1bdd1a28abb21f8b46d1/html5/thumbnails/9.jpg)
PHP 7 LINTING
Methods with the same name as their class will not be constructors in a future version of PHP
Cannot use a\b\c\Int as Int because 'Int' is a special class name
Switch statements may only contain one default clause
Redefinition of parameter $%s
syntax error, unexpected 'new' (T_NEW)
![Page 10: Preparing for the next php version](https://reader037.vdocuments.mx/reader037/viewer/2022103010/588a1bdd1a28abb21f8b46d1/html5/thumbnails/10.jpg)
WHERE ELSE CODE WILL BREAK?
PHP running has 3 stages
parsed
compiled
executed
Checked with lint
Checked with data and UT
Checked code review
![Page 11: Preparing for the next php version](https://reader037.vdocuments.mx/reader037/viewer/2022103010/588a1bdd1a28abb21f8b46d1/html5/thumbnails/11.jpg)
GETTING READY
http://php.net/manual/en/migration70.php
UPGRADING TO PHP 7, Davey Shafik
https://github.com/php/php-src/blob/master/UPGRADING
https://github.com/php/php-src/blob/master/NEWS
get_headers() has an extra parameter in 7.1
![Page 12: Preparing for the next php version](https://reader037.vdocuments.mx/reader037/viewer/2022103010/588a1bdd1a28abb21f8b46d1/html5/thumbnails/12.jpg)
WHAT WILL CHANGE?
Incompatible changes
Deprecated changes
Changed features
New features
![Page 13: Preparing for the next php version](https://reader037.vdocuments.mx/reader037/viewer/2022103010/588a1bdd1a28abb21f8b46d1/html5/thumbnails/13.jpg)
INCOMPATIBILITIES
Features that were dropped
Features that were added
![Page 14: Preparing for the next php version](https://reader037.vdocuments.mx/reader037/viewer/2022103010/588a1bdd1a28abb21f8b46d1/html5/thumbnails/14.jpg)
ADDED STRUCTURES
Functions Classes Constants
5.3 40 2 80
5.4 0 9 78
5.5 12 11 57
5.6 1 10 10
7.0 10 10 41
Total 1293 153 1149
![Page 15: Preparing for the next php version](https://reader037.vdocuments.mx/reader037/viewer/2022103010/588a1bdd1a28abb21f8b46d1/html5/thumbnails/15.jpg)
NAME IMPACT
get_resources(), intdiv()
PREG_JIT_STACKLIMIT_ERROR
Error, Date
![Page 16: Preparing for the next php version](https://reader037.vdocuments.mx/reader037/viewer/2022103010/588a1bdd1a28abb21f8b46d1/html5/thumbnails/16.jpg)
REMOVED FEATURES
$HTTP_RAW_POST_DATA
Replace it by php://input
php://input is now reusable
![Page 17: Preparing for the next php version](https://reader037.vdocuments.mx/reader037/viewer/2022103010/588a1bdd1a28abb21f8b46d1/html5/thumbnails/17.jpg)
REMOVED FEATURES
ext/mysql
Look for mysql_* functions
Probably in Db/Adapter
ext/ereg
ereg, ereg_replace, split, sql_regcase
![Page 18: Preparing for the next php version](https://reader037.vdocuments.mx/reader037/viewer/2022103010/588a1bdd1a28abb21f8b46d1/html5/thumbnails/18.jpg)
USORT<?php
$array = array( 'foo', 'bar', 'php' );
usort($array, function($a, $b) { return 0; } );
print_r($array);
Array ( [0] => php [1] => bar [2] => foo )
Array ( [0] => foo [1] => bar [2] => php )
PHP 5
PHP 7
![Page 19: Preparing for the next php version](https://reader037.vdocuments.mx/reader037/viewer/2022103010/588a1bdd1a28abb21f8b46d1/html5/thumbnails/19.jpg)
WHERE TO LOOK FOR ?
Find the name of the structure (function name…)
Grep, or IDE’s search function will help you
$HTTP_RAW_POST_DATA
Look for mysql_*
Look ereg, split, usort
![Page 20: Preparing for the next php version](https://reader037.vdocuments.mx/reader037/viewer/2022103010/588a1bdd1a28abb21f8b46d1/html5/thumbnails/20.jpg)
PREG_REPLACE AND /E
preg_replace(‘/ /e’, ‘evaled code’, $haystack)
replaced preg_replace_callback(‘/ /‘, closure, $haystack)
preg_replace_callback_array()
![Page 21: Preparing for the next php version](https://reader037.vdocuments.mx/reader037/viewer/2022103010/588a1bdd1a28abb21f8b46d1/html5/thumbnails/21.jpg)
PREG_REPLACE_CALLBACK_ARRAY<?php
$code = "abbbb";
$spec = 'c';
echo preg_replace_callback_array( array( "/a/" => function($matches) { return strtoupper($matches[0]); }, "/b/" => function($matches) use ($spec) { static $i = 0; $i++;
return "B$i$spec"; } ), $code);
AB1cB2cB3cB4c
![Page 22: Preparing for the next php version](https://reader037.vdocuments.mx/reader037/viewer/2022103010/588a1bdd1a28abb21f8b46d1/html5/thumbnails/22.jpg)
DEFAULT_CHARSET
iconv.input_encoding
iconv.output_encoding
iconv.internal_encoding
mbstring.http_input
mbstring.http_output
mbstring.internal_encoding
default_charset
![Page 23: Preparing for the next php version](https://reader037.vdocuments.mx/reader037/viewer/2022103010/588a1bdd1a28abb21f8b46d1/html5/thumbnails/23.jpg)
DEFAULT_CHARSET
htmlentities()
PHP 5.3 : ISO-8859-1
PHP 5.4 : UTF-8
PHP 5.6 : default_charset (also UTF 8)
![Page 24: Preparing for the next php version](https://reader037.vdocuments.mx/reader037/viewer/2022103010/588a1bdd1a28abb21f8b46d1/html5/thumbnails/24.jpg)
WHERE TO LOOK FOR ?
preg_replace
Search for preg_replace function calls
Refine with /e, multiples calls
default_charset
Search for ini_set, ini_get, ini_get_all, ini_restore, get_cfg_var
Seach in php.ini, .htaccess
Search for htmlentities(), html_entity_decode() and htmlspecialchars()
![Page 25: Preparing for the next php version](https://reader037.vdocuments.mx/reader037/viewer/2022103010/588a1bdd1a28abb21f8b46d1/html5/thumbnails/25.jpg)
DEPRECATED FEATURES
Methods with the same name as their class will not be constructors in a future version of PHP; foo has a deprecated constructor
Not happening if a parent case has a __constructor()
Not happening if the class is in a namespace
![Page 26: Preparing for the next php version](https://reader037.vdocuments.mx/reader037/viewer/2022103010/588a1bdd1a28abb21f8b46d1/html5/thumbnails/26.jpg)
Deprecated: Methods with the same name as their class will not be constructors in a future version of PHP;
foo has a deprecated constructor
PHP 4 CONSTRUCTORS
Use the E_DEPRECATED error level while in DEV Check the logs
![Page 27: Preparing for the next php version](https://reader037.vdocuments.mx/reader037/viewer/2022103010/588a1bdd1a28abb21f8b46d1/html5/thumbnails/27.jpg)
CALL-TIME PASS-BY-REFERENCE
References are in the function signature
Deprecated warnings until PHP 7
A nice Parse error in PHP 7
<?php
$a = 3;
function f($b) { $b++; }
f(&$a); print $a; ?>
PHP Parse error: syntax error, unexpected '&' in
![Page 28: Preparing for the next php version](https://reader037.vdocuments.mx/reader037/viewer/2022103010/588a1bdd1a28abb21f8b46d1/html5/thumbnails/28.jpg)
WHERE TO LOOK FOR ?
Use error level
Set error_level to maximum
Spot errors in the log
Refine
Great to reduce log size
![Page 29: Preparing for the next php version](https://reader037.vdocuments.mx/reader037/viewer/2022103010/588a1bdd1a28abb21f8b46d1/html5/thumbnails/29.jpg)
INCOMPATIBLE CONTEXT
<?php class A { function f() { echo get_class($this); } } A::f(); ?>
Notice: Undefined variable: this in A
Deprecated: Non-static method A::f() should not be called statically in Notice: Undefined variable: this in A
![Page 30: Preparing for the next php version](https://reader037.vdocuments.mx/reader037/viewer/2022103010/588a1bdd1a28abb21f8b46d1/html5/thumbnails/30.jpg)
EASY TO SPOT
Use the E_DEPRECATED or strict while in DEV
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
![Page 31: Preparing for the next php version](https://reader037.vdocuments.mx/reader037/viewer/2022103010/588a1bdd1a28abb21f8b46d1/html5/thumbnails/31.jpg)
CHANGED BEHAVIOR
Indirect expressions
![Page 32: Preparing for the next php version](https://reader037.vdocuments.mx/reader037/viewer/2022103010/588a1bdd1a28abb21f8b46d1/html5/thumbnails/32.jpg)
SEARCH FOR SITUATIONS
Search for :: operator
Get the class
then the method
then the static keyword
Needs a automated auditing tool
Exakat, Code sniffer, IDE
![Page 33: Preparing for the next php version](https://reader037.vdocuments.mx/reader037/viewer/2022103010/588a1bdd1a28abb21f8b46d1/html5/thumbnails/33.jpg)
STATIC ANALYZIS
PHP 5, PHP 7 Psr-4 ClearPHP Performance
![Page 34: Preparing for the next php version](https://reader037.vdocuments.mx/reader037/viewer/2022103010/588a1bdd1a28abb21f8b46d1/html5/thumbnails/34.jpg)
SUMMARY
PHP lint is your friend
Search in the code
With Grep
Directly, or indirectly
With the logs
Use static analysis tools
![Page 35: Preparing for the next php version](https://reader037.vdocuments.mx/reader037/viewer/2022103010/588a1bdd1a28abb21f8b46d1/html5/thumbnails/35.jpg)
NEW FEATURES
They require willpower
Breaks backward compatibility
FUD
Search for places to apply them like for incompatibilities
![Page 36: Preparing for the next php version](https://reader037.vdocuments.mx/reader037/viewer/2022103010/588a1bdd1a28abb21f8b46d1/html5/thumbnails/36.jpg)
NEW FEATURES
Fixing
Modernization
New feature
![Page 37: Preparing for the next php version](https://reader037.vdocuments.mx/reader037/viewer/2022103010/588a1bdd1a28abb21f8b46d1/html5/thumbnails/37.jpg)
FIXING
![Page 38: Preparing for the next php version](https://reader037.vdocuments.mx/reader037/viewer/2022103010/588a1bdd1a28abb21f8b46d1/html5/thumbnails/38.jpg)
EMPTY() UPGRADE
No need anymore to expressions in a variable for empty()!
Fatal error: Can't use function return value in write context in test.php on line 6
5.5
<?php function myFunction() { return -2 ; }
if (empty(myFunction() + 2)) { echo "This means 0!\n"; } ?>
![Page 39: Preparing for the next php version](https://reader037.vdocuments.mx/reader037/viewer/2022103010/588a1bdd1a28abb21f8b46d1/html5/thumbnails/39.jpg)
MODERNIZATION
![Page 40: Preparing for the next php version](https://reader037.vdocuments.mx/reader037/viewer/2022103010/588a1bdd1a28abb21f8b46d1/html5/thumbnails/40.jpg)
SPACESHIP OPERATOR
Replaces a lot of code
Mainly useful for usort and co
Very Cute
<?php
// PHP 5.6 if ($a > $b) { echo 1; } elseif ($a < $b) { echo -1; } else { echo 0; }
// PHP 7.0 echo $a <=> $b; // 0
![Page 41: Preparing for the next php version](https://reader037.vdocuments.mx/reader037/viewer/2022103010/588a1bdd1a28abb21f8b46d1/html5/thumbnails/41.jpg)
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';
?>
![Page 42: Preparing for the next php version](https://reader037.vdocuments.mx/reader037/viewer/2022103010/588a1bdd1a28abb21f8b46d1/html5/thumbnails/42.jpg)
DIRNAME() SECOND ARG
<?php $path = '/a/b/c/d/e/f';
// PHP 5.6 $root = dirname(dirname(dirname($x)));
// PHP 7 $root = dirname($path, 3); ?>
![Page 43: Preparing for the next php version](https://reader037.vdocuments.mx/reader037/viewer/2022103010/588a1bdd1a28abb21f8b46d1/html5/thumbnails/43.jpg)
… VARIADIC
replaces func_get_args()
Easier to read
<?php
// PHP 5.5 function array_power($pow) { $integers = func_get_args(); array_unshift($integers);
foreach($integers as $i) { print "$i ^ $pow = ". pow($i, $pow)."\n"; } } // PHP 7.0 function array_power($pow, ...$integers) { foreach($integers as $i) { print "$i ^ $pow = ". ($i ** $pow)."\n"; } }
5.6
![Page 44: Preparing for the next php version](https://reader037.vdocuments.mx/reader037/viewer/2022103010/588a1bdd1a28abb21f8b46d1/html5/thumbnails/44.jpg)
VARIADIC …
<?php
// Avoid! foreach($source as $x) { if (is_array($x)) $final = array_merge($final, $x); } }
![Page 45: Preparing for the next php version](https://reader037.vdocuments.mx/reader037/viewer/2022103010/588a1bdd1a28abb21f8b46d1/html5/thumbnails/45.jpg)
VARIADIC …<?php
$collection = []; foreach($source as $x) { if (is_array($x)) $collection[] = $x; } }
// PHP 5.5 $final = call_user_func_array('array_merge', $collection); // PHP 7.0 $final = array_merge(...$collection);
![Page 46: Preparing for the next php version](https://reader037.vdocuments.mx/reader037/viewer/2022103010/588a1bdd1a28abb21f8b46d1/html5/thumbnails/46.jpg)
REALLY NEW
![Page 47: Preparing for the next php version](https://reader037.vdocuments.mx/reader037/viewer/2022103010/588a1bdd1a28abb21f8b46d1/html5/thumbnails/47.jpg)
SCALAR TYPE TYPEHINT
Whenever type is tested
<?php
function foo(string $x) { if (!is_string($x)) { throw new Exception('Type error while calling '.__FUNCTION__); } }
![Page 48: Preparing for the next php version](https://reader037.vdocuments.mx/reader037/viewer/2022103010/588a1bdd1a28abb21f8b46d1/html5/thumbnails/48.jpg)
GENERATORS<?php function factors($limit) { yield 2; yield 3;
yield from prime_database();
for ($i = 1001; $i <= $limit; $i += 2) { yield $i; } }
$prime = 1357; foreach (factors(sqrt($prime)) as $n) { echo "$n ". ($prime % $n ? ' not ' : '') . " factor\n"; }
![Page 49: Preparing for the next php version](https://reader037.vdocuments.mx/reader037/viewer/2022103010/588a1bdd1a28abb21f8b46d1/html5/thumbnails/49.jpg)
GENERATORS
New yield keyword
Save memory from
n down to 1 value
Good for long or infinite loops
Search for range(), for() or loops
literals, database result sets, file lines
![Page 50: Preparing for the next php version](https://reader037.vdocuments.mx/reader037/viewer/2022103010/588a1bdd1a28abb21f8b46d1/html5/thumbnails/50.jpg)
<?php class Version { const MAJOR = 2; const MIDDLE = ONE; const MINOR = 1; const FULL = Version::MAJOR.'.'.Version::MIDDLE.'.'.Version::MINOR. '-'.PHP_VERSION; const SHORT = Version::MAJOR.'.'.Version::MIDDLE; const COMPACT = Version::MAJOR.Version::MIDDLE.Version::MINOR; const AN_ARRAY = [1,2,3,4];
public function f($a = (MAJOR == 2) ? 3 : Version::MINOR ** 3) { return $a; } }
CONSTANT SCALAR EXPRESSIONS
Code automation
Keep it simple
Won’t accept functioncalls
Won't accept variables
![Page 51: Preparing for the next php version](https://reader037.vdocuments.mx/reader037/viewer/2022103010/588a1bdd1a28abb21f8b46d1/html5/thumbnails/51.jpg)
CONSTANT SCALAR EXPRESSIONS
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]); } }
![Page 52: Preparing for the next php version](https://reader037.vdocuments.mx/reader037/viewer/2022103010/588a1bdd1a28abb21f8b46d1/html5/thumbnails/52.jpg)
SUMMARY
Check the manuals
PHP lint is your friend
Search in the code
Use static analysis tools