Preparing for the next PHP version (5.6)
-
Upload
damien-seguy- -
Category
Technology
-
view
436 -
download
1
description
Transcript of Preparing for the next PHP version (5.6)
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 with data and UT
Checked code review
What will change?
• Removed features
• Deprecated features
• Changed features
• New features
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
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
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
/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
<?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
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 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
New features
• Fixing
• Modernization
• New feature
Fixing
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
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 dereferencingecho str_split("123", 1 )[2]; echo "\n";
/// Array dereferencingecho [5, 5, 3][0]; echo "\n";
/// String dereferencingecho '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 = 12 ^ 3 = 83 ^ 3 = 274 ^ 3 = 645 ^ 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 = 12 ^ 3 = 83 ^ 3 = 274 ^ 3 = 645 ^ 3 = 125
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
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"; }
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
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 Name\Space; class ClassName {}
echo ClassName::class;
echo "\n"; ?>
• Get the full name of a class with ::class
5.5
__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
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
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
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
Context changes• PHP 5.6
• Windows XP and 2003 dropped
• Support for Zend Optimiser
• PHP 5.5
• phpdbg
• Large File Upload5.5
5.6
www.slideshare.net/dseguy