S & R E L E A S E S 0K 150K 300K 450K 600K 2011-09 2011-12 2012-03 2012-06 2012-09 2012-12 2013-03 2013-06 2013-09 2013-12 2014-03 2014-06 2014-09 2014-12 2015-03 2015-06 2015-09 2015-12 2016-03 2016-06 568K 105K Packages Versions Source: Packagist
I N STA L LS ( AV E R AG E / D AY ) 0M 45M 90M 135M 180M 2012-04 2012-07 2012-10 2013-01 2013-04 2013-07 2013-10 2014-01 2014-04 2014-07 2014-10 2015-01 2015-04 2015-07 2015-10 2016-01 2016-04 169M Source: Packagist
E N TS E XC E PT I O N • Throw an exception when too few arguments are passed to a user defined function/method regardless of strict types • Backwards compatibility break
F E W A R G U M E N TS E XC E PT I O N 1 2 3 4 5 6 Fatal error: Uncaught Error: Too few arguments to function hello(), 0 passed in <file> on line 6 and exactly 1 expected in <file>:2
$when"; } try { $args = ['World']; hello(... $args); } catch (\Error $e) { // Handle exception } TO O F E W A R G U M E N TS E XC E PT I O N 1 2 3 4 5 6 7 8 9 10 11
$when"; } try { $args = ['World']; hello(... $args); } catch (\Error $e) { // Handle exception } TO O F E W A R G U M E N TS E XC E PT I O N 1 2 3 4 5 6 7 8 9 10 11
$when"; } try { $args = ['World']; hello(... $args); } catch (\Error $e) { // Handle exception } TO O F E W A R G U M E N TS E XC E PT I O N 1 2 3 4 5 6 7 8 9 10 11
if (strlen($_POST['password']) < 8) { // Do something } if (!isset($_POST['password'][7])) { // Do something } if (!isset($_POST['password'][-8])) { // Do something }
S CO P E class Validator { public function getValidatorCallback($validationType) { if ($validationType == 'email') { return [$this, 'emailValidation']; } return [$this, 'genericValidation']; } private function emailValidation($userData) {...} private function genericValidation($userData) {...} } $validator = new Validator(); $callback = $validator->getValidatorCallback('email'); $callback($userData);
S CO P E class Validator { public function getValidatorCallback($validationType) { if ($validationType == 'email') { return [$this, 'emailValidation']; } return [$this, 'genericValidation']; } private function emailValidation($userData) {...} private function genericValidation($userData) {...} } $validator = new Validator(); $callback = $validator->getValidatorCallback('email'); $callback($userData);
S CO P E class Validator { public function getValidatorCallback($validationType) { if ($validationType == 'email') { return [$this, 'emailValidation']; } return [$this, 'genericValidation']; } private function emailValidation($userData) {...} private function genericValidation($userData) {...} } $validator = new Validator(); $callback = $validator->getValidatorCallback('email'); $callback($userData);
S CO P E class Validator { public function getValidatorCallback($validationType) { if ($validationType == 'email') { return [$this, 'emailValidation']; } return [$this, 'genericValidation']; } private function emailValidation($userData) {...} private function genericValidation($userData) {...} } $validator = new Validator(); $callback = $validator->getValidatorCallback('email'); $callback($userData);
S CO P E class Validator { public function getValidatorCallback($validationType) { if ($validationType == 'email') { return [$this, 'emailValidation']; } return [$this, 'genericValidation']; } private function emailValidation($userData) {...} private function genericValidation($userData) {...} } $validator = new Validator(); $callback = $validator->getValidatorCallback('email'); $callback($userData);
S CO P E class Validator { public function getValidatorCallback($validationType) { if ($validationType == 'email') { return [$this, 'emailValidation']; } return [$this, 'genericValidation']; } private function emailValidation($userData) {...} private function genericValidation($userData) {...} } $validator = new Validator(); $callback = $validator->getValidatorCallback('email'); $callback($userData);
S CO P E class Validator { public function getValidatorCallback($validationType) { if ($validationType == 'email') { return [$this, 'emailValidation']; } return [$this, 'genericValidation']; } private function emailValidation($userData) {...} private function genericValidation($userData) {...} } $validator = new Validator(); $callback = $validator->getValidatorCallback('email'); $callback($userData);
S CO P E class Validator { public function getValidatorCallback($validationType) { if ($validationType == 'email') { return [$this, 'emailValidation']; } return [$this, 'genericValidation']; } private function emailValidation($userData) {...} private function genericValidation($userData) {...} } $validator = new Validator(); $callback = $validator->getValidatorCallback('email'); $callback($userData);
S CO P E class Validator { public function getValidatorCallback($validationType) { if ($validationType == 'email') { return [$this, 'emailValidation']; } return [$this, 'genericValidation']; } private function emailValidation($userData) {...} private function genericValidation($userData) {...} } $validator = new Validator(); $callback = $validator->getValidatorCallback('email'); $callback($userData);
S CO P E class Validator { public function getValidatorCallback($validationType) { if ($validationType == 'email') { return [$this, 'emailValidation']; } return [$this, 'genericValidation']; } private function emailValidation($userData) {...} private function genericValidation($userData) {...} } $validator = new Validator(); $callback = $validator->getValidatorCallback('email'); $callback($userData);
S CO P E class Validator { public function getValidatorCallback($validationType) { if ($validationType == 'email') { return [$this, 'emailValidation']; } return [$this, 'genericValidation']; } private function emailValidation($userData) {...} private function genericValidation($userData) {...} } $validator = new Validator(); $callback = $validator->getValidatorCallback('email'); $callback($userData);
S CO P E class Validator { public function getValidatorCallback($validationType) { if ($validationType == 'email') { return [$this, 'emailValidation']; } return [$this, 'genericValidation']; } private function emailValidation($userData) {...} private function genericValidation($userData) {...} } $validator = new Validator(); $callback = $validator->getValidatorCallback('email'); $callback($userData);
S CO P E class Validator { public function getValidatorCallback($validationType) { if ($validationType == 'email') { return [$this, 'emailValidation']; } return [$this, 'genericValidation']; } public function emailValidation($userData) {...} public function genericValidation($userData) {...} } $validator = new Validator(); $callback = $validator->getValidatorCallback('email'); $callback($userData);
S CO P E class Validator { public function getValidatorCallback($validationType) { if ($validationType == 'email') { return [$this, 'emailValidation']; } return [$this, 'genericValidation']; } public function emailValidation($userData) {...} public function genericValidation($userData) {...} } $validator = new Validator(); $callback = $validator->getValidatorCallback('email'); $callback($userData);
S CO P E class Validator { public function getValidatorCallback($validationType) { if ($validationType == 'email') { return [$this, 'emailValidation']; } return [$this, 'genericValidation']; } private function emailValidation($userData) {...} private function genericValidation($userData) {...} } $validator = new Validator(); $callback = $validator->getValidatorCallback('email'); $callback($userData);
S CO P E class Validator { public function getValidatorCallback($validationType) { if ($validationType == 'email') { return Closure::fromCallable([$this, 'emailValidation']); } return Closure::fromCallable([$this, 'genericValidation']); } private function emailValidation($userData) {...} private function genericValidation($userData) {...} } $validator = new Validator(); $callback = $validator->getValidatorCallback('email'); $callback($userData);
S CO P E class Validator { public function getValidatorCallback($validationType) { if ($validationType == 'email') { return Closure::fromCallable([$this, 'emailValidation']); } return Closure::fromCallable([$this, 'genericValidation']); } private function emailValidation($userData) {...} private function genericValidation($userData) {...} } $validator = new Validator(); $callback = $validator->getValidatorCallback('email'); $callback($userData);
R H A N D L I N G class Validator { public function getValidatorCallback($validationType) { if ($validationType == 'email') { return Closure::fromCallable([$this, 'emailValidation']); } return Closure::fromCallable([$this, 'genericValidation']); } private function emailValidation($userData) {...} private function genericValidation($userData) {...} } $validator = new Validator(); $callback = $validator->getValidatorCallback('email'); $callback($userData);
R H A N D L I N G class Validator { public function getValidatorCallback($validationType) { if ($validationType == 'email') { return Closure::fromCallable([$this, 'emailValdation']); } return Closure::fromCallable([$this, 'genericValidation']); } private function emailValidation($userData) {...} private function genericValidation($userData) {...} } $validator = new Validator(); $callback = $validator->getValidatorCallback('email'); $callback($userData);
I S I B I L I TY class MyClass { public const MY_CONSTANT = 0; protected const MY_OTHER_CONSTANT = 1; private const MY_FAVORITE_CONSTANT = 2; private const FOO = 1, BAR = 2; }
I S I B I L I TY class MyClass { public const MY_CONSTANT = 0; protected const MY_OTHER_CONSTANT = 1; private const MY_FAVORITE_CONSTANT = 2; private const FOO = 1, BAR = 2; }
I S I B I L I TY class MyClass { public const MY_CONSTANT = 0; protected const MY_OTHER_CONSTANT = 1; private const MY_FAVORITE_CONSTANT = 2; private const FOO = 1, BAR = 2; }
I S I B I L I TY class MyClass { public const MY_CONSTANT = 0; protected const MY_OTHER_CONSTANT = 1; private const MY_FAVORITE_CONSTANT = 2; private const FOO = 1, BAR = 2; }
I S I B I L I TY class MyClass { public const MY_CONSTANT = 0; protected const MY_OTHER_CONSTANT = 1; private const MY_FAVORITE_CONSTANT = 2; private const FOO = 1, BAR = 2; }
STA N T V I S I B I L I TY interface MyInterface { public const MY_CONSTANT = 0; protected const MY_OTHER_CONSTANT = 1; private const MY_FAVORITE_CONSTANT = 2; private const FOO = 1, BAR = 2; }
TS TO R E F L E CT I O N • Added ReflectionClass->getReflectionConstant() • Added ReflectionClass->getReflectionConstants() • Both return ReflectionClassConstant instances
TS TO R E F L E CT I O N class ReflectionClassConstant { public function getName() { } public function getValue() { } public function isPublic() { } public function isPrivate() { } public function isProtected() { } public function getModifiers() { } public function getDeclaringClass() { } public function getDocComment() { } }
P L E E XC E PT I O N S try { ... } catch (\PDOException $e) { \My\App::renderError(500); } catch (\My\RequestException $e) { \My\App::renderError(500); } catch (\My\RequestMethodException $e) { \My\App::renderError(405); }
P L E E XC E PT I O N S try { ... } catch (\PDOException $e) { \My\App::renderError(500); } catch (\My\RequestException $e) { \My\App::renderError(500); } catch (\My\RequestMethodException $e) { \My\App::renderError(405); }
P L E E XC E PT I O N S try { ... } catch (\PDOException $e) { \My\App::renderError(500); } catch (\My\RequestException $e) { \My\App::renderError(500); } catch (\My\RequestMethodException $e) { \My\App::renderError(405); }
P L E E XC E PT I O N S try { ... } catch (\PDOException $e) { \My\App::renderError(500); } catch (\My\RequestException $e) { \My\App::renderError(500); } catch (\My\RequestMethodException $e) { \My\App::renderError(405); }
P L E E XC E PT I O N S try { ... } catch (\PDOException $e) { \My\App::renderError(500); } catch (\My\RequestException $e) { \My\App::renderError(500); } catch (\My\RequestMethodException $e) { \My\App::renderError(405); }
P L E E XC E PT I O N S try { ... } catch (\PDOException $e) { \My\App::renderError(500); } catch (\My\RequestException $e) { \My\App::renderError(500); } catch (\My\RequestMethodException $e) { \My\App::renderError(405); }
P L E E XC E PT I O N S try { ... } catch (\PDOException | \My\RequestException $e) { \My\App::renderError(500); } catch (\My\RequestMethodException $e) { \My\App::renderError(405); }
P L E E XC E PT I O N S try { ... } catch (\PDOException | \My\RequestException $e) { \My\App::renderError(500); } catch (\My\RequestMethodException $e) { \My\App::renderError(405); }
K E YS I N L I S T ( ) $coords = [ 'lat' => '1.3521° N', 'long' => '103.8198° E' ]; list($lat, $long) = $coords; var_dump($lat, $long); Notice: Undefined offset: 0 Notice: Undefined offset: 1
K E YS I N L I S T ( ) $coords = [ 'lat' => '1.3521° N', 'long' => '103.8198° E' ]; list($lat, $long) = $coords; var_dump($lat, $long); $lat === NULL $long === NULL
K E YS I N L I S T ( ) $coords = [ 'lat' => '1.3521° N', 'long' => '103.8198° E' ]; list('lat' => $lat, 'long' => $long) = $coords; var_dump($lat, $long);
K E YS I N L I S T ( ) $coords = [ 'lat' => '1.3521° N', 'long' => '103.8198° E' ]; list('lat' => $lat, 'long' => $long) = $coords; var_dump($lat, $long);
K E YS I N L I S T ( ) $coords = [ 'lat' => '1.3521° N', 'long' => '103.8198° E' ]; list('lat' => $lat, 'long' => $long) = $coords; var_dump($lat, $long); $lat === '1.3521° N' $long === '103.8198° E'
N TA X : M U T UA L LY E XC LU S I V E SY N TA X // This is not allowed: list([$a, $b], [$c, $d]) = [[1, 2], [3, 4]]; // This is also not allowed: [list($a, $b), list($c, $d)] = [[1, 2], [3, 4]]; // This, however, is allowed: [[$a, $b], [$c, $d]] = [[1, 2], [3, 4]]; // This also: list(list($a, $b), list($c, $d)) = [[1, 2], [3, 4]];
U E D OTY P E • Similar to callable but values you can foreach, or yield • Accepts any array, or object that implements Traversable • SPL Iterators • Generators • Can be used for return value
R A B L E ( ) F U N CT I O N // true is_iterable([1, 2, 3]); is_iterable(new ArrayIterator([1, 2, 3])); is_iterable((function () { yield 1; })()); // false is_iterable(1); is_iterable("Hello World"); is_iterable(new stdClass());
TY P E • PHP functions implicitly return null • There is a semantic difference between returning null, and returning nothing (or not returning) • Void enforces this behavior • Can only be used as a return type • Cannot be changed in sub-classes
TY P E function return_nothing(): void { return null; } Fatal error: A void function must not return a value (did you mean "return;" instead of "return null;"?)
E S • Allow specified type, or null • Requires an explicit null, doesn’t default to null • Works for Arguments & Return Types • Prefix type with a ? (question mark)
E S function hello(?string $whom) { echo "Hello " . ($whom ?? "World"); } hello(); Fatal error: Uncaught Error: Too few arguments to function hello(), 0 passed in <file> on line 6 and exactly 1 expected in <file>:2