preparing code for php 7 workshop
TRANSCRIPT
![Page 1: Preparing code for Php 7 workshop](https://reader033.vdocument.in/reader033/viewer/2022050900/588a1bc31a28abb21f8b4685/html5/thumbnails/1.jpg)
Preparing for PHP 7.1 workshop
Damien Seguy @exakat Warsaw, Poland, October 2016
![Page 2: Preparing code for Php 7 workshop](https://reader033.vdocument.in/reader033/viewer/2022050900/588a1bc31a28abb21f8b4685/html5/thumbnails/2.jpg)
Full ahead to PHP 7. 1
• Changing version is always a big challenge
• Backward incompatibilities
• New features
• Learn, spot, fix, repeat
0
![Page 3: Preparing code for Php 7 workshop](https://reader033.vdocument.in/reader033/viewer/2022050900/588a1bc31a28abb21f8b4685/html5/thumbnails/3.jpg)
Speaker
• Damien Seguy
• CTO at exakat
• Static code analysis for PHP
![Page 4: Preparing code for Php 7 workshop](https://reader033.vdocument.in/reader033/viewer/2022050900/588a1bc31a28abb21f8b4685/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: Preparing code for Php 7 workshop](https://reader033.vdocument.in/reader033/viewer/2022050900/588a1bc31a28abb21f8b4685/html5/thumbnails/5.jpg)
Migration to PHP 7.1
• 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: Preparing code for Php 7 workshop](https://reader033.vdocument.in/reader033/viewer/2022050900/588a1bc31a28abb21f8b4685/html5/thumbnails/6.jpg)
Destination
![Page 7: Preparing code for Php 7 workshop](https://reader033.vdocument.in/reader033/viewer/2022050900/588a1bc31a28abb21f8b4685/html5/thumbnails/7.jpg)
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
![Page 8: Preparing code for Php 7 workshop](https://reader033.vdocument.in/reader033/viewer/2022050900/588a1bc31a28abb21f8b4685/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: Preparing code for Php 7 workshop](https://reader033.vdocument.in/reader033/viewer/2022050900/588a1bc31a28abb21f8b4685/html5/thumbnails/9.jpg)
![Page 10: Preparing code for Php 7 workshop](https://reader033.vdocument.in/reader033/viewer/2022050900/588a1bc31a28abb21f8b4685/html5/thumbnails/10.jpg)
![Page 11: Preparing code for Php 7 workshop](https://reader033.vdocument.in/reader033/viewer/2022050900/588a1bc31a28abb21f8b4685/html5/thumbnails/11.jpg)
![Page 12: Preparing code for Php 7 workshop](https://reader033.vdocument.in/reader033/viewer/2022050900/588a1bc31a28abb21f8b4685/html5/thumbnails/12.jpg)
![Page 13: Preparing code for Php 7 workshop](https://reader033.vdocument.in/reader033/viewer/2022050900/588a1bc31a28abb21f8b4685/html5/thumbnails/13.jpg)
![Page 14: Preparing code for Php 7 workshop](https://reader033.vdocument.in/reader033/viewer/2022050900/588a1bc31a28abb21f8b4685/html5/thumbnails/14.jpg)
• PHP has 3 phases
• syntax
• definitions
• execution
Where does code break?
Checked with phplint
Checked with tests
Checked code review
![Page 15: Preparing code for Php 7 workshop](https://reader033.vdocument.in/reader033/viewer/2022050900/588a1bc31a28abb21f8b4685/html5/thumbnails/15.jpg)
<?php
function splitNames($fullname, $fullname) { list($first, $last) = split($fullname, ' '); }
?>
Where will code break?
SyntaxDefinitionsExecution
![Page 16: Preparing code for Php 7 workshop](https://reader033.vdocument.in/reader033/viewer/2022050900/588a1bc31a28abb21f8b4685/html5/thumbnails/16.jpg)
Tools for migration
• Your own experience with your code
• Lint
• Search
• Static analysis
• Logs
![Page 17: Preparing code for Php 7 workshop](https://reader033.vdocument.in/reader033/viewer/2022050900/588a1bc31a28abb21f8b4685/html5/thumbnails/17.jpg)
Linting PHP 7
![Page 18: Preparing code for Php 7 workshop](https://reader033.vdocument.in/reader033/viewer/2022050900/588a1bc31a28abb21f8b4685/html5/thumbnails/18.jpg)
PHP linting
• command line : php -l filename.php
• Spot parse errors
• Works on files only :
• For directories, see composer phplint/phplint
![Page 19: Preparing code for Php 7 workshop](https://reader033.vdocument.in/reader033/viewer/2022050900/588a1bc31a28abb21f8b4685/html5/thumbnails/19.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 20: Preparing code for Php 7 workshop](https://reader033.vdocument.in/reader033/viewer/2022050900/588a1bc31a28abb21f8b4685/html5/thumbnails/20.jpg)
Backward unlintable code
![Page 21: Preparing code for Php 7 workshop](https://reader033.vdocument.in/reader033/viewer/2022050900/588a1bc31a28abb21f8b4685/html5/thumbnails/21.jpg)
Code focused on current versions
![Page 22: Preparing code for Php 7 workshop](https://reader033.vdocument.in/reader033/viewer/2022050900/588a1bc31a28abb21f8b4685/html5/thumbnails/22.jpg)
Backward unlintable code
![Page 23: Preparing code for Php 7 workshop](https://reader033.vdocument.in/reader033/viewer/2022050900/588a1bc31a28abb21f8b4685/html5/thumbnails/23.jpg)
Redefinition of parameter
<?php
function foo($a, $a, $a) { print $a."\n"; }
foo('x', 'y', 'z');
?>
![Page 24: Preparing code for Php 7 workshop](https://reader033.vdocument.in/reader033/viewer/2022050900/588a1bc31a28abb21f8b4685/html5/thumbnails/24.jpg)
Switch statements only contain one default clause
<?php
switch($x) { case '1' : break; default : break; default : break; case '2' : break; }
![Page 25: Preparing code for Php 7 workshop](https://reader033.vdocument.in/reader033/viewer/2022050900/588a1bc31a28abb21f8b4685/html5/thumbnails/25.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 26: Preparing code for Php 7 workshop](https://reader033.vdocument.in/reader033/viewer/2022050900/588a1bc31a28abb21f8b4685/html5/thumbnails/26.jpg)
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
![Page 27: Preparing code for Php 7 workshop](https://reader033.vdocument.in/reader033/viewer/2022050900/588a1bc31a28abb21f8b4685/html5/thumbnails/27.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 28: Preparing code for Php 7 workshop](https://reader033.vdocument.in/reader033/viewer/2022050900/588a1bc31a28abb21f8b4685/html5/thumbnails/28.jpg)
Migration to PHP 7.1
• Lint with
• PHP 7.1
• PHP 7.2 (or src)
• PHP 5.6 (current), PHP 7.0
• PHP 5.5, 5.4,… (manual)
![Page 29: Preparing code for Php 7 workshop](https://reader033.vdocument.in/reader033/viewer/2022050900/588a1bc31a28abb21f8b4685/html5/thumbnails/29.jpg)
PHP 7 linting
• Pre-commit
• Use different versions
• Be ruthless with unlintable files
![Page 30: Preparing code for Php 7 workshop](https://reader033.vdocument.in/reader033/viewer/2022050900/588a1bc31a28abb21f8b4685/html5/thumbnails/30.jpg)
• PHP has 3 phases
• syntax
• definitions
• execution
Where does code break?
Checked with phplint
Checked with tests
Checked code review
![Page 31: Preparing code for Php 7 workshop](https://reader033.vdocument.in/reader033/viewer/2022050900/588a1bc31a28abb21f8b4685/html5/thumbnails/31.jpg)
Static analysis
![Page 32: Preparing code for Php 7 workshop](https://reader033.vdocument.in/reader033/viewer/2022050900/588a1bc31a28abb21f8b4685/html5/thumbnails/32.jpg)
Presentation
• Review code without executing it
• Common in C/C++, Java, Javascript
• Hot subject coming to PHP
![Page 33: Preparing code for Php 7 workshop](https://reader033.vdocument.in/reader033/viewer/2022050900/588a1bc31a28abb21f8b4685/html5/thumbnails/33.jpg)
GREP/SEARCH
• Any searching facility
• Pro : High speed, great for keyword search, universal
• Cons : Little repeat value, no PHP semantics
![Page 34: Preparing code for Php 7 workshop](https://reader033.vdocument.in/reader033/viewer/2022050900/588a1bc31a28abb21f8b4685/html5/thumbnails/34.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 35: Preparing code for Php 7 workshop](https://reader033.vdocument.in/reader033/viewer/2022050900/588a1bc31a28abb21f8b4685/html5/thumbnails/35.jpg)
Static analysis
PHP 5 / 7 Calisthenics ClearPHP
Performance
![Page 36: Preparing code for Php 7 workshop](https://reader033.vdocument.in/reader033/viewer/2022050900/588a1bc31a28abb21f8b4685/html5/thumbnails/36.jpg)
Static analysis tools
PHP7mar
PHP7cc
Phan
Exakat
PHP inspections
![Page 37: Preparing code for Php 7 workshop](https://reader033.vdocument.in/reader033/viewer/2022050900/588a1bc31a28abb21f8b4685/html5/thumbnails/37.jpg)
PHP7mar
• PHP 7 Migration Assistant Report (MAR)
• Alexia : https://github.com/Alexia/php7mar
• Works with regex
• Produces a .md file
![Page 38: Preparing code for Php 7 workshop](https://reader033.vdocument.in/reader033/viewer/2022050900/588a1bc31a28abb21f8b4685/html5/thumbnails/38.jpg)
12 results
![Page 39: Preparing code for Php 7 workshop](https://reader033.vdocument.in/reader033/viewer/2022050900/588a1bc31a28abb21f8b4685/html5/thumbnails/39.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 40: Preparing code for Php 7 workshop](https://reader033.vdocument.in/reader033/viewer/2022050900/588a1bc31a28abb21f8b4685/html5/thumbnails/40.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 41: Preparing code for Php 7 workshop](https://reader033.vdocument.in/reader033/viewer/2022050900/588a1bc31a28abb21f8b4685/html5/thumbnails/41.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 42: Preparing code for Php 7 workshop](https://reader033.vdocument.in/reader033/viewer/2022050900/588a1bc31a28abb21f8b4685/html5/thumbnails/42.jpg)
![Page 43: Preparing code for Php 7 workshop](https://reader033.vdocument.in/reader033/viewer/2022050900/588a1bc31a28abb21f8b4685/html5/thumbnails/43.jpg)
11.244s 333 resultsPhanUndeclaredProperty 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 44: Preparing code for Php 7 workshop](https://reader033.vdocument.in/reader033/viewer/2022050900/588a1bc31a28abb21f8b4685/html5/thumbnails/44.jpg)
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
![Page 45: Preparing code for Php 7 workshop](https://reader033.vdocument.in/reader033/viewer/2022050900/588a1bc31a28abb21f8b4685/html5/thumbnails/45.jpg)
20 mins6798 results260 analysis
![Page 46: Preparing code for Php 7 workshop](https://reader033.vdocument.in/reader033/viewer/2022050900/588a1bc31a28abb21f8b4685/html5/thumbnails/46.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 47: Preparing code for Php 7 workshop](https://reader033.vdocument.in/reader033/viewer/2022050900/588a1bc31a28abb21f8b4685/html5/thumbnails/47.jpg)
![Page 48: Preparing code for Php 7 workshop](https://reader033.vdocument.in/reader033/viewer/2022050900/588a1bc31a28abb21f8b4685/html5/thumbnails/48.jpg)
Write your own?
• https://github.com/exakat/php-static-analysis-tools.git
• PHP 7 : use ext/ast
• PHP 5 :"nikic/php-parser"
• Avoid regex (but it does work)
![Page 49: Preparing code for Php 7 workshop](https://reader033.vdocument.in/reader033/viewer/2022050900/588a1bc31a28abb21f8b4685/html5/thumbnails/49.jpg)
PHP 7 : what changes?
• Incompatible changes
• New features
• Features/Incompatibilities from PHP 5.6 => 7.2
![Page 50: Preparing code for Php 7 workshop](https://reader033.vdocument.in/reader033/viewer/2022050900/588a1bc31a28abb21f8b4685/html5/thumbnails/50.jpg)
How to spot issues?
• Code knowledge
• lint
• Grep / Search
• Static analysis
• Logs / error_reporting
• Unit Tests
What to replace them with ?
![Page 51: Preparing code for Php 7 workshop](https://reader033.vdocument.in/reader033/viewer/2022050900/588a1bc31a28abb21f8b4685/html5/thumbnails/51.jpg)
Incompatibilities
![Page 52: Preparing code for Php 7 workshop](https://reader033.vdocument.in/reader033/viewer/2022050900/588a1bc31a28abb21f8b4685/html5/thumbnails/52.jpg)
Incompatibilities
• Removed features
• Added features
• Collateral damages
![Page 53: Preparing code for Php 7 workshop](https://reader033.vdocument.in/reader033/viewer/2022050900/588a1bc31a28abb21f8b4685/html5/thumbnails/53.jpg)
Removed features
![Page 54: Preparing code for Php 7 workshop](https://reader033.vdocument.in/reader033/viewer/2022050900/588a1bc31a28abb21f8b4685/html5/thumbnails/54.jpg)
Removed extensions
• Extensions
• ereg
• mssql
• mysql
• sybase_ct
• mcrypt (7.1)
![Page 55: Preparing code for Php 7 workshop](https://reader033.vdocument.in/reader033/viewer/2022050900/588a1bc31a28abb21f8b4685/html5/thumbnails/55.jpg)
Removed extensions
• ext/ereg
• ereg
• ereg_replace
• split
• sql_regcase
![Page 56: Preparing code for Php 7 workshop](https://reader033.vdocument.in/reader033/viewer/2022050900/588a1bc31a28abb21f8b4685/html5/thumbnails/56.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
![Page 57: Preparing code for Php 7 workshop](https://reader033.vdocument.in/reader033/viewer/2022050900/588a1bc31a28abb21f8b4685/html5/thumbnails/57.jpg)
Removed variables
• $HTTP_RAW_POST_DATA
• Replace it by php://input
• php://input is now reusable
• Since PHP 5.5
![Page 58: Preparing code for Php 7 workshop](https://reader033.vdocument.in/reader033/viewer/2022050900/588a1bc31a28abb21f8b4685/html5/thumbnails/58.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 59: Preparing code for Php 7 workshop](https://reader033.vdocument.in/reader033/viewer/2022050900/588a1bc31a28abb21f8b4685/html5/thumbnails/59.jpg)
default_charset
• htmlentities()
• PHP 5.3 : ISO-8859-1
• PHP 5.4 : UTF-8
• PHP 5.6 : default_charset (also UTF 8)
![Page 60: Preparing code for Php 7 workshop](https://reader033.vdocument.in/reader033/viewer/2022050900/588a1bc31a28abb21f8b4685/html5/thumbnails/60.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 61: Preparing code for Php 7 workshop](https://reader033.vdocument.in/reader033/viewer/2022050900/588a1bc31a28abb21f8b4685/html5/thumbnails/61.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 62: Preparing code for Php 7 workshop](https://reader033.vdocument.in/reader033/viewer/2022050900/588a1bc31a28abb21f8b4685/html5/thumbnails/62.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 63: Preparing code for Php 7 workshop](https://reader033.vdocument.in/reader033/viewer/2022050900/588a1bc31a28abb21f8b4685/html5/thumbnails/63.jpg)
preg_replace()
<?php
$code = "abcde";
echo preg_replace( array( '/a/', '/b/'), array( 'f' , 'g'), $code);
fgcde
![Page 64: Preparing code for Php 7 workshop](https://reader033.vdocument.in/reader033/viewer/2022050900/588a1bc31a28abb21f8b4685/html5/thumbnails/64.jpg)
mb_eregi?_replace also drops /e in 7.2
<?php
$code = "abcde";
echo preg_replace( array( '/a/', '/b/'), array( 'f' , 'g'), $code);
fgcde
![Page 65: Preparing code for Php 7 workshop](https://reader033.vdocument.in/reader033/viewer/2022050900/588a1bc31a28abb21f8b4685/html5/thumbnails/65.jpg)
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
![Page 66: Preparing code for Php 7 workshop](https://reader033.vdocument.in/reader033/viewer/2022050900/588a1bc31a28abb21f8b4685/html5/thumbnails/66.jpg)
Added features
![Page 67: Preparing code for Php 7 workshop](https://reader033.vdocument.in/reader033/viewer/2022050900/588a1bc31a28abb21f8b4685/html5/thumbnails/67.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 7 2 157.2 0 0 0
Total 766 92 1163
![Page 68: Preparing code for Php 7 workshop](https://reader033.vdocument.in/reader033/viewer/2022050900/588a1bc31a28abb21f8b4685/html5/thumbnails/68.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 69: Preparing code for Php 7 workshop](https://reader033.vdocument.in/reader033/viewer/2022050900/588a1bc31a28abb21f8b4685/html5/thumbnails/69.jpg)
New functions
• intdiv()
• get_resources()
• random_bytes(), random_int()
• error_clear_last()
• gc_mem_caches()
• preg_replace_callback_array()
![Page 70: Preparing code for Php 7 workshop](https://reader033.vdocument.in/reader033/viewer/2022050900/588a1bc31a28abb21f8b4685/html5/thumbnails/70.jpg)
Collaterals
![Page 71: Preparing code for Php 7 workshop](https://reader033.vdocument.in/reader033/viewer/2022050900/588a1bc31a28abb21f8b4685/html5/thumbnails/71.jpg)
Invalid octals are invalid
• Upgraded from silent to Fatal error
PHP Parse error: Invalid numeric literal in test.php
<?php
$x = 0890;
![Page 72: Preparing code for Php 7 workshop](https://reader033.vdocument.in/reader033/viewer/2022050900/588a1bc31a28abb21f8b4685/html5/thumbnails/72.jpg)
More invalid octals in strings
<?php
var_dump("\000" === "\400");
• PHP 7.1
https://wiki.php.net/rfc/octal.overload-checking
![Page 73: Preparing code for Php 7 workshop](https://reader033.vdocument.in/reader033/viewer/2022050900/588a1bc31a28abb21f8b4685/html5/thumbnails/73.jpg)
Invalid numeric are signaledPHP 7.1
Notice: A non well formed numeric value encountered in
<?php
echo "1 monkey" + "2 bananas";
![Page 74: Preparing code for Php 7 workshop](https://reader033.vdocument.in/reader033/viewer/2022050900/588a1bc31a28abb21f8b4685/html5/thumbnails/74.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 75: Preparing code for Php 7 workshop](https://reader033.vdocument.in/reader033/viewer/2022050900/588a1bc31a28abb21f8b4685/html5/thumbnails/75.jpg)
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; } }
![Page 76: Preparing code for Php 7 workshop](https://reader033.vdocument.in/reader033/viewer/2022050900/588a1bc31a28abb21f8b4685/html5/thumbnails/76.jpg)
More strict keywords
• $this is not available anymore
• Not as argument
• Not as variable
• Not as global
• Not as static
• Not as property
• Not as reference
• Not via extract()
<?php
function foo($this) { echo $this; }
![Page 77: Preparing code for Php 7 workshop](https://reader033.vdocument.in/reader033/viewer/2022050900/588a1bc31a28abb21f8b4685/html5/thumbnails/77.jpg)
Strings may be invalid
• Upgraded to Fatal error
<?php
echo "\u{1F418}\n";
> php56 test.php \u{1F418}
> php70 test.php
🐘
<?php
echo "ni\u{119} m\u{f3}wi\u{119} p\u{f3} po\u{142}\u{15b}";
//nię mówię pó połśku
![Page 78: Preparing code for Php 7 workshop](https://reader033.vdocument.in/reader033/viewer/2022050900/588a1bc31a28abb21f8b4685/html5/thumbnails/78.jpg)
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{
![Page 79: Preparing code for Php 7 workshop](https://reader033.vdocument.in/reader033/viewer/2022050900/588a1bc31a28abb21f8b4685/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: Preparing code for Php 7 workshop](https://reader033.vdocument.in/reader033/viewer/2022050900/588a1bc31a28abb21f8b4685/html5/thumbnails/80.jpg)
Warning for strings (7.1)
Upgraded to Fatal error
<?php
print "2" + "4"; print "3 elephpants" + "4 dolphins"; print "2" + "d4 d";
6 7 2
Warning: A non-numeric value encountered
![Page 81: Preparing code for Php 7 workshop](https://reader033.vdocument.in/reader033/viewer/2022050900/588a1bc31a28abb21f8b4685/html5/thumbnails/81.jpg)
Exceptions
• Upgraded to Fatal errorThrowable
Exception
LogicException RuntimeException
BadFunctionCallException
BadMethodCallException
DomainExceptionInvalidArgumentException
OutOfRangeException
OutOfBoundsException
OverflowException
RangeException
Error
ParseErrorDivisionByZeroError
AssertionError
![Page 82: Preparing code for Php 7 workshop](https://reader033.vdocument.in/reader033/viewer/2022050900/588a1bc31a28abb21f8b4685/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: Preparing code for Php 7 workshop](https://reader033.vdocument.in/reader033/viewer/2022050900/588a1bc31a28abb21f8b4685/html5/thumbnails/83.jpg)
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 }
![Page 84: Preparing code for Php 7 workshop](https://reader033.vdocument.in/reader033/viewer/2022050900/588a1bc31a28abb21f8b4685/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: Preparing code for Php 7 workshop](https://reader033.vdocument.in/reader033/viewer/2022050900/588a1bc31a28abb21f8b4685/html5/thumbnails/85.jpg)
And more catching exceptions
Parser errors now throw a ParseError object. Error handling for eval()
<?php
try { $random = random_bytes(10); } catch( TypeError $e) { // invalid parameter } catch( Error $e) { // invalid length } catch( Exception $e) { // no source of randomness }
![Page 86: Preparing code for Php 7 workshop](https://reader033.vdocument.in/reader033/viewer/2022050900/588a1bc31a28abb21f8b4685/html5/thumbnails/86.jpg)
Even more catching exceptions
<?php
try { attemptSomething(); } catch (RuntimeException $e) { fixSomething(); } catch (InvalidArgumentException $e) { fixSomething(); } catch (BadFunctioncallException $e) { fixSomethingElse(); }
![Page 87: Preparing code for Php 7 workshop](https://reader033.vdocument.in/reader033/viewer/2022050900/588a1bc31a28abb21f8b4685/html5/thumbnails/87.jpg)
Even more catching exceptionsFederate error catching in catch clause
<?php
try { attemptSomething(); } catch (RuntimeException| InvalidArgumentException| BadFunctioncallException $e) { fixSomething(); }
![Page 88: Preparing code for Php 7 workshop](https://reader033.vdocument.in/reader033/viewer/2022050900/588a1bc31a28abb21f8b4685/html5/thumbnails/88.jpg)
Even more catching exceptions
<?php
//try really hardertry { attemptSomething(); } catch (Exception $e) { attemptSomething(); }
![Page 89: Preparing code for Php 7 workshop](https://reader033.vdocument.in/reader033/viewer/2022050900/588a1bc31a28abb21f8b4685/html5/thumbnails/89.jpg)
Negative string offset (7.1)
• Upgraded to Fatal error<?php
$string = "abcde";
print $string[-3];
print "$string[3]";
print "$string[-2]";
c
d
Parse error: syntax error, unexpected '-', expecting identifier (T_STRING) or variable (T_VARIABLE) or number (T_NUM_STRING)
![Page 90: Preparing code for Php 7 workshop](https://reader033.vdocument.in/reader033/viewer/2022050900/588a1bc31a28abb21f8b4685/html5/thumbnails/90.jpg)
PHP 7.1 : list() with keys =>
<?php $array = ['a' => 1, 'b' => 5, 'c' => 3];
// Assigns to $a, $b and $c in the same orderlist($a, $b, $c) = $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: Preparing code for Php 7 workshop](https://reader033.vdocument.in/reader033/viewer/2022050900/588a1bc31a28abb21f8b4685/html5/thumbnails/91.jpg)
Short syntax for list()
<?php
$array = ['a' => 1, 'b' => 5, 'c' => 3];
["a" => $a, "b" => $b, "c" => $c] = $array;
// Works even when nested$array = [['a' => 1, 'b' => 5], ['c' => 3]];
[["a" => $a, "b" => $b], ["c" => $c]] = $array;
![Page 92: Preparing code for Php 7 workshop](https://reader033.vdocument.in/reader033/viewer/2022050900/588a1bc31a28abb21f8b4685/html5/thumbnails/92.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 93: Preparing code for Php 7 workshop](https://reader033.vdocument.in/reader033/viewer/2022050900/588a1bc31a28abb21f8b4685/html5/thumbnails/93.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 94: Preparing code for Php 7 workshop](https://reader033.vdocument.in/reader033/viewer/2022050900/588a1bc31a28abb21f8b4685/html5/thumbnails/94.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 95: Preparing code for Php 7 workshop](https://reader033.vdocument.in/reader033/viewer/2022050900/588a1bc31a28abb21f8b4685/html5/thumbnails/95.jpg)
Changed behavior
![Page 96: Preparing code for Php 7 workshop](https://reader033.vdocument.in/reader033/viewer/2022050900/588a1bc31a28abb21f8b4685/html5/thumbnails/96.jpg)
Changed behavior
• Indirect expressions
![Page 97: Preparing code for Php 7 workshop](https://reader033.vdocument.in/reader033/viewer/2022050900/588a1bc31a28abb21f8b4685/html5/thumbnails/97.jpg)
func_get_arg()
• func_get_arg() and func_get_args() now return 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 98: Preparing code for Php 7 workshop](https://reader033.vdocument.in/reader033/viewer/2022050900/588a1bc31a28abb21f8b4685/html5/thumbnails/98.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 99: Preparing code for Php 7 workshop](https://reader033.vdocument.in/reader033/viewer/2022050900/588a1bc31a28abb21f8b4685/html5/thumbnails/99.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 100: Preparing code for Php 7 workshop](https://reader033.vdocument.in/reader033/viewer/2022050900/588a1bc31a28abb21f8b4685/html5/thumbnails/100.jpg)
New features
![Page 101: Preparing code for Php 7 workshop](https://reader033.vdocument.in/reader033/viewer/2022050900/588a1bc31a28abb21f8b4685/html5/thumbnails/101.jpg)
New features
• Breaks backward compatibility sometimes
• FUD
• Search for places to apply them like for incompatibilities
![Page 102: Preparing code for Php 7 workshop](https://reader033.vdocument.in/reader033/viewer/2022050900/588a1bc31a28abb21f8b4685/html5/thumbnails/102.jpg)
New features
• Fixing
• Modernization
• New features
![Page 103: Preparing code for Php 7 workshop](https://reader033.vdocument.in/reader033/viewer/2022050900/588a1bc31a28abb21f8b4685/html5/thumbnails/103.jpg)
Fixing
![Page 104: Preparing code for Php 7 workshop](https://reader033.vdocument.in/reader033/viewer/2022050900/588a1bc31a28abb21f8b4685/html5/thumbnails/104.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 105: Preparing code for Php 7 workshop](https://reader033.vdocument.in/reader033/viewer/2022050900/588a1bc31a28abb21f8b4685/html5/thumbnails/105.jpg)
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]); } }
![Page 106: Preparing code for Php 7 workshop](https://reader033.vdocument.in/reader033/viewer/2022050900/588a1bc31a28abb21f8b4685/html5/thumbnails/106.jpg)
Modernization
![Page 107: Preparing code for Php 7 workshop](https://reader033.vdocument.in/reader033/viewer/2022050900/588a1bc31a28abb21f8b4685/html5/thumbnails/107.jpg)
Foreach update the actual array
<?php
$array = [0]; foreach ($array as $k => &$val) { print "$k\n"; $array[] = 1; } ?>
0 1 2 3 4 5 6 7 8 9 10 11
0
PHP 5 PHP 7
![Page 108: Preparing code for Php 7 workshop](https://reader033.vdocument.in/reader033/viewer/2022050900/588a1bc31a28abb21f8b4685/html5/thumbnails/108.jpg)
Closure binding
• Code automation
• Keep it simple
• Won’t accept functioncalls
• Won't accept variables
<?php class Hello { private $hello = "Hello";
function makeClosure() { return function() { echo $this->hello; }; }
$obj = new Hello(); $closure = $obj->makeClosure(); $closure();
![Page 109: Preparing code for Php 7 workshop](https://reader033.vdocument.in/reader033/viewer/2022050900/588a1bc31a28abb21f8b4685/html5/thumbnails/109.jpg)
Closure binding
• Code automation
• Keep it simple
• Won’t accept functioncalls
• Won't accept variables
<?php
class {
private $hello = " ";
}
$obj = new Hello(); $closure = $obj->makeClosure();
$nihao = new ();
$closure2 = $closure->bindTo($nihao); $closure2();
![Page 110: Preparing code for Php 7 workshop](https://reader033.vdocument.in/reader033/viewer/2022050900/588a1bc31a28abb21f8b4685/html5/thumbnails/110.jpg)
Closure binding
• Code automation
• Keep it simple
• Won’t accept functioncalls
• Won't accept variables
<?php
$closure = function() { echo $this->hello; };
class {
private $hello = " ";
}
$nihao = new ();
$closure->call($nihao);
![Page 111: Preparing code for Php 7 workshop](https://reader033.vdocument.in/reader033/viewer/2022050900/588a1bc31a28abb21f8b4685/html5/thumbnails/111.jpg)
session_start($options)
<?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 112: Preparing code for Php 7 workshop](https://reader033.vdocument.in/reader033/viewer/2022050900/588a1bc31a28abb21f8b4685/html5/thumbnails/112.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 113: Preparing code for Php 7 workshop](https://reader033.vdocument.in/reader033/viewer/2022050900/588a1bc31a28abb21f8b4685/html5/thumbnails/113.jpg)
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
![Page 114: Preparing code for Php 7 workshop](https://reader033.vdocument.in/reader033/viewer/2022050900/588a1bc31a28abb21f8b4685/html5/thumbnails/114.jpg)
Really new
![Page 115: Preparing code for Php 7 workshop](https://reader033.vdocument.in/reader033/viewer/2022050900/588a1bc31a28abb21f8b4685/html5/thumbnails/115.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 116: Preparing code for Php 7 workshop](https://reader033.vdocument.in/reader033/viewer/2022050900/588a1bc31a28abb21f8b4685/html5/thumbnails/116.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 117: Preparing code for Php 7 workshop](https://reader033.vdocument.in/reader033/viewer/2022050900/588a1bc31a28abb21f8b4685/html5/thumbnails/117.jpg)
Generators delegation
<?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 118: Preparing code for Php 7 workshop](https://reader033.vdocument.in/reader033/viewer/2022050900/588a1bc31a28abb21f8b4685/html5/thumbnails/118.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 119: Preparing code for Php 7 workshop](https://reader033.vdocument.in/reader033/viewer/2022050900/588a1bc31a28abb21f8b4685/html5/thumbnails/119.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 120: Preparing code for Php 7 workshop](https://reader033.vdocument.in/reader033/viewer/2022050900/588a1bc31a28abb21f8b4685/html5/thumbnails/120.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 121: Preparing code for Php 7 workshop](https://reader033.vdocument.in/reader033/viewer/2022050900/588a1bc31a28abb21f8b4685/html5/thumbnails/121.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 122: Preparing code for Php 7 workshop](https://reader033.vdocument.in/reader033/viewer/2022050900/588a1bc31a28abb21f8b4685/html5/thumbnails/122.jpg)
Return type hint
<?php
function getData($login) : user { if (userExists($login)) { return userDetails($login); } else { return null; } }
• scalar, array, callable, class or interfaces
void (PHP 7.1)
![Page 123: Preparing code for Php 7 workshop](https://reader033.vdocument.in/reader033/viewer/2022050900/588a1bc31a28abb21f8b4685/html5/thumbnails/123.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 124: Preparing code for Php 7 workshop](https://reader033.vdocument.in/reader033/viewer/2022050900/588a1bc31a28abb21f8b4685/html5/thumbnails/124.jpg)
Minimum args in custom functions is Fatal error
scalar, array, callable, class or interfaces
void (PHP 7.1)
<?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 125: Preparing code for Php 7 workshop](https://reader033.vdocument.in/reader033/viewer/2022050900/588a1bc31a28abb21f8b4685/html5/thumbnails/125.jpg)
Omitted
• Assertions
• Grouped assertions
• opening tags that were dropped
![Page 126: Preparing code for Php 7 workshop](https://reader033.vdocument.in/reader033/viewer/2022050900/588a1bc31a28abb21f8b4685/html5/thumbnails/126.jpg)
Summary
• Check the manuals
• PHP lint is your friend
• Search in the code
• Use static analysis tools
![Page 127: Preparing code for Php 7 workshop](https://reader033.vdocument.in/reader033/viewer/2022050900/588a1bc31a28abb21f8b4685/html5/thumbnails/127.jpg)
Thank you! Damien Seguy @exakat [email protected] https://www.exakat.io/
![Page 128: Preparing code for Php 7 workshop](https://reader033.vdocument.in/reader033/viewer/2022050900/588a1bc31a28abb21f8b4685/html5/thumbnails/128.jpg)
The end