Transcript
Page 1: Preparing for the next PHP version (5.6)

Preparing for the next PHP version

Page 2: Preparing for the next PHP version (5.6)

Towards PHP 5.5 and 5.6

• Changing version is often a big challenge

• Backward incompatibilities

• New features

• How to spot them ?

Page 3: Preparing for the next PHP version (5.6)

Speaker

• Damien Seguy

• CTO at exakat

• Phather of the plush toy elePHPant

• Will talk on automated code audit later

Page 4: Preparing for the next PHP version (5.6)

PHP linting

• command line : php -l filename.php

• Will only parse the code,

• not execution

• Will spot compilation problems

Page 5: Preparing for the next PHP version (5.6)
Page 6: Preparing for the next PHP version (5.6)

PHP lint will find

• Short array syntax

• Function subscripting

• break/continue with variables

• Rare other situations

• Code that won’t compile anyway

Page 7: Preparing for the next PHP version (5.6)

Where else code will break?

• PHP running has 3 stages

• parsed

• compiled

• executed

Checked with lint

Checked with data and UT

Checked code review

Page 8: Preparing for the next PHP version (5.6)

What will change?

• Removed features

• Deprecated features

• Changed features

• New features

Page 9: Preparing for the next PHP version (5.6)

Deprecated features• PHP 5.6

• $HTTP_RAW_POST_DATA

• Call From Incompatible Context

• iconv and mbstring directives go to default_charset

• PHP 5.5

• /e in preg_replace

• ext/mysql

• mcrypt arguments

5.6

5.5

Page 10: Preparing for the next PHP version (5.6)

Deprecated features• $HTTP_RAW_POST_DATA

• Replace it by php://input

• php://input is now reusable

• ext/mysql

• Look for mysql_* functions

• Probably in Db/Adapter

5.6

5.5

Page 11: Preparing for the next PHP version (5.6)

Search is your friend

• Grep, or IDE’s search function will help you

• Look for mysql_*

• $HTTP_RAW_POST_DATA

Page 12: Preparing for the next PHP version (5.6)

Deprecated: The mysql extension is deprecated and will be removed in

the future: use mysqli or PDO instead in /path/to/filename.php on

line 11

Error_level to E_STRICT

Page 13: Preparing for the next PHP version (5.6)

/e and charset directives

• preg_replace(‘/ /e’, ‘evaled code’, $haystack)

• replaced preg_replace_callback(‘/ /‘, closure, $haystack)

• in php.ini, check for mbstring, iconv and default_charset

5.5

5.6

Page 14: Preparing for the next PHP version (5.6)

Where to look for• preg_replace

• Search for preg_replace function calls

• defaut_charset

• Search for ini_set, ini_get, ini_get_all, ini_restore, get_cfg_var

• Seach in php.ini, .htaccess

Page 15: Preparing for the next PHP version (5.6)

Incompatible context

<?php  class A {       function f() { echo get_class($this); }  }  A::f();  ?>

$ php53 test.php

Notice: Undefined variable: this in test.php on line 3 A

$ php56 test.php

Strict Standards: Non-static method A::f() should not be called statically in /Users/famille/Desktop/test.php on line 6

Notice: Undefined variable: this in test.php on line 3 A

5.6

Page 16: Preparing for the next PHP version (5.6)

Search for situations• Search for :: operator

• Get the class

• then the method

• then the static keyword

• Needs a automated auditing tool

• Code sniffer, IDE

Page 17: Preparing for the next PHP version (5.6)

Strict Standards: Non-static method A::f() should not be called statically in test.php on line 6

Page 18: Preparing for the next PHP version (5.6)

Changed behavior• json_decode is stricter

• it was more tolerant before with TRUE or False values

• gmp resources are object

• and not resources

• search for is_resource()

• mcrypt requires valid keys and vectors

• check correct size and vector presence

• pack and unpack

• More compatible with Perl

• Z and a format code must be checked

5.6

5.5

Page 19: Preparing for the next PHP version (5.6)

Added structures• PHP adds

• constants

• functions

• extensions

• traits

• interfaces

Page 20: Preparing for the next PHP version (5.6)

Added structuresFunctions Classes Constants

5.3 25 18 80

5.4 0 9 78

5.5 113 9 37

5.6 19 0 24

Total 157 36 219

Page 21: Preparing for the next PHP version (5.6)

New features

• Fixing

• Modernization

• New feature

Page 22: Preparing for the next PHP version (5.6)

Fixing

Page 23: Preparing for the next PHP version (5.6)

empty() upgrade

• No need anymore to expressions in a variable for empty()!

Fatal error: Can't use function return value in write context in test.php on line 6

function myFunction() {     return -2 ; }

if (empty(myFunction() + 2)) {     echo "This means 0!\n"; }

5.5

Page 24: Preparing for the next PHP version (5.6)

SELF::const != self::const<?php

class object {     const x = 1;          function x() { print SELF::x."\n"; } }

$object = new object(); $object->x(); ?>

Fatal error: Class 'SELF' not found in test.php on line 6

5.5

Page 25: Preparing for the next PHP version (5.6)

Modernization

Page 26: Preparing for the next PHP version (5.6)

Dereferencing

• Direct access to element in a string or an array.

<?php  /// Function dereferencingecho str_split("123", 1 )[2];  echo "\n"; 

/// Array dereferencingecho [5, 5, 3][0];  echo "\n"; 

/// String dereferencingecho 'PHP'[0];  echo "\n";  ?>5.5

Page 27: Preparing for the next PHP version (5.6)

Power operator

• Replaces pow()

• Be aware of precedence

echo pow(2, 3); 

$a=2;  $a **= 3; 

$a = 2 ** 3; 

5.6

Page 28: Preparing for the next PHP version (5.6)

… Variadic

• replaces func_get_args()

• Easier to read

function array_power($pow, ...$integers) {     foreach($integers as $i) {        print "$i ^ $pow  = ". ($i ** $pow)."\n";     }  }     array_power(3, 1, 2, 3, 4, 5); 

1 ^ 3 = 12 ^ 3 = 83 ^ 3 = 274 ^ 3 = 645 ^ 3 = 125

5.6

Page 29: Preparing for the next PHP version (5.6)

Variadic …• replaces

call_user_func_array

• Easier to read

• Works on functions

• Works with typehint

• Doesn’t work with references

function array_power($pow, ...$integers) {     foreach($integers as $i) {        print "$i ^ $pow  = ". ($i ** $pow)."\n";     }  }     array_power(3, ...range(1, 5));  array_power(3, ...[1, 2, 3, 4, 5]);  array_power(3, ...[1, 2, 3], ...[4, 5]); 

1 ^ 3 = 12 ^ 3 = 83 ^ 3 = 274 ^ 3 = 645 ^ 3 = 125

Page 30: Preparing for the next PHP version (5.6)

Generatorsfunction factors($limit) {     $r = array(2);     for ($i = 3; $i <= $limit; $i += 2) {         $r[] = $i;     }     return $r; }

$prime = 135; foreach (factors(sqrt($prime)) as $n) {     echo "$n ". ($prime % $n ? ' not ' : '') . " factor\n"; }

• $step big => huge memory usage

5.5

Page 31: Preparing for the next PHP version (5.6)

Generators• New yield keyword

• Save memory from n down to 1 value

• Good for long or infinite loops

• Search for range(), for() or loops

function factors($limit) {     yield 2;     for ($i = 3; $i <= $limit; $i += 2) {         yield $i;     } }

$prime = 135; foreach (factors(sqrt($prime)) as $n) {     echo "$n ". ($prime % $n ? ' not ' : '') . " factor\n"; }

Page 32: Preparing for the next PHP version (5.6)

Finallyfunction x() {        $r = new resource();         try {             $result = $r->do();         }         catch (NetworkException $e) {             unset ($r);             throw $e;         }         catch (UnexpectedException $e) {             unset ($r);             throw $e;         }         catch (DaylightSavingException $e) {             unset ($r);             throw $e;         }                  unset ($r);         return $result; }

• Clean up after exception

• What if return in try?

• Move cleaning to __destruct()?

5.5

Page 33: Preparing for the next PHP version (5.6)

Finally

• Clean up after exception or not

• Clean up even when return too early

function x() {        $r = new resource();         try {             $result = $r->do();         }         catch (NetworkException $e) {

       throw $e;}

        catch (UnexpectedException $e) {             throw $e;         }         catch (DaylightSavingException $e) {

// just ignore this one} finally { unset ($r) ;}

                return $result; }

Page 34: Preparing for the next PHP version (5.6)

Really new

Page 35: Preparing for the next PHP version (5.6)

Class name resolution

<?php namespace Name\Space; class ClassName {}

echo ClassName::class;

echo "\n"; ?>

• Get the full name of a class with ::class

5.5

Page 36: Preparing for the next PHP version (5.6)

__debugInfo()class somePasswordSafe {     private $user;     private $password;

    public function __construct($user, $password) {         $this->user = $user;         $this->password = $password;     }

    public function __debugInfo() {         return [             'user' => $this->password,             'password' => '**********',         ];     } }

print_r(new somePasswordSafe('root', 'secret'));

somePasswordSafe Object( [user] => secret [password] => **********)

5.6

Page 37: Preparing for the next PHP version (5.6)

use const / functionsnamespace Name\Space {     const FOO = 42;     function f() { echo __FUNCTION__."\n"; } }

namespace {     use const Name\Space\FOO;     use function Name\Space\f;

    echo FOO."\n";     f(); }

• Importing constants or functions from another namespace

• Keep things separated

• Avoid polluting global namespace

• Avoid static only classes

5.6

Page 38: Preparing for the next PHP version (5.6)

Constant scalar expressionsclass Version {     const MAJOR = 2;     const MIDDLE = ONE;     const MINOR = 1;     const FULL = Version::MAJOR.'.'.Version::MIDDLE.'.'.Version::MINOR.'-'.PHP_VERSION;     const SHORT = Version::MAJOR.'.'.Version::MIDDLE;     const COMPACT = Version::MAJOR.Version::MIDDLE.Version::MINOR;

    public function f($a = (MAJOR == 2) ? 3 : Version::MINOR ** 3) {         return $a;     } }

• Code automation

• Won’t accept functioncalls

• Keep it simple5.6

Page 39: Preparing for the next PHP version (5.6)

Foreach supports list• And any type

of keys

• Good with Iterator classes

• Not possible with Arrays

<?php

class object implements Iterator {     /.../     function key() { return array(1,2); }     function current() { return 3; }     /.../ }

$object = new object(); foreach($object as list($a, $b) = $c) {     print "$a + $b + $c = ".($a + $b + $c)."\n"; } ?>

5.5

Page 40: Preparing for the next PHP version (5.6)

Context changes• PHP 5.6

• Windows XP and 2003 dropped

• Support for Zend Optimiser

• PHP 5.5

• phpdbg

• Large File Upload5.5

5.6


Recommended