php 7 compliance workshop singapore

126
PHP 7.1 compliance workshop Damien Seguy @exakat Singapore, August 2016

Upload: damien-seguy-

Post on 13-Apr-2017

217 views

Category:

Technology


1 download

TRANSCRIPT

Page 1: Php 7 compliance workshop singapore

PHP 7.1 compliance workshop

Damien Seguy @exakat Singapore, August 2016

Page 2: Php 7 compliance workshop singapore

Full ahead to PHP 7. 1

Changing version is always a big challenge

Backward incompatibilities

New features

Learn, spot, fix, repeat

0

Page 3: Php 7 compliance workshop singapore

Speaker

Damien Seguy

CTO at exakat

Static code analysis for PHP

Page 4: Php 7 compliance workshop singapore

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 compliance workshop singapore

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: Php 7 compliance workshop singapore

Destination

Page 7: Php 7 compliance workshop singapore

Living on the edgehttp://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: Php 7 compliance workshop singapore

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 compliance workshop singapore
Page 10: Php 7 compliance workshop singapore
Page 11: Php 7 compliance workshop singapore
Page 12: Php 7 compliance workshop singapore
Page 13: Php 7 compliance workshop singapore
Page 14: Php 7 compliance workshop singapore

PHP has 3 phases

syntax

definitions

execution

Where does code break?

Checked with phplint

Checked with tests

Checked code review

Page 15: Php 7 compliance workshop singapore

<?php

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

?>

Where will code break?

SyntaxDefinitionsExecution

Page 16: Php 7 compliance workshop singapore

Tools for migration

• Your own experience with your code

• Lint

• Search

• Static analysis

• Logs

Page 17: Php 7 compliance workshop singapore

Linting PHP 7

Page 18: Php 7 compliance workshop singapore

PHP linting

• command line : php -l filename.php

• Spot parse errors

• Works on files only :

• For directories, see composer phplint/phplint

Page 19: Php 7 compliance workshop singapore

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: Php 7 compliance workshop singapore

Backward unlintable code

Page 21: Php 7 compliance workshop singapore

Code focused on current versions

Page 22: Php 7 compliance workshop singapore

Backward unlintable code

Page 23: Php 7 compliance workshop singapore

Redefinition of parameter

<?php

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

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

?>

Page 24: Php 7 compliance workshop singapore

Switch statements may only contain one default clause

<?php   

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

Page 25: Php 7 compliance workshop singapore

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: Php 7 compliance workshop singapore

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: Php 7 compliance workshop singapore

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: Php 7 compliance workshop singapore

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: Php 7 compliance workshop singapore

PHP 7 linting

Pre-commit

Use different versions

Be ruthless with unlintable files

Page 30: Php 7 compliance workshop singapore

PHP has 3 phases

syntax

definitions

execution

Where does code break?

Checked with phplint

Checked with tests

Checked code review

Page 31: Php 7 compliance workshop singapore

Static analysis

Page 32: Php 7 compliance workshop singapore

Presentation

Review code without executing it

Common in C/C++, Java, Javascript

Hot subject coming to PHP

Page 33: Php 7 compliance workshop singapore

GREP/SEARCH

Any searching facility

Pro : High speed, great for keyword search, universal

Cons : Little repeat value, no PHP semantics

Page 34: Php 7 compliance workshop singapore

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: Php 7 compliance workshop singapore

Static analysis

PHP 5 / 7 Calisthenics ClearPHP

Performance

Page 36: Php 7 compliance workshop singapore

Static analysis tools

PHP7mar

PHP7cc

Phan

Exakat

PHP inspections

Page 37: Php 7 compliance workshop singapore

PHP7mar

PHP 7 Migration Assistant Report (MAR)

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

Works with regex

Produces a .md file

Page 38: Php 7 compliance workshop singapore

12 results

Page 39: Php 7 compliance workshop singapore

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: Php 7 compliance workshop singapore

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: Php 7 compliance workshop singapore

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: Php 7 compliance workshop singapore
Page 43: Php 7 compliance workshop singapore

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 44: Php 7 compliance workshop singapore

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: Php 7 compliance workshop singapore

20 mins6798 results250 analysis

Page 46: Php 7 compliance workshop singapore

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: Php 7 compliance workshop singapore
Page 48: Php 7 compliance workshop singapore

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: Php 7 compliance workshop singapore

PHP 7.1 : what changes?

Incompatible changes

New features

Features/Incompatibilities from PHP 5.6 => 7.2

Page 50: Php 7 compliance workshop singapore

How to spot issues?Code knowledge

lint

Grep / Search

Static analysis

Logs / error_reporting

Unit Tests

What to replace them with ?

Page 51: Php 7 compliance workshop singapore

Incompatibilities

Page 52: Php 7 compliance workshop singapore

Incompatibilities

Removed features

Added features

Collateral damages

Page 53: Php 7 compliance workshop singapore

Removed features

Page 54: Php 7 compliance workshop singapore

Removed extensionsExtensions

ereg

mssql

mysql

sybase_ct

mycrypt (7.1)

Page 55: Php 7 compliance workshop singapore

Removed extensions

ext/ereg

ereg

ereg_replace

split

sql_regcase

Page 56: Php 7 compliance workshop singapore

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: Php 7 compliance workshop singapore

Removed variables

$HTTP_RAW_POST_DATA

Replace it by php://input

php://input is now reusable

Since PHP 5.5

Page 58: Php 7 compliance workshop singapore

Removed INIsql.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: Php 7 compliance workshop singapore

default_charset

htmlentities()

PHP 5.3 : ISO-8859-1

PHP 5.4 : UTF-8

PHP 5.6 : default_charset (also UTF 8)

Page 60: Php 7 compliance workshop singapore

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: Php 7 compliance workshop singapore

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: Php 7 compliance workshop singapore

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: Php 7 compliance workshop singapore

preg_replace()

<?php  

$code = "abcde"; 

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

fgcde

Page 64: Php 7 compliance workshop singapore

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 65: Php 7 compliance workshop singapore

Added features

Page 66: Php 7 compliance workshop singapore

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 67: Php 7 compliance workshop singapore

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 68: Php 7 compliance workshop singapore

New functionsintdiv()

get_resources()

random_bytes(), random_int()

error_clear_last()

gc_mem_caches()

preg_replace_callback_array()

Page 69: Php 7 compliance workshop singapore

Collaterals

Page 70: Php 7 compliance workshop singapore

Invalid octals are invalid

Upgraded from silent to Fatal error

PHP Parse error: Invalid numeric literal in test.php

<?php 

$x = 0890;

Page 71: Php 7 compliance workshop singapore

More invalid octals in strings

<?php  

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

PHP 7.1

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

Page 72: Php 7 compliance workshop singapore

Invalid numeric are signaled

PHP 7.1

Notice: A non well formed numeric value encountered in

<?php

echo "1 monkey" + "2 bananas";

Page 73: Php 7 compliance workshop singapore

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 74: Php 7 compliance workshop singapore

More relaxed keywordsAlmost 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 75: Php 7 compliance workshop singapore

Upgraded to Fatal error

Strings may be invalid<?php 

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

> php56 test.php \u{1F418}

> php70 test.php

🐘

<?php 

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

Page 76: Php 7 compliance workshop singapore

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 77: Php 7 compliance workshop singapore

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 78: Php 7 compliance workshop singapore

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 79: Php 7 compliance workshop singapore

Exceptions

Upgraded to Fatal error

Throwable

Exception

LogicException RuntimeException

BadFunctionCallException

BadMethodCallException

DomainExceptionInvalidArgumentException

OutOfRangeException

OutOfBoundsException

OverflowException

RangeException

Error

ParseErrorDivisionByZeroError

AssertionError

Page 80: Php 7 compliance workshop singapore

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 81: Php 7 compliance workshop singapore

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 82: Php 7 compliance workshop singapore

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 83: Php 7 compliance workshop singapore

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 84: Php 7 compliance workshop singapore

Even more catching exceptions

<?php

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

Page 85: Php 7 compliance workshop singapore

Even more catching exceptions

<?php

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

Page 86: Php 7 compliance workshop singapore

Even more catching exceptions

<?php

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

Page 87: Php 7 compliance workshop singapore

Negative string offset (7.1)<?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 88: Php 7 compliance workshop singapore

list() with keys => (7.1)<?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 89: Php 7 compliance workshop singapore

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 90: Php 7 compliance workshop singapore

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 91: Php 7 compliance workshop singapore

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 92: Php 7 compliance workshop singapore

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 93: Php 7 compliance workshop singapore

Changed behavior

Page 94: Php 7 compliance workshop singapore

Changed behavior

Indirect expressions

Page 95: Php 7 compliance workshop singapore

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 96: Php 7 compliance workshop singapore

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 97: Php 7 compliance workshop singapore

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 98: Php 7 compliance workshop singapore

New features

Page 99: Php 7 compliance workshop singapore

New features

Breaks backward compatibility sometimes

FUD

Search for places to apply them like for incompatibilities

Page 100: Php 7 compliance workshop singapore

New features

Fixing

Modernization

New features

Page 101: Php 7 compliance workshop singapore

Fixing

Page 102: Php 7 compliance workshop singapore

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 103: Php 7 compliance workshop singapore

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 104: Php 7 compliance workshop singapore

Modernization

Page 105: Php 7 compliance workshop singapore

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 106: Php 7 compliance workshop singapore

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 107: Php 7 compliance workshop singapore

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 108: Php 7 compliance workshop singapore

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 109: Php 7 compliance workshop singapore

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 110: Php 7 compliance workshop singapore

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 111: Php 7 compliance workshop singapore

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 112: Php 7 compliance workshop singapore

Really new

Page 113: Php 7 compliance workshop singapore

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 114: Php 7 compliance workshop singapore

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 115: Php 7 compliance workshop singapore

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 116: Php 7 compliance workshop singapore

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 117: Php 7 compliance workshop singapore

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 118: Php 7 compliance workshop singapore

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 119: Php 7 compliance workshop singapore

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 120: Php 7 compliance workshop singapore

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 121: Php 7 compliance workshop singapore

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 122: Php 7 compliance workshop singapore

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 123: Php 7 compliance workshop singapore

Omitted

Assertions

Grouped assertions

opening tags that were dropped

Page 124: Php 7 compliance workshop singapore

Summary

Check the manuals

PHP lint is your friend

Search in the code

Use static analysis tools

Page 125: Php 7 compliance workshop singapore

Thank you!Damien Seguy @exakat [email protected]

https://www.exakat.io/

Page 126: Php 7 compliance workshop singapore

The end