php 7.2 compliance workshop php benelux

135
PHP 7.2 COMPLIANCE WORKSHOP Damien Seguy @exakat Antwerp, January 2017

Upload: damien-seguy-

Post on 08-Feb-2017

204 views

Category:

Technology


4 download

TRANSCRIPT

Page 1: Php 7.2 compliance workshop php benelux

PHP 7.2 COMPLIANCE WORKSHOP

Damien Seguy @exakat Antwerp, January 2017

Page 2: Php 7.2 compliance workshop php benelux

FULL AHEAD TO PHP 7. 2

Changing version is always a big challenge

Backward incompatibilities

New features

Learn, spot, fix, repeat

01

Page 3: Php 7.2 compliance workshop php benelux

SPEAKER

Damien Seguy

CTO at exakat

Static code analysis for PHP

Retiring house for oldest elephpant

Page 4: Php 7.2 compliance workshop php benelux

SYNOPSIS

What is in the next version ?

Where in my code ?

How to replace this ?

Get documentation

Find issue

Fix code

Page 5: Php 7.2 compliance workshop php benelux

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: Php 7.2 compliance workshop php benelux

DESTINATION

Page 7: Php 7.2 compliance workshop php benelux

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: Php 7.2 compliance workshop php benelux

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: Php 7.2 compliance workshop php benelux
Page 10: Php 7.2 compliance workshop php benelux
Page 11: Php 7.2 compliance workshop php benelux
Page 12: Php 7.2 compliance workshop php benelux

64 opened discussions

4 opened votes

Page 13: Php 7.2 compliance workshop php benelux
Page 14: Php 7.2 compliance workshop php benelux

WHICH TO BELIEVE

Books

PHP manual Migration, blogs

Wiki (Implemented)

NEWS

Bugs

Wiki (Future)

Yearly

Monthly

Weekly

As possible

As needed

Page 15: Php 7.2 compliance workshop php benelux

PHP has 3 phases

syntax

definitions

execution

WHERE DOES CODE BREAK?

Checked with phplint

Checked with tests

Checked code review

Page 16: Php 7.2 compliance workshop php benelux

<?php

function splitNames($fullname, $fullname) {    list($first, $last) = split($fullname, ' '); }

?>

WHERE WILL CODE BREAK?

SyntaxDefinitionsExecution

Page 17: Php 7.2 compliance workshop php benelux

TOOLS FOR MIGRATION

• Your own experience with your code

• Lint

• Search

• Static analysis

• Logs

Page 18: Php 7.2 compliance workshop php benelux

LINTING PHP 7

Page 19: Php 7.2 compliance workshop php benelux

PHP LINTING

• command line : php -l filename.php

• Spot parse errors

• Works on files only :

• For directories, see composer phplint/phplint

Page 20: Php 7.2 compliance workshop php benelux

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: Php 7.2 compliance workshop php benelux

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: Php 7.2 compliance workshop php benelux

Code focused on current versions

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: Php 7.2 compliance workshop php benelux

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: Php 7.2 compliance workshop php benelux

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: Php 7.2 compliance workshop php benelux

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: Php 7.2 compliance workshop php benelux

REDEFINITION OF PARAMETER

<?php

function foo($a, $a, $a) {   print $a."\n"; }

foo('x', 'y', 'z');

?>

Page 27: Php 7.2 compliance workshop php benelux

SWITCH STATEMENTS MAY ONLY CONTAIN ONE DEFAULT CLAUSE

<?php   

switch($x) {        case '1' :             break;        default :             break;        default :             break;        case '2' :             break;    }   

Page 28: Php 7.2 compliance workshop php benelux

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: Php 7.2 compliance workshop php benelux

DEPRECATED FEATURES

Not happening if a parent case has a __constructor()

Not happening if the class is in a namespaceUse 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: Php 7.2 compliance workshop php benelux

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 31: Php 7.2 compliance workshop php benelux

PHP 7 LINTING

Pre-commit

Use different versions

Be ruthless with unlintable files

Page 32: Php 7.2 compliance workshop php benelux

PHP has 3 phases

syntax

definitions

execution

WHERE DOES CODE BREAK?

Checked with phplint

Checked with tests

Checked code review

Page 33: Php 7.2 compliance workshop php benelux

STATIC ANALYSIS

Page 34: Php 7.2 compliance workshop php benelux

DEFINITION

Review code without executing it

Audit code by reading it

Common in C/C++, Java, Javascript

Hot subject to PHP

Page 35: Php 7.2 compliance workshop php benelux

GREP/SEARCH

Any searching facility

Pro : High speed, great for keyword search, universal

Cons : Little repeat value, no PHP semantics

Page 36: Php 7.2 compliance workshop php benelux

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: Php 7.2 compliance workshop php benelux

STATIC ANALYSIS

PHP 5 / 7 Calisthenics ClearPHP

Performance

Page 38: Php 7.2 compliance workshop php benelux

STATIC ANALYSIS TOOLS

PHP7mar

PHP7cc

Phan

Exakat

PHP inspections

Page 39: Php 7.2 compliance workshop php benelux

PHP7MAR

PHP 7 Migration Assistant Report (MAR)

Alexia : https://github.com/Alexia/php7mar

Works with regex

Produces a .md file

Page 40: Php 7.2 compliance workshop php benelux

12 results

Page 41: Php 7.2 compliance workshop php benelux

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: Php 7.2 compliance workshop php benelux

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: Php 7.2 compliance workshop php benelux

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: Php 7.2 compliance workshop php benelux
Page 45: Php 7.2 compliance workshop php benelux

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: Php 7.2 compliance workshop php benelux

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: Php 7.2 compliance workshop php benelux

20 mins6798 results290 analysis

Page 48: Php 7.2 compliance workshop php benelux

20 mins6798 results290 analysis

Page 49: Php 7.2 compliance workshop php benelux

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: Php 7.2 compliance workshop php benelux
Page 51: Php 7.2 compliance workshop php benelux

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: Php 7.2 compliance workshop php benelux

PHP 7.1 : WHAT CHANGES?

Incompatible changes

New features

Features/Incompatibilities from PHP 5.6 => 7.2

Page 53: Php 7.2 compliance workshop php benelux

HOW TO SPOT ISSUES?

Code knowledge

lint

Grep / Search

Static analysis

Logs / error_reporting

Unit Tests

Page 54: Php 7.2 compliance workshop php benelux

INCOMPATIBILITIES

Page 55: Php 7.2 compliance workshop php benelux

INCOMPATIBILITIES

Removed features

Added features

Collateral damages

Page 56: Php 7.2 compliance workshop php benelux

REMOVED FEATURES

Page 57: Php 7.2 compliance workshop php benelux

REMOVED EXTENSIONS

Extensions

ereg

mssql

mysql

sybase_ct

mcrypt 7.2

Page 58: Php 7.2 compliance workshop php benelux

REMOVED EXTENSIONS

ext/ereg

ereg

ereg_replace

split

sql_regcase

Page 59: Php 7.2 compliance workshop php benelux

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

Page 60: Php 7.2 compliance workshop php benelux

REMOVED VARIABLES

$HTTP_RAW_POST_DATA

Replace it by php://input

php://input is now reusable

Since PHP 5.5

Page 61: Php 7.2 compliance workshop php benelux

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: Php 7.2 compliance workshop php benelux

DEFAULT_CHARSET

htmlentities()

PHP 5.3 : ISO-8859-1

PHP 5.4 : UTF-8

PHP 5.6 : default_charset (also UTF 8)

Page 63: Php 7.2 compliance workshop php benelux

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: Php 7.2 compliance workshop php benelux

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: Php 7.2 compliance workshop php benelux

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: Php 7.2 compliance workshop php benelux

PREG_REPLACE()

<?php  

$code = "abcde"; 

echo preg_replace(      array( '/a/', '/b/'),      array( 'f' , 'g'),     $code);

fgcde

Page 67: Php 7.2 compliance workshop php benelux

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: Php 7.2 compliance workshop php benelux

ADDED FEATURES

Page 69: Php 7.2 compliance workshop php benelux

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: Php 7.2 compliance workshop php benelux

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: Php 7.2 compliance workshop php benelux

NEW FUNCTIONS

intdiv()

get_resources()

random_bytes(), random_int()

error_clear_last()

gc_mem_caches()

preg_replace_callback_array()

socket_getaddrinfo()

Page 72: Php 7.2 compliance workshop php benelux

COLLATERALS

Page 73: Php 7.2 compliance workshop php benelux

INVALID OCTALS ARE INVALID

Upgraded from silent to Fatal error

PHP Parse error: Invalid numeric literal in test.php

<?php 

$x = 0890;

Page 74: Php 7.2 compliance workshop php benelux

MORE INVALID OCTALS IN STRINGS

<?php  

var_dump("\000" === "\400");

PHP 7.1

https://wiki.php.net/rfc/octal.overload-checking

Page 75: Php 7.2 compliance workshop php benelux

Invalid numeric are signaled

PHP 7.1

Notice: A non well formed numeric value encountered in

<?php

echo "1 monkey" + "2 bananas";

Page 76: Php 7.2 compliance workshop php benelux

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 77: Php 7.2 compliance workshop php benelux

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 78: Php 7.2 compliance workshop php benelux

STRINGS MAY BE INVALID

Upgraded to Fatal error

<?php 

echo "\u{1F418}\n";

> php56 test.php \u{1F418}

> php70 test.php

🐘

<?php 

echo "\u{65B0}\u{52A0}\u{5761}\n"; //

Page 79: Php 7.2 compliance workshop php benelux

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 80: Php 7.2 compliance workshop php benelux

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 81: Php 7.2 compliance workshop php benelux

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 82: Php 7.2 compliance workshop php benelux

EXCEPTIONS

Throwable

Exception

LogicException RuntimeException

BadFunctionCallException

BadMethodCallException

DomainExceptionInvalidArgumentException

OutOfRangeException

OutOfBoundsException

OverflowException

RangeException

Error

ParseErrorDivisionByZeroError

AssertionError

Page 83: Php 7.2 compliance workshop php benelux

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 84: Php 7.2 compliance workshop php benelux

MORE CATCHING EXCEPTIONS

<?php

try {   eval($somePHPcode); } catch( ParseError $e) {    log($e->getMessage());   // attempt to fix this or error handling }

Page 85: Php 7.2 compliance workshop php benelux

MORE CATCHING EXCEPTIONS

<?php 

try {    $file = new finfo(FILEINFO_NONE,$magic_file);  } catch( ParseError $e) {     log($e->getMessage());    // attempt to fix this or error handling  }

Page 86: Php 7.2 compliance workshop php benelux

AND MORE CATCHING EXCEPTIONS

<?php 

try {    $random = random_bytes(10);   } catch( TypeError $e) {    // invalid parameter } catch( Error $e) {    // invalid length } catch( Exception $e) {    // no source of randomness } 

Page 87: Php 7.2 compliance workshop php benelux

Even more catching exceptions

<?php

try {    attemptSomething(); } catch (RuntimeException $e) {   fixSomething(); } catch (InvalidArgumentException $e) {   fixSomething(); } catch (BadFunctioncallException $e) {   fixSomethingElse(); } 

Page 88: Php 7.2 compliance workshop php benelux

Even more catching exceptions

<?php

try {    attemptSomething(); } catch (RuntimeException|  InvalidArgumentException|  BadFunctioncallException $e) {   fixSomething(); } 

Page 89: Php 7.2 compliance workshop php benelux

Even more catching exceptions

<?php

//try really hardertry {    attemptSomething(); } catch (Exception $e) {    attemptSomething(); } 

Page 90: Php 7.2 compliance workshop php benelux

NEGATIVE STRING OFFSET (7.1)

<?php  

$string = "abcde";

print $string[-3];

print "$string[3]";

print "$string[-2]";

c

d

d

Page 91: Php 7.2 compliance workshop php benelux

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 92: Php 7.2 compliance workshop php benelux

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 93: Php 7.2 compliance workshop php benelux

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: Php 7.2 compliance workshop php benelux

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: Php 7.2 compliance workshop php benelux

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: Php 7.2 compliance workshop php benelux

CHANGED BEHAVIOR

Page 97: Php 7.2 compliance workshop php benelux

CHANGED BEHAVIOR

Indirect expressions

Page 98: Php 7.2 compliance workshop php benelux

FUNC_GET_ARG()

<?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 99: Php 7.2 compliance workshop php benelux

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 100: Php 7.2 compliance workshop php benelux

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 101: Php 7.2 compliance workshop php benelux

NEW FEATURES

Page 102: Php 7.2 compliance workshop php benelux

NEW FEATURES

Breaks backward compatibility sometimes

FUD

Search for places to apply them like for incompatibilities

Page 103: Php 7.2 compliance workshop php benelux

NEW FEATURES

Fixing

Modernization

New features

Page 104: Php 7.2 compliance workshop php benelux

FIXING

Page 105: Php 7.2 compliance workshop php benelux

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 106: Php 7.2 compliance workshop php benelux

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 107: Php 7.2 compliance workshop php benelux

MODERNIZATION

Page 108: Php 7.2 compliance workshop php benelux

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

Page 109: Php 7.2 compliance workshop php benelux

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"}; 

Page 110: Php 7.2 compliance workshop php benelux

WARN WITH COUNT()

<?php function handle_records(iterable $iterable) {     if (count($iterable) === 0) {         return handle_empty();     }       foreach ($iterable as $value) {         handle_value($value);     } }

Page 111: Php 7.2 compliance workshop php benelux

CLOSURE BINDING

<?php class Hello {   private $hello = "Hello";

  function makeClosure() {    return function() {     echo $this->hello;   }; }

$obj = new Hello(); $closure = $obj->makeClosure(); $closure();

Page 112: Php 7.2 compliance workshop php benelux

CLOSURE BINDING

<?php

class   {

  private $hello = " ";

}

$obj = new Hello(); $closure = $obj->makeClosure();

$nihao = new  ();

$closure2 = $closure->bindTo($nihao); $closure2();

Page 113: Php 7.2 compliance workshop php benelux

CLOSURE BINDING

<?php

$closure = function() {     echo $this->hello; };

class   {

  private $hello = " ";

}

$nihao = new  ();

$closure->call($nihao);

Page 114: Php 7.2 compliance workshop php benelux

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 115: Php 7.2 compliance workshop php benelux

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 116: Php 7.2 compliance workshop php benelux

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 117: Php 7.2 compliance workshop php benelux

REALLY NEW

Page 118: Php 7.2 compliance workshop php benelux

NULL-COALESCE

<?php 

// PHP 5.6 $x = $_GET['x'] === null ? 'default' : $_GET['x'];

// PHP 7.0 $x = $_GET['x'] ?? 'default';

?>

Page 119: Php 7.2 compliance workshop php benelux

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 120: Php 7.2 compliance workshop php benelux

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 121: Php 7.2 compliance workshop php benelux

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 122: Php 7.2 compliance workshop php benelux

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 123: Php 7.2 compliance workshop php benelux

SCALAR TYPEHINT BACK IN 5.6

<?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 124: Php 7.2 compliance workshop php benelux

VARIOUS SCALAR TYPEHINT

<?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 125: Php 7.2 compliance workshop php benelux

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 126: Php 7.2 compliance workshop php benelux

RETURN TYPE HINT

<?php

function getData($login) : user {    if (userExists($login)) {      return userDetails($login);    } else {      return null;   } }

Page 127: Php 7.2 compliance workshop php benelux

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 128: Php 7.2 compliance workshop php benelux

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 129: Php 7.2 compliance workshop php benelux

HELPING AT MIGRATION

Backward incompatibilities

Removed / renamed features

Collaterals

Changed behaviors

Page 130: Php 7.2 compliance workshop php benelux

HELPING AT MIGRATION

New features

Fixing

Totally new

Spot previous work-arounds

Page 131: Php 7.2 compliance workshop php benelux
Page 132: Php 7.2 compliance workshop php benelux
Page 133: Php 7.2 compliance workshop php benelux

SUMMARY

Check the manuals

PHP lint is your friend

Search in the code

Use static analysis tools

Page 134: Php 7.2 compliance workshop php benelux

THANK YOU!Damien Seguy @exakat [email protected]

https://www.exakat.io/

https://joind.in/talk/615d8

Page 135: Php 7.2 compliance workshop php benelux

THE END