Last train to php 7
-
Upload
damien-seguy- -
Category
Technology
-
view
211 -
download
0
Transcript of Last train to php 7
![Page 1: Last train to php 7](https://reader030.fdocuments.net/reader030/viewer/2022012908/58ed07db1a28abfd388b45f3/html5/thumbnails/1.jpg)
Last Train to PHP 7.1Damien Seguy @exakat
London, United Kingdom, February 2017
![Page 2: Last train to php 7](https://reader030.fdocuments.net/reader030/viewer/2022012908/58ed07db1a28abfd388b45f3/html5/thumbnails/2.jpg)
Full ahead to PHP 7. 2
Changing version is always a big challenge
Backward incompatibilities
New features
Learn, spot, fix, repeat
01
![Page 3: Last train to php 7](https://reader030.fdocuments.net/reader030/viewer/2022012908/58ed07db1a28abfd388b45f3/html5/thumbnails/3.jpg)
Speaker
Damien Seguy
CTO at exakat
Static code analysis for PHP
Retiring house for oldest elephpant
![Page 4: Last train to php 7](https://reader030.fdocuments.net/reader030/viewer/2022012908/58ed07db1a28abfd388b45f3/html5/thumbnails/4.jpg)
Synopsis
What is in the next version ?
Where in my code ?
How to replace this ?
Get documentation
Find issue
Fix code
![Page 5: Last train to php 7](https://reader030.fdocuments.net/reader030/viewer/2022012908/58ed07db1a28abfd388b45f3/html5/thumbnails/5.jpg)
Migration to PHP 7.2
Migration to PHP 7.0, 7.1 and 7.2 / 8.0
From PHP 5.6
No framework, no libraries
Tools, experience, discipline
![Page 6: Last train to php 7](https://reader030.fdocuments.net/reader030/viewer/2022012908/58ed07db1a28abfd388b45f3/html5/thumbnails/6.jpg)
Destination
![Page 7: Last train to php 7](https://reader030.fdocuments.net/reader030/viewer/2022012908/58ed07db1a28abfd388b45f3/html5/thumbnails/7.jpg)
Living on the edge
http://php.net/manual/en/migration71.php
Online
UPGRADING TO PHP 7.0
Free Book, PDF
Davey Shafik is RM for PHP 7.1
Lots of blogs and articles
![Page 8: Last train to php 7](https://reader030.fdocuments.net/reader030/viewer/2022012908/58ed07db1a28abfd388b45f3/html5/thumbnails/8.jpg)
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/
![Page 9: Last train to php 7](https://reader030.fdocuments.net/reader030/viewer/2022012908/58ed07db1a28abfd388b45f3/html5/thumbnails/9.jpg)
![Page 10: Last train to php 7](https://reader030.fdocuments.net/reader030/viewer/2022012908/58ed07db1a28abfd388b45f3/html5/thumbnails/10.jpg)
![Page 11: Last train to php 7](https://reader030.fdocuments.net/reader030/viewer/2022012908/58ed07db1a28abfd388b45f3/html5/thumbnails/11.jpg)
![Page 12: Last train to php 7](https://reader030.fdocuments.net/reader030/viewer/2022012908/58ed07db1a28abfd388b45f3/html5/thumbnails/12.jpg)
62 opened discussions
3 opened votes
![Page 13: Last train to php 7](https://reader030.fdocuments.net/reader030/viewer/2022012908/58ed07db1a28abfd388b45f3/html5/thumbnails/13.jpg)
![Page 14: Last train to php 7](https://reader030.fdocuments.net/reader030/viewer/2022012908/58ed07db1a28abfd388b45f3/html5/thumbnails/14.jpg)
Which to believe
Books
PHP manual Migration, blogs
Wiki (Implemented)
NEWS
Bugs
Wiki (Future)
Yearly
Monthly
Weekly
As possible
As needed
![Page 15: Last train to php 7](https://reader030.fdocuments.net/reader030/viewer/2022012908/58ed07db1a28abfd388b45f3/html5/thumbnails/15.jpg)
Where does code break?
Checked with phplint
Checked with tests
Checked code review
PHP has 3 phases
syntax
definitions
execution
![Page 16: Last train to php 7](https://reader030.fdocuments.net/reader030/viewer/2022012908/58ed07db1a28abfd388b45f3/html5/thumbnails/16.jpg)
<?php
function splitNames($fullname, $fullname) { list($first, $last) = split($fullname, ' '); } echo splitNames('John Doe');?>
Where will code break?
SyntaxDefinitionsExecution
![Page 17: Last train to php 7](https://reader030.fdocuments.net/reader030/viewer/2022012908/58ed07db1a28abfd388b45f3/html5/thumbnails/17.jpg)
Tools for migration
• Your own experience with your code
• Lint
• Search
• Static analysis
• Logs
![Page 18: Last train to php 7](https://reader030.fdocuments.net/reader030/viewer/2022012908/58ed07db1a28abfd388b45f3/html5/thumbnails/18.jpg)
Linting PHP 7
![Page 19: Last train to php 7](https://reader030.fdocuments.net/reader030/viewer/2022012908/58ed07db1a28abfd388b45f3/html5/thumbnails/19.jpg)
PHP linting
• command line : php -l filename.php
• Spot parse errors
• Works on files only :
• For directories, see composer phplint/phplint
![Page 20: Last train to php 7](https://reader030.fdocuments.net/reader030/viewer/2022012908/58ed07db1a28abfd388b45f3/html5/thumbnails/20.jpg)
PHP linting
Error messagesin PHP
0
550
1100
1650
2200
5.0 5.1 5.2 5.3 5.4 5.5 5.6 7.0 7.1 7.2
Total Distinct
![Page 21: Last train to php 7](https://reader030.fdocuments.net/reader030/viewer/2022012908/58ed07db1a28abfd388b45f3/html5/thumbnails/21.jpg)
Backward unlintable code
0
1
2
3
4
5.2 5.3 5.4 5.5 5.6 7.0 7.1 7.2
![Page 22: Last train to php 7](https://reader030.fdocuments.net/reader030/viewer/2022012908/58ed07db1a28abfd388b45f3/html5/thumbnails/22.jpg)
Current versions code
0
1.25
2.5
3.75
5
5.2 5.3 5.4 5.5 5.6 7.0 7.1 7.2
![Page 23: Last train to php 7](https://reader030.fdocuments.net/reader030/viewer/2022012908/58ed07db1a28abfd388b45f3/html5/thumbnails/23.jpg)
Backward unlintable code
0
0.25
0.5
0.75
1
5.2 5.3 5.4 5.5 5.6 7.0 7.1 7.2
![Page 24: Last train to php 7](https://reader030.fdocuments.net/reader030/viewer/2022012908/58ed07db1a28abfd388b45f3/html5/thumbnails/24.jpg)
0
1.25
2.5
3.75
5
5.2 5.3 5.4 5.5 5.6 7.0 7.1 7.2
0
1
2
3
4
5.2 5.3 5.4 5.5 5.6 7.0 7.1 7.2
0
0.75
1.5
2.25
3
5.2 5.3 5.4 5.5 5.6 7.0 7.1 7.2
0
1.75
3.5
5.25
7
5.2 5.3 5.4 5.5 5.6 7.0 7.1 7.2
0
0.25
0.5
0.75
1
5.2 5.3 5.4 5.5 5.6 7.0 7.1 7.2
![Page 25: Last train to php 7](https://reader030.fdocuments.net/reader030/viewer/2022012908/58ed07db1a28abfd388b45f3/html5/thumbnails/25.jpg)
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();
![Page 26: Last train to php 7](https://reader030.fdocuments.net/reader030/viewer/2022012908/58ed07db1a28abfd388b45f3/html5/thumbnails/26.jpg)
Redefinition of parameter
<?php
function foo($a, $a, $a) { print $a."\n"; }
foo('x', 'y', 'z');
?>
![Page 27: Last train to php 7](https://reader030.fdocuments.net/reader030/viewer/2022012908/58ed07db1a28abfd388b45f3/html5/thumbnails/27.jpg)
Switch statements may only contain one default clause
<?php
switch($x) { case '1' : break; default : break; default : break; case '2' : break; }
![Page 28: Last train to php 7](https://reader030.fdocuments.net/reader030/viewer/2022012908/58ed07db1a28abfd388b45f3/html5/thumbnails/28.jpg)
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; }
![Page 29: Last train to php 7](https://reader030.fdocuments.net/reader030/viewer/2022012908/58ed07db1a28abfd388b45f3/html5/thumbnails/29.jpg)
Deprecated features
Not happening if a parent case has a __construct()
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
![Page 30: Last train to php 7](https://reader030.fdocuments.net/reader030/viewer/2022012908/58ed07db1a28abfd388b45f3/html5/thumbnails/30.jpg)
Migration to PHP 7.2
Lint with
PHP 7.1
PHP 7.2 (or src)
PHP 5.6 (current), PHP 7.0
PHP 5.5, 5.4,… (manual)
![Page 31: Last train to php 7](https://reader030.fdocuments.net/reader030/viewer/2022012908/58ed07db1a28abfd388b45f3/html5/thumbnails/31.jpg)
PHP 7 linting
Pre-commit
Use different versions
Be ruthless with unlintable files
![Page 32: Last train to php 7](https://reader030.fdocuments.net/reader030/viewer/2022012908/58ed07db1a28abfd388b45f3/html5/thumbnails/32.jpg)
Where does code break?
Checked with phplint
Checked with tests
Checked code review
PHP has 3 phases
syntax
definitions
execution
![Page 33: Last train to php 7](https://reader030.fdocuments.net/reader030/viewer/2022012908/58ed07db1a28abfd388b45f3/html5/thumbnails/33.jpg)
Static analysis
![Page 34: Last train to php 7](https://reader030.fdocuments.net/reader030/viewer/2022012908/58ed07db1a28abfd388b45f3/html5/thumbnails/34.jpg)
Definition
Review code without executing it
Audit code by reading it
Common in C/C++, Java, Javascript
Hot subject to PHP
![Page 35: Last train to php 7](https://reader030.fdocuments.net/reader030/viewer/2022012908/58ed07db1a28abfd388b45f3/html5/thumbnails/35.jpg)
GREP/SEARCH
Any searching facility
Pro : High speed, great for keyword search, universal
Cons : Little repeat value, no PHP semantics
![Page 36: Last train to php 7](https://reader030.fdocuments.net/reader030/viewer/2022012908/58ed07db1a28abfd388b45f3/html5/thumbnails/36.jpg)
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(text.join("\n")), origin: "paste"}; po/zh_CN.po:"example: address can be split into street, city, country and zip."
libraries/Advisor.php: public static function splitJustification($rule) libraries/plugins/ImportCsv.php: $tmp = preg_split('/,( ?)/', $csv_columns); libraries/Config.php: // split file to lines
![Page 37: Last train to php 7](https://reader030.fdocuments.net/reader030/viewer/2022012908/58ed07db1a28abfd388b45f3/html5/thumbnails/37.jpg)
Static analysis
PHP 5 / 7 Calisthenics ClearPHP
Performance
![Page 38: Last train to php 7](https://reader030.fdocuments.net/reader030/viewer/2022012908/58ed07db1a28abfd388b45f3/html5/thumbnails/38.jpg)
Static analysis tools
PHP7mar
PHP7cc
Phan
Exakat
PHP inspections
![Page 39: Last train to php 7](https://reader030.fdocuments.net/reader030/viewer/2022012908/58ed07db1a28abfd388b45f3/html5/thumbnails/39.jpg)
PHP7mar
PHP 7 Migration Assistant Report (MAR)
Alexia : https://github.com/Alexia/php7mar
Works with regex
Produces a .md file
![Page 40: Last train to php 7](https://reader030.fdocuments.net/reader030/viewer/2022012908/58ed07db1a28abfd388b45f3/html5/thumbnails/40.jpg)
12 results
![Page 41: Last train to php 7](https://reader030.fdocuments.net/reader030/viewer/2022012908/58ed07db1a28abfd388b45f3/html5/thumbnails/41.jpg)
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
![Page 42: Last train to php 7](https://reader030.fdocuments.net/reader030/viewer/2022012908/58ed07db1a28abfd388b45f3/html5/thumbnails/42.jpg)
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
![Page 43: Last train to php 7](https://reader030.fdocuments.net/reader030/viewer/2022012908/58ed07db1a28abfd388b45f3/html5/thumbnails/43.jpg)
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
![Page 44: Last train to php 7](https://reader030.fdocuments.net/reader030/viewer/2022012908/58ed07db1a28abfd388b45f3/html5/thumbnails/44.jpg)
![Page 45: Last train to php 7](https://reader030.fdocuments.net/reader030/viewer/2022012908/58ed07db1a28abfd388b45f3/html5/thumbnails/45.jpg)
11.244s 333 results
PhanUndeclaredProperty Reference to undeclared property processedPhanUndeclaredProperty Reference to undeclared property \stdclass->results
PhanNonClassMethodCall Call to method relateTo on non-class type null
PhanStaticCallToNonStatic Static call to non-static method \loader\cypher::saveTokenCounts() defined at library//Loader/Cypher.php:179PhanAccessPropertyProtected Cannot access protected property \tokenizer\token::$alternativeEnding
PhanTypeMismatchArgument Argument 1 (atom) is string but \analyzer\structures\useconstant::atomfunctionis() takes array defined at library//Analyzer/Analyzer.php:415
PhanUndeclaredClassMethod Call to method __construct from undeclared class \reports\xmlwriterPhanUndeclaredVariable Variable $r is undeclared
84 analysis
![Page 46: Last train to php 7](https://reader030.fdocuments.net/reader030/viewer/2022012908/58ed07db1a28abfd388b45f3/html5/thumbnails/46.jpg)
Exakat
Static analysis engine for PHP
https://github.com/exakat/exakat
PHP 5.2 to 7.2;
php exakat.phar project -p name
![Page 47: Last train to php 7](https://reader030.fdocuments.net/reader030/viewer/2022012908/58ed07db1a28abfd388b45f3/html5/thumbnails/47.jpg)
20 mins6798 results290 analysis
![Page 48: Last train to php 7](https://reader030.fdocuments.net/reader030/viewer/2022012908/58ed07db1a28abfd388b45f3/html5/thumbnails/48.jpg)
Exakat
![Page 49: Last train to php 7](https://reader030.fdocuments.net/reader030/viewer/2022012908/58ed07db1a28abfd388b45f3/html5/thumbnails/49.jpg)
PHP inspections
Static analysis engine for within the IDE
Vladimir Reznichenko
https://bitbucket.org/kalessil/phpinspectionsea
Written in Java
Runs from within PHPstorm
![Page 50: Last train to php 7](https://reader030.fdocuments.net/reader030/viewer/2022012908/58ed07db1a28abfd388b45f3/html5/thumbnails/50.jpg)
![Page 51: Last train to php 7](https://reader030.fdocuments.net/reader030/viewer/2022012908/58ed07db1a28abfd388b45f3/html5/thumbnails/51.jpg)
Write your own?
https://github.com/exakat/php-static-analysis-tools.git
PHP 7 : use ext/ast
PHP 5 :"nikic/php-parser"
Better Reflexion
Avoid regex (but it does work)
![Page 52: Last train to php 7](https://reader030.fdocuments.net/reader030/viewer/2022012908/58ed07db1a28abfd388b45f3/html5/thumbnails/52.jpg)
PHP 7.2 : what changes?
Incompatible changes
New features
Features/Incompatibilities from PHP 5.6 => 7.2
![Page 53: Last train to php 7](https://reader030.fdocuments.net/reader030/viewer/2022012908/58ed07db1a28abfd388b45f3/html5/thumbnails/53.jpg)
How to spot issues?
Code knowledge
lint
Grep / Search
Static analysis
Logs / error_reporting
Unit Tests
![Page 54: Last train to php 7](https://reader030.fdocuments.net/reader030/viewer/2022012908/58ed07db1a28abfd388b45f3/html5/thumbnails/54.jpg)
Incompatibilities
![Page 55: Last train to php 7](https://reader030.fdocuments.net/reader030/viewer/2022012908/58ed07db1a28abfd388b45f3/html5/thumbnails/55.jpg)
Incompatibilities
Removed features
Added features
Collateral damages
![Page 56: Last train to php 7](https://reader030.fdocuments.net/reader030/viewer/2022012908/58ed07db1a28abfd388b45f3/html5/thumbnails/56.jpg)
Removed features
![Page 57: Last train to php 7](https://reader030.fdocuments.net/reader030/viewer/2022012908/58ed07db1a28abfd388b45f3/html5/thumbnails/57.jpg)
Removed extensions
Extensions
ereg
mssql
mysql
sybase_ct
mcrypt 7.2
![Page 58: Last train to php 7](https://reader030.fdocuments.net/reader030/viewer/2022012908/58ed07db1a28abfd388b45f3/html5/thumbnails/58.jpg)
Removed extensions
ext/ereg
ereg
ereg_replace
split
sql_regcase
Moved utf8_encode() and utf8_decode() to the Standard extension7.2
![Page 59: Last train to php 7](https://reader030.fdocuments.net/reader030/viewer/2022012908/58ed07db1a28abfd388b45f3/html5/thumbnails/59.jpg)
Removed functions
call_user_method()
call_user_method_array()
Repleacable by $funcname
Replaced by call_user_func() and call_user_func_array()
Partially replaced by variadic
png2wbmp() and jpeg2wbmp()
Deprecated
7.2
![Page 60: Last train to php 7](https://reader030.fdocuments.net/reader030/viewer/2022012908/58ed07db1a28abfd388b45f3/html5/thumbnails/60.jpg)
Removed variables
$HTTP_RAW_POST_DATA
Replace it by php://input
php://input is now reusable
Since PHP 5.5
![Page 61: Last train to php 7](https://reader030.fdocuments.net/reader030/viewer/2022012908/58ed07db1a28abfd388b45f3/html5/thumbnails/61.jpg)
Removed INI
sql.safe_mode (PHP 7.2)
mbstring.internal_encoding
mbstring.http_output
mbstring.http_input
iconv.internal_encoding
iconv.input_encoding
iconv.output_encoding
default_charset}
![Page 62: Last train to php 7](https://reader030.fdocuments.net/reader030/viewer/2022012908/58ed07db1a28abfd388b45f3/html5/thumbnails/62.jpg)
default_charset
htmlentities()
PHP 5.3 : ISO-8859-1
PHP 5.4 : UTF-8
PHP 5.6 : default_charset (also UTF 8)
![Page 63: Last train to php 7](https://reader030.fdocuments.net/reader030/viewer/2022012908/58ed07db1a28abfd388b45f3/html5/thumbnails/63.jpg)
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()
![Page 64: Last train to php 7](https://reader030.fdocuments.net/reader030/viewer/2022012908/58ed07db1a28abfd388b45f3/html5/thumbnails/64.jpg)
Preg_replace and /e
preg_replace(‘/ /e’, ‘evaled code’, $haystack)
replaced by
preg_replace_callback_array()
preg_replace(‘/ /e’, ‘evaled code’, $haystack)
preg_replace_callback_array([‘/ /’ => $closure], $haystack)
preg_replace_callback(‘/ /’, $closure],
$haystack)
![Page 65: Last train to php 7](https://reader030.fdocuments.net/reader030/viewer/2022012908/58ed07db1a28abfd388b45f3/html5/thumbnails/65.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 66: Last train to php 7](https://reader030.fdocuments.net/reader030/viewer/2022012908/58ed07db1a28abfd388b45f3/html5/thumbnails/66.jpg)
preg_replace()
<?php
$code = "abcde";
echo preg_replace( array( '/a/', '/b/'), array( 'f' , 'g'), $code);
fgcde
![Page 67: Last train to php 7](https://reader030.fdocuments.net/reader030/viewer/2022012908/58ed07db1a28abfd388b45f3/html5/thumbnails/67.jpg)
Can't call dynamically!
•$func() •call_user_func() •array_map() •or similar •assert() with a string argument
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
![Page 68: Last train to php 7](https://reader030.fdocuments.net/reader030/viewer/2022012908/58ed07db1a28abfd388b45f3/html5/thumbnails/68.jpg)
Added features
![Page 69: Last train to php 7](https://reader030.fdocuments.net/reader030/viewer/2022012908/58ed07db1a28abfd388b45f3/html5/thumbnails/69.jpg)
Added definitions
Functions Classes Constants5.3 40 2 805.4 0 9 785.5 12 11 575.6 1 10 107.0 10 10 417.1 9 3 307.2 4 0 15
Total 766 92 1163
![Page 70: Last train to php 7](https://reader030.fdocuments.net/reader030/viewer/2022012908/58ed07db1a28abfd388b45f3/html5/thumbnails/70.jpg)
Name impact
get_resources(), intdiv(), is_iterable(), mb_scrub()
PREG_JIT_STACKLIMIT_ERROR
class Date (from PHP 5.1)
Error (new class in PHP 7)
![Page 71: Last train to php 7](https://reader030.fdocuments.net/reader030/viewer/2022012908/58ed07db1a28abfd388b45f3/html5/thumbnails/71.jpg)
New functions
intdiv()
get_resources()
random_bytes(), random_int()
error_clear_last()
gc_mem_caches()
preg_replace_callback_array()
socket_getaddrinfo()
mb_ord, mb_scrub,
![Page 72: Last train to php 7](https://reader030.fdocuments.net/reader030/viewer/2022012908/58ed07db1a28abfd388b45f3/html5/thumbnails/72.jpg)
Collaterals
![Page 73: Last train to php 7](https://reader030.fdocuments.net/reader030/viewer/2022012908/58ed07db1a28abfd388b45f3/html5/thumbnails/73.jpg)
Invalid octals are invalid
Upgraded from silent to Fatal error
PHP Parse error: Invalid numeric literal in test.php
<?php
$x = 0890;
![Page 74: Last train to php 7](https://reader030.fdocuments.net/reader030/viewer/2022012908/58ed07db1a28abfd388b45f3/html5/thumbnails/74.jpg)
More invalid octals in strings
<?php
var_dump("\000" === "\400");
https://wiki.php.net/rfc/octal.overload-checking
![Page 75: Last train to php 7](https://reader030.fdocuments.net/reader030/viewer/2022012908/58ed07db1a28abfd388b45f3/html5/thumbnails/75.jpg)
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
![Page 76: Last train to php 7](https://reader030.fdocuments.net/reader030/viewer/2022012908/58ed07db1a28abfd388b45f3/html5/thumbnails/76.jpg)
More relaxed keywords
<?php class foo { const instanceof = 1; function use() { $this->while(4) + foo::instanceof; } }
![Page 77: Last train to php 7](https://reader030.fdocuments.net/reader030/viewer/2022012908/58ed07db1a28abfd388b45f3/html5/thumbnails/77.jpg)
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"; //
![Page 78: Last train to php 7](https://reader030.fdocuments.net/reader030/viewer/2022012908/58ed07db1a28abfd388b45f3/html5/thumbnails/78.jpg)
Strings may be invalid
<?php
echo "\u{Yes}\n";
PHP Parse error: Invalid UTF-8 codepoint escape sequence in test.php on line 3
\u{
![Page 79: Last train to php 7](https://reader030.fdocuments.net/reader030/viewer/2022012908/58ed07db1a28abfd388b45f3/html5/thumbnails/79.jpg)
Hexadecimal numeric strings
Also, -0 !!
<?php
var_dump(1 + 0xf); var_dump(1 + "0xf");
$ php56 test.php int(16) int(16)
$ php70 test.php int(16) int(1)
![Page 80: Last train to php 7](https://reader030.fdocuments.net/reader030/viewer/2022012908/58ed07db1a28abfd388b45f3/html5/thumbnails/80.jpg)
Warning for strings (7.1)
<?php
print "2" + "4"; print "3 elephpants" + "4 dolphins"; print "2" + "d4 d";
6 7 2
Warning: A non-numeric value encountered
![Page 81: Last train to php 7](https://reader030.fdocuments.net/reader030/viewer/2022012908/58ed07db1a28abfd388b45f3/html5/thumbnails/81.jpg)
Exceptions
Throwable
Exception
LogicException RuntimeException
BadFunctionCallException
BadMethodCallException
DomainExceptionInvalidArgumentException
OutOfRangeException
OutOfBoundsException
OverflowException
RangeException
Error
ParseErrorDivisionByZeroError
AssertionError
![Page 82: Last train to php 7](https://reader030.fdocuments.net/reader030/viewer/2022012908/58ed07db1a28abfd388b45f3/html5/thumbnails/82.jpg)
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
![Page 83: Last train to php 7](https://reader030.fdocuments.net/reader030/viewer/2022012908/58ed07db1a28abfd388b45f3/html5/thumbnails/83.jpg)
More catching exceptions
<?php
try { eval($somePHPcode); } catch( ParseError $e) { log($e->getMessage()); // attempt to fix this or error handling }
![Page 84: Last train to php 7](https://reader030.fdocuments.net/reader030/viewer/2022012908/58ed07db1a28abfd388b45f3/html5/thumbnails/84.jpg)
More catching exceptions
Parser errors now throw a ParseError object. Error handling for eval()
<?php
try { $file = new finfo(FILEINFO_NONE,$magic_file); } catch( ParseError $e) { log($e->getMessage()); // attempt to fix this or error handling }
![Page 85: Last train to php 7](https://reader030.fdocuments.net/reader030/viewer/2022012908/58ed07db1a28abfd388b45f3/html5/thumbnails/85.jpg)
<?php
try { $random = random_bytes($size); } catch( TypeError $e) { // invalid parameter } catch( Error $e) { // invalid length } catch( Exception $e) { // no source of randomness }
And more catching exceptions
![Page 86: Last train to php 7](https://reader030.fdocuments.net/reader030/viewer/2022012908/58ed07db1a28abfd388b45f3/html5/thumbnails/86.jpg)
Even more catching exceptions
<?php
try { attemptSomething(); } catch (RuntimeException $e) { fixSomething(); } catch (InvalidArgumentException $e) { fixSomething(); } catch (BadFunctioncallException $e) { fixSomething(); }
![Page 87: Last train to php 7](https://reader030.fdocuments.net/reader030/viewer/2022012908/58ed07db1a28abfd388b45f3/html5/thumbnails/87.jpg)
Even more catching exceptions
Parser errors now throw a ParseError object. Error handling for eval()
<?php
try { attemptSomething(); } catch (RuntimeException| InvalidArgumentException| BadFunctioncallException $e) { fixSomething(); }
![Page 88: Last train to php 7](https://reader030.fdocuments.net/reader030/viewer/2022012908/58ed07db1a28abfd388b45f3/html5/thumbnails/88.jpg)
Even more catching exceptions
<?php
//try really hardertry { attemptSomething(); } catch (Exception $e) { attemptSomething(); }
![Page 89: Last train to php 7](https://reader030.fdocuments.net/reader030/viewer/2022012908/58ed07db1a28abfd388b45f3/html5/thumbnails/89.jpg)
Negative string offset (7.1)
<?php
$string = "abcde";
print $string[-3];
print "$string[3]";
print "$string[-2]";
c
d
d
![Page 90: Last train to php 7](https://reader030.fdocuments.net/reader030/viewer/2022012908/58ed07db1a28abfd388b45f3/html5/thumbnails/90.jpg)
list() with keys
Upgraded to Fatal error
<?php $array = ['a' => 1, 'b' => 5, 'c' => 3];
// Assigns to $a, $b and $c in the same orderlist($a, $b, $c) = array_values($array);
// Assigns to $a, $b and $c from the keys //"a", "b" and "c", respectively list("a" => $a, "c" => $c, "b" => $b) = $array;list("a" => $a, "b" => $b, "c" => $c) = $array;list("c" => $c, "a" => $a, "b" => $b) = $array;
![Page 91: Last train to php 7](https://reader030.fdocuments.net/reader030/viewer/2022012908/58ed07db1a28abfd388b45f3/html5/thumbnails/91.jpg)
list() with keys
<?php $array = ['b' => 5, 'a' => 1, 'c' => 3]; ksort($array); $array = array_values($array);
// Assigns to $a, $b and $c in the same order list($a, $b, $c) = $array;
// SELECT id, * FROM users list($userId, $name, $last) = array_values($row);
![Page 92: Last train to php 7](https://reader030.fdocuments.net/reader030/viewer/2022012908/58ed07db1a28abfd388b45f3/html5/thumbnails/92.jpg)
Short syntax for list()
<?php
$array = ['a' => 1, 'b' => 5, 'c' => 3];
["a" => $b, "c" => $c, "b" => $a] = $array;
// Works even when nested $array = [['a' => 1, 'b' => 5], ['c' => 3]];
[["a" => $a, "b" => $b], ["c" => $c]] = $array;
![Page 93: Last train to php 7](https://reader030.fdocuments.net/reader030/viewer/2022012908/58ed07db1a28abfd388b45f3/html5/thumbnails/93.jpg)
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 …
![Page 94: Last train to php 7](https://reader030.fdocuments.net/reader030/viewer/2022012908/58ed07db1a28abfd388b45f3/html5/thumbnails/94.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 inNotice: Undefined variable: $this in A
![Page 95: Last train to php 7](https://reader030.fdocuments.net/reader030/viewer/2022012908/58ed07db1a28abfd388b45f3/html5/thumbnails/95.jpg)
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
![Page 96: Last train to php 7](https://reader030.fdocuments.net/reader030/viewer/2022012908/58ed07db1a28abfd388b45f3/html5/thumbnails/96.jpg)
$this is for classes<?php class bar{ function foo($this) { static $this; global $this;
foreach ($a as $this) { try { $a = "this"; $$a = 42; } catch (Exception $this) {} } unset($this); } }
![Page 97: Last train to php 7](https://reader030.fdocuments.net/reader030/viewer/2022012908/58ed07db1a28abfd388b45f3/html5/thumbnails/97.jpg)
Changed behavior
![Page 98: Last train to php 7](https://reader030.fdocuments.net/reader030/viewer/2022012908/58ed07db1a28abfd388b45f3/html5/thumbnails/98.jpg)
Changed behavior
Indirect expressions
![Page 99: Last train to php 7](https://reader030.fdocuments.net/reader030/viewer/2022012908/58ed07db1a28abfd388b45f3/html5/thumbnails/99.jpg)
func_get_arg()
func_get_arg() and func_get_args() now return the current argument values
<?php
function foo($a, $b, $c) { print_r(func_get_args()); ++$a; print_r(func_get_args()); } foo(1,2,3);
Array ( [0] => 1 [1] => 2 [2] => 3 ) Array ( [0] => 2 [1] => 2 [2] => 3 )
![Page 100: Last train to php 7](https://reader030.fdocuments.net/reader030/viewer/2022012908/58ed07db1a28abfd388b45f3/html5/thumbnails/100.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 101: Last train to php 7](https://reader030.fdocuments.net/reader030/viewer/2022012908/58ed07db1a28abfd388b45f3/html5/thumbnails/101.jpg)
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.
![Page 102: Last train to php 7](https://reader030.fdocuments.net/reader030/viewer/2022012908/58ed07db1a28abfd388b45f3/html5/thumbnails/102.jpg)
New features
![Page 103: Last train to php 7](https://reader030.fdocuments.net/reader030/viewer/2022012908/58ed07db1a28abfd388b45f3/html5/thumbnails/103.jpg)
New features
Breaks backward compatibility sometimes
FUD
Search for places to apply them like for incompatibilities
![Page 104: Last train to php 7](https://reader030.fdocuments.net/reader030/viewer/2022012908/58ed07db1a28abfd388b45f3/html5/thumbnails/104.jpg)
New features
Fixing
Modernization
New features
![Page 105: Last train to php 7](https://reader030.fdocuments.net/reader030/viewer/2022012908/58ed07db1a28abfd388b45f3/html5/thumbnails/105.jpg)
Fixing
![Page 106: Last train to php 7](https://reader030.fdocuments.net/reader030/viewer/2022012908/58ed07db1a28abfd388b45f3/html5/thumbnails/106.jpg)
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
![Page 107: Last train to php 7](https://reader030.fdocuments.net/reader030/viewer/2022012908/58ed07db1a28abfd388b45f3/html5/thumbnails/107.jpg)
Constant arrays
Lots of properties could be turned to 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 108: Last train to php 7](https://reader030.fdocuments.net/reader030/viewer/2022012908/58ed07db1a28abfd388b45f3/html5/thumbnails/108.jpg)
Constant visibility
<?php class Version { private const BUILD = 123; public const VERSION = '1.2.2'; }
echo Version::UNDEFINED; echo Version::BUILD; echo Version::VERSION;
![Page 109: Last train to php 7](https://reader030.fdocuments.net/reader030/viewer/2022012908/58ed07db1a28abfd388b45f3/html5/thumbnails/109.jpg)
Constant arrays
Lots of properties could be turned to 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 110: Last train to php 7](https://reader030.fdocuments.net/reader030/viewer/2022012908/58ed07db1a28abfd388b45f3/html5/thumbnails/110.jpg)
Modernization
![Page 111: Last train to php 7](https://reader030.fdocuments.net/reader030/viewer/2022012908/58ed07db1a28abfd388b45f3/html5/thumbnails/111.jpg)
Foreach update the actual array
<?php
$array = [0]; foreach ($array as $k => &$val) { print "$k\n"; $array[] = 1; // Only for pushing, not unshifting }
0 1 2 3 4 5 6 7 8 9 10 11
0
![Page 112: Last train to php 7](https://reader030.fdocuments.net/reader030/viewer/2022012908/58ed07db1a28abfd388b45f3/html5/thumbnails/112.jpg)
Array/Object casting
<?php
$arr = [0 => 1, 1 => 2, 2 => 3]; $obj = (object)$arr;
// PHP 7.1 echo $obj->{"0"};
// PHP 7.2 echo $obj->{0};
7.2
![Page 113: Last train to php 7](https://reader030.fdocuments.net/reader030/viewer/2022012908/58ed07db1a28abfd388b45f3/html5/thumbnails/113.jpg)
Warn with COUNT()
<?php function handle_records(iterable $iterable) { if (count($iterable) === 0) { return handle_empty(); } foreach ($iterable as $value) { handle_value($value); } }
7.2
![Page 114: Last train to php 7](https://reader030.fdocuments.net/reader030/viewer/2022012908/58ed07db1a28abfd388b45f3/html5/thumbnails/114.jpg)
Closure binding
<?php class Hello { private $hello = "Hello";
function makeClosure() { return function() { echo $this->hello; }; }
$obj = new Hello(); $closure = $obj->makeClosure(); $closure();
![Page 115: Last train to php 7](https://reader030.fdocuments.net/reader030/viewer/2022012908/58ed07db1a28abfd388b45f3/html5/thumbnails/115.jpg)
Closure binding
<?php
class {
private $hello = " ";
}
$obj = new Hello(); $closure = $obj->makeClosure();
$nihao = new ();
$closure2 = $closure->bindTo($nihao); $closure2();
Request the closure from the object
![Page 116: Last train to php 7](https://reader030.fdocuments.net/reader030/viewer/2022012908/58ed07db1a28abfd388b45f3/html5/thumbnails/116.jpg)
Closure binding
<?php $closure = function() { echo $this->hello; };
class {
private $hello = " ";
}
$nihao = new ();
$closure->call($nihao);
Bind the object at the last moment
![Page 117: Last train to php 7](https://reader030.fdocuments.net/reader030/viewer/2022012908/58ed07db1a28abfd388b45f3/html5/thumbnails/117.jpg)
session_start($options)
Very Cute <=>
Replaces a lot of code
Mainly useful for usort()
<?php
// PHP 5.6 ini_set('session.name','session'); ini_set('session.gc_probability',1); ini_set('session.gc_divisor',1); session_start();
// PHP 7.0 session_start(['name' => 'session', 'gc_probability' => 1, 'gc_divisor' => 1 ] );
![Page 118: Last train to php 7](https://reader030.fdocuments.net/reader030/viewer/2022012908/58ed07db1a28abfd388b45f3/html5/thumbnails/118.jpg)
dirname() second argument
<?php $path = '/a/b/c/d/e/f';
// PHP 5.6 $root = dirname(dirname(dirname($x)));
// PHP 7 $root = dirname($path, 3); ?>
![Page 119: Last train to php 7](https://reader030.fdocuments.net/reader030/viewer/2022012908/58ed07db1a28abfd388b45f3/html5/thumbnails/119.jpg)
Parameters evolution
get_headers() has an extra parameter
Passing a custom stream context
getenv() doesn't need parameter
all the current environment variables will be returned
get_class() doesn't allow null anymore
![Page 120: Last train to php 7](https://reader030.fdocuments.net/reader030/viewer/2022012908/58ed07db1a28abfd388b45f3/html5/thumbnails/120.jpg)
Really new
![Page 121: Last train to php 7](https://reader030.fdocuments.net/reader030/viewer/2022012908/58ed07db1a28abfd388b45f3/html5/thumbnails/121.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 122: Last train to php 7](https://reader030.fdocuments.net/reader030/viewer/2022012908/58ed07db1a28abfd388b45f3/html5/thumbnails/122.jpg)
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
![Page 123: Last train to php 7](https://reader030.fdocuments.net/reader030/viewer/2022012908/58ed07db1a28abfd388b45f3/html5/thumbnails/123.jpg)
Generators delegation
New yield keyword
Save memory from
n down to 1 value
Good for long or infinite loops
Search for range(), for() or loops
<?php function factors($limit) { yield 2; yield 3;
yield from primeTill1000();
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 124: Last train to php 7](https://reader030.fdocuments.net/reader030/viewer/2022012908/58ed07db1a28abfd388b45f3/html5/thumbnails/124.jpg)
Generators returns<?php function factors($limit) { return 'first'; yield 2; return 'second'; yield 3; return 'third'; yield 5; } $gen = factors(sqrt($prime)); foreach ($gen as $n) { echo "$n\n"; if ($n == 3) {break 1;} } print $gen->getReturn(); // second
Generators returns
The last return is accessible
The generator returns the final state
![Page 125: Last train to php 7](https://reader030.fdocuments.net/reader030/viewer/2022012908/58ed07db1a28abfd388b45f3/html5/thumbnails/125.jpg)
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) { ... }
![Page 126: Last train to php 7](https://reader030.fdocuments.net/reader030/viewer/2022012908/58ed07db1a28abfd388b45f3/html5/thumbnails/126.jpg)
Scalar typehint back in 5.6
Whenever type is tested =>
<?php
function foo(string $x) { } foo('that');
Catchable fatal error: Argument 1 passed tofoo() must be an instance of string, string given, called in file..
![Page 127: Last train to php 7](https://reader030.fdocuments.net/reader030/viewer/2022012908/58ed07db1a28abfd388b45f3/html5/thumbnails/127.jpg)
Various scalar typehint
int, float
string, bool
true, false, null
void (PHP 7.1)
mixed, object, resource, numeric (RFU)
<?php
function foo(?int $a, float $b, float $c) : ?int { return $a + $b + $c; }
echo foo(null, 2, 1); // 4 echo foo(1.2, 2, 1); // 4 echo foo(1, 2.2, 1); // 4 echo foo(1, 2.7, 1.4); // 5
![Page 128: Last train to php 7](https://reader030.fdocuments.net/reader030/viewer/2022012908/58ed07db1a28abfd388b45f3/html5/thumbnails/128.jpg)
Option for strict typing
<?php // Enable strict types declare(strict_types=1);
declare(encoding='ISO-8859-1'); declare(ticks=1);
namespace Foo\Bar; foo('that');
![Page 129: Last train to php 7](https://reader030.fdocuments.net/reader030/viewer/2022012908/58ed07db1a28abfd388b45f3/html5/thumbnails/129.jpg)
Return type hint
<?php
function getData($login) : user { if (userExists($login)) { return userDetails($login); } else { return null; } }
![Page 130: Last train to php 7](https://reader030.fdocuments.net/reader030/viewer/2022012908/58ed07db1a28abfd388b45f3/html5/thumbnails/130.jpg)
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
![Page 131: Last train to php 7](https://reader030.fdocuments.net/reader030/viewer/2022012908/58ed07db1a28abfd388b45f3/html5/thumbnails/131.jpg)
Helping at migration
Document the evolutions between two versions
Identify anchors in the code
Link the migration to the actual code
Keywords, syntax, code structures
Suggest fallback, work-around, detection tools
![Page 132: Last train to php 7](https://reader030.fdocuments.net/reader030/viewer/2022012908/58ed07db1a28abfd388b45f3/html5/thumbnails/132.jpg)
Helping at migration
Backward incompatibilities
Removed / renamed features
Collaterals
Changed behaviors
![Page 133: Last train to php 7](https://reader030.fdocuments.net/reader030/viewer/2022012908/58ed07db1a28abfd388b45f3/html5/thumbnails/133.jpg)
Helping at migration
New features
Fixing
Totally new
Spot previous work-arounds
![Page 134: Last train to php 7](https://reader030.fdocuments.net/reader030/viewer/2022012908/58ed07db1a28abfd388b45f3/html5/thumbnails/134.jpg)
![Page 135: Last train to php 7](https://reader030.fdocuments.net/reader030/viewer/2022012908/58ed07db1a28abfd388b45f3/html5/thumbnails/135.jpg)
Summary
Check the manuals
PHP lint is your friend
Search in the code
Use static analysis tools
![Page 136: Last train to php 7](https://reader030.fdocuments.net/reader030/viewer/2022012908/58ed07db1a28abfd388b45f3/html5/thumbnails/136.jpg)
Thank you!Damien Seguy @exakat [email protected]
https://www.exakat.io/
https://joind.in/event/php-uk-2017/schedule/list
![Page 137: Last train to php 7](https://reader030.fdocuments.net/reader030/viewer/2022012908/58ed07db1a28abfd388b45f3/html5/thumbnails/137.jpg)
The end