Preparing for the next 
PHP version
Towards PHP 5.5 and 5.6 
• Changing version is often a big challenge 
• Backward incompatibilities 
• New features 
• How to spot them ?
Speaker 
• Damien Seguy 
• CTO at exakat 
• Phather of the plush toy 
elePHPant 
• Will talk on automated 
code audit later
PHP linting 
• command line : php -l filename.php 
• Will only parse the code, 
• not execution 
• Will spot compilation problems
PHP lint will find 
• Short array syntax 
• Function subscripting 
• break/continue with variables 
• Rare other situations 
• Code that won’t compile anyway
Where else code will break? 
• PHP running has 3 stages 
• parsed 
• compiled 
• executed 
Checked with lint 
Checked code review 
Checked with data and UT
What will change? 
• Removed features 
• Deprecated features 
• Changed features 
• New features
Deprecated features 
• PHP 5.6 
• $HTTP_RAW_POST_DATA 
5.6 
• Call From Incompatible Context 
• iconv and mbstring directives go to default_charset 
• PHP 5.5 
• /e in preg_replace 
• ext/mysql 
5.5 
• mcrypt arguments
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
Search is your friend 
• Grep, or IDE’s search function will help you 
• Look for mysql_* 
• $HTTP_RAW_POST_DATA
Error_level to E_STRICT 
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
/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
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
Incompatible context 
$ php53 test.php 
Notice: Undefined variable: this in test.php on line 3 
A 
<?php 
class A { 
function f() { echo get_class($this); } 
} 
A::f(); 
?> 
5.6 
$ 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
Search for situations 
• Search for :: operator 
• Get the class 
• then the method 
• then the static keyword 
• Needs a automated auditing tool 
• Code sniffer, IDE
Strict Standards: Non-static method 
A::f() should not be called 
statically in test.php on line 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
Added structures 
• PHP adds 
• constants 
• functions 
• extensions 
• traits 
• interfaces
Added structures 
Functions 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
New features 
• Fixing 
• Modernization 
• New feature
Fixing
empty() upgrade 
• No need 
anymore to 
expressions in a 
variable for 
empty()! 
function myFunction() { 
return -2 ; 
} 
if (empty(myFunction() + 2)) { 
echo "This means 0!n"; 
} 
Fatal error: Can't use function return value in write context in test.php on line 6 
5.5
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
Modernization
Dereferencing 
• Direct access to 
element in a string 
or an array. 
<?php 
/// Function dereferencing 
echo str_split("123", 1 )[2]; 
echo "n"; 
/// Array dereferencing 
echo [5, 5, 3][0]; 
echo "n"; 
/// String dereferencing 
echo 'PHP'[0]; 
echo "n"; 
5.5 ?>
Power operator 
• Replaces pow() 
• Be aware of precedence 
echo pow(2, 3); 
$a=2; 
$a **= 3; 
$a = 2 ** 3; 
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 = 1 
2 ^ 3 = 8 
3 ^ 3 = 27 
4 ^ 3 = 64 
5 ^ 3 = 125 
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 = 1 
2 ^ 3 = 8 
3 ^ 3 = 27 
4 ^ 3 = 64 
5 ^ 3 = 125
Generators 
function 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} 
• $step big => huge 
memory usage 
5.5
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}
function x() { 
$r = new resource(); 
Finally 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
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; 
}
Really new
Class name resolution 
<?php 
namespace NameSpace; 
class ClassName {} 
echo ClassName::class; 
echo "n"; 
?> 
• Get the full name of 
a class with ::class 
5.5
class somePasswordSa_fe {_ debugInfo() 
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
use const / functions 
namespace NameSpace { 
const FOO = 42; 
function f() { echo __FUNCTION__."n"; } 
} 
namespace { 
use const NameSpaceFOO; 
use function NameSpacef; 
echo FOO."n"; 
f(); 
} 
• Importing constants 
or functions from 
another namespace 
• Keep things 
separated 
• Avoid polluting 
global namespace 
• Avoid static only 
classes 
5.6
Constant scalar expressions 
class 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 simple 
5.6
Foreach supports list 
• And any type 
<?php 
of keys 
• Good with 
Iterator 
classes 
• Not possible 
with Arrays 
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
Context changes 
• PHP 5.6 
• Windows XP and 2003 dropped 
• Support for Zend Optimiser 
• PHP 5.5 
• phpdbg 
• Large File Upload 5.5 
5.6
www.slideshare 
.net/dseguy 
damien.seguy@gmail.com

Preparing for the next PHP version (5.6)

  • 1.
    Preparing for thenext PHP version
  • 2.
    Towards PHP 5.5and 5.6 • Changing version is often a big challenge • Backward incompatibilities • New features • How to spot them ?
  • 3.
    Speaker • DamienSeguy • CTO at exakat • Phather of the plush toy elePHPant • Will talk on automated code audit later
  • 4.
    PHP linting •command line : php -l filename.php • Will only parse the code, • not execution • Will spot compilation problems
  • 6.
    PHP lint willfind • Short array syntax • Function subscripting • break/continue with variables • Rare other situations • Code that won’t compile anyway
  • 7.
    Where else codewill break? • PHP running has 3 stages • parsed • compiled • executed Checked with lint Checked code review Checked with data and UT
  • 8.
    What will change? • Removed features • Deprecated features • Changed features • New features
  • 9.
    Deprecated features •PHP 5.6 • $HTTP_RAW_POST_DATA 5.6 • Call From Incompatible Context • iconv and mbstring directives go to default_charset • PHP 5.5 • /e in preg_replace • ext/mysql 5.5 • mcrypt arguments
  • 10.
    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
  • 11.
    Search is yourfriend • Grep, or IDE’s search function will help you • Look for mysql_* • $HTTP_RAW_POST_DATA
  • 12.
    Error_level to E_STRICT 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
  • 13.
    /e and charsetdirectives • 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
  • 14.
    Where to lookfor • 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
  • 15.
    Incompatible context $php53 test.php Notice: Undefined variable: this in test.php on line 3 A <?php class A { function f() { echo get_class($this); } } A::f(); ?> 5.6 $ 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
  • 16.
    Search for situations • Search for :: operator • Get the class • then the method • then the static keyword • Needs a automated auditing tool • Code sniffer, IDE
  • 17.
    Strict Standards: Non-staticmethod A::f() should not be called statically in test.php on line 6
  • 18.
    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
  • 19.
    Added structures •PHP adds • constants • functions • extensions • traits • interfaces
  • 20.
    Added structures FunctionsClasses 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
  • 21.
    New features •Fixing • Modernization • New feature
  • 22.
  • 23.
    empty() upgrade •No need anymore to expressions in a variable for empty()! function myFunction() { return -2 ; } if (empty(myFunction() + 2)) { echo "This means 0!n"; } Fatal error: Can't use function return value in write context in test.php on line 6 5.5
  • 24.
    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
  • 25.
  • 26.
    Dereferencing • Directaccess to element in a string or an array. <?php /// Function dereferencing echo str_split("123", 1 )[2]; echo "n"; /// Array dereferencing echo [5, 5, 3][0]; echo "n"; /// String dereferencing echo 'PHP'[0]; echo "n"; 5.5 ?>
  • 27.
    Power operator •Replaces pow() • Be aware of precedence echo pow(2, 3); $a=2; $a **= 3; $a = 2 ** 3; 5.6
  • 28.
    … 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 = 1 2 ^ 3 = 8 3 ^ 3 = 27 4 ^ 3 = 64 5 ^ 3 = 125 5.6
  • 29.
    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 = 1 2 ^ 3 = 8 3 ^ 3 = 27 4 ^ 3 = 64 5 ^ 3 = 125
  • 30.
    Generators function 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} • $step big => huge memory usage 5.5
  • 31.
    Generators • Newyield 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}
  • 32.
    function x() { $r = new resource(); Finally 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
  • 33.
    Finally • Cleanup 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; }
  • 34.
  • 35.
    Class name resolution <?php namespace NameSpace; class ClassName {} echo ClassName::class; echo "n"; ?> • Get the full name of a class with ::class 5.5
  • 36.
    class somePasswordSa_fe {_debugInfo() 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
  • 37.
    use const /functions namespace NameSpace { const FOO = 42; function f() { echo __FUNCTION__."n"; } } namespace { use const NameSpaceFOO; use function NameSpacef; echo FOO."n"; f(); } • Importing constants or functions from another namespace • Keep things separated • Avoid polluting global namespace • Avoid static only classes 5.6
  • 38.
    Constant scalar expressions class 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 simple 5.6
  • 39.
    Foreach supports list • And any type <?php of keys • Good with Iterator classes • Not possible with Arrays 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
  • 40.
    Context changes •PHP 5.6 • Windows XP and 2003 dropped • Support for Zend Optimiser • PHP 5.5 • phpdbg • Large File Upload 5.5 5.6
  • 41.