SlideShare a Scribd company logo
1 of 79
Download to read offline
What's new in PHP 8.0?
Nikita Popov
PHP 8.0
●
Just-In-Time (JIT) compiler
●
Many new language features
●
SemVer major version: Backwards incompatible
changes
Just-In-Time (JIT) Compiler
●
Compiles PHP code to x86 machine code to
improve performance
Just-In-Time (JIT) Compiler
●
Compiles PHP code to x86 machine code to
improve performance
●
Basic usage:
– Enable opcache
– opcache.jit_buffer_size=128M
Just-In-Time (JIT) Compiler
bench.php
micro_bench.php
PHP-Parser
amphp
Symfony Demo
With Preloading
0 0.5 1 1.5 2 2.5 3 3.5
Baseline: Opcache + No JIT
Just-In-Time (JIT) Compiler
bench.php
micro_bench.php
PHP-Parser
amphp
Symfony Demo
With Preloading
0 0.5 1 1.5 2 2.5 3 3.5
Baseline: Opcache + No JIT
Just-In-Time (JIT) Compiler
bench.php
micro_bench.php
PHP-Parser
amphp
Symfony Demo
With Preloading
0 0.5 1 1.5 2 2.5 3 3.5
Baseline: Opcache + No JIT
Just-In-Time (JIT) Compiler
bench.php
micro_bench.php
PHP-Parser
amphp
Symfony Demo
With Preloading
0 0.5 1 1.5 2 2.5 3 3.5
Baseline: Opcache + No JIT
Attributes
<?php
use SymfonyComponentRoutingAnnotationRoute;
class SomeController {
/**
* @Route("/path", name="action")
*/
public function someAction() {
}
}
Attributes
<?php
use SymfonyComponentRoutingAnnotationRoute;
class SomeController {
#[Route("/path", name: "action")]
public function someAction() {
}
}
Attributes
<?php
use SymfonyComponentRoutingAnnotationRoute;
class SomeController {
#[Route("/path", name: "action")]
public function someAction() {
}
}
Class name Constructor arguments
Attributes
<?php
namespace SymfonyComponentRoutingAnnotation;
use Attribute;
#[Attribute(Attribute::TARGET_METHOD)]
class Route {
public function __construct(string $path, ...) {
// ...
}
}
Attributes
<?php
$rm = new ReflectionMethod(
SomeController::class, "someAction");
foreach ($rm->getAttributes() as $attr) {
var_dump($attr->getName());
// => "SymfonyComponentRoutingAnnotationRoute"
var_dump($attr->getArguments());
// => ["/path", "name" => "action"]
var_dump($attr->newInstance());
// object(SymfonyComponentRoutingAnnotationRoute)
}
Attributes
<?php
$rm = new ReflectionMethod(
SomeController::class, "someAction");
foreach ($rm->getAttributes() as $attr) {
var_dump($attr->getName());
// => "SymfonyComponentRoutingAnnotationRoute"
var_dump($attr->getArguments());
// => ["/path", "name" => "action"]
var_dump($attr->newInstance());
// object(SymfonyComponentRoutingAnnotationRoute)
}
Attribute validation happens HERE.
Constructor Promotion
<?php
class Point {
public float $x;
public float $y;
public float $z;
public function __construct(
float $x = 0.0,
float $y = 0.0,
float $z = 0.0,
) {
$this->x = $x;
$this->y = $y;
$this->z = $z;
}
}
Constructor Promotion
<?php
class Point {
public function __construct(
public float $x = 0.0,
public float $y = 0.0,
public float $z = 0.0,
) {}
}
Constructor Promotion
<?php
class Point {
public function __construct(
public float $x = 0.0,
public float $y = 0.0,
public float $z = 0.0,
) {}
}
Trailing comma now allowed
Named Arguments
<?php
// Using positional arguments:
array_fill(0, 100, 50);
Named Arguments
<?php
// Using positional arguments:
array_fill(0, 100, 50);
// Using named arguments:
array_fill(start_index: 0, count: 100, value: 50);
Named Arguments
<?php
// Using positional arguments:
array_fill(0, 100, 50);
// Using named arguments:
array_fill(start_index: 0, count: 100, value: 50);
// Order does not matter!
array_fill(value: 50, count: 100, start_index: 0);
Named Arguments
<?php
// Using positional arguments:
htmlspecialchars(
$string, ENT_COMPAT | ENT_HTML401, 'UTF-8', false);
Named Arguments
<?php
// Using positional arguments:
htmlspecialchars(
$string, ENT_COMPAT | ENT_HTML401, 'UTF-8', false);
// Using named arguments:
htmlspecialchars($string, double_encode: false);
Named Arguments
<?php
use SymfonyComponentRoutingAnnotationRoute;
class SomeController {
#[Route("/path", name: "action")]
public function someAction() {
// ...
}
}
Named Arguments
<?php
class Point {
public function __construct(
public float $x,
public float $y,
public float $z,
) {}
}
new Point(x: 2.0, y: 3.1, z: 4.2);
Named Arguments
<?php
class A {
public function method($name_a) {}
}
class B extends A {
public function method($name_b) {}
}
// Error: Unknown named parameter $name_a
(new B)->method(name_a: 42);
Names not the same
Union Types
<?php
class Number {
/** @var int|float $number */
private $number;
/** @param int|float $number */
public function setNumber($number) {
$this->number = $number;
}
/** @return int|float */
public function getNumber() {
return $this->number;
}
}
Union Types
<?php
class Number {
private int|float $number;
public function setNumber(int|float $number) {
$this->number = $number;
}
public function getNumber(): int|float {
return $this->number;
}
}
Union Types
<?php
function strpos(
string $haystack, string $needle, int $offset = 0
): int|false {}
Union Types
<?php
function strpos(
string $haystack, string $needle, int $offset = 0
): int|false {}
Very common in standard library
Union Types
<?php
function strpos(
string $haystack, string $needle, int $offset = 0
): int|false {}
function array_key_first(array $arg): int|string|null {}
?Type is a shorthand for Type|null now
Union Types
<?php declare(strict_types=0);
function test(int|float|bool $arg) {
var_dump($arg);
}
test(45); // int(45)
test(45.8); // float(45.8)
test("45"); // int(45)
test("45.8"); // float(45.8)
test(""); // bool(false)
test("X"); // bool(true)
test([]); // TypeError
Union Types
<?php declare(strict_types=1);
function test(int|float|bool $arg) {
var_dump($arg);
}
test(45); // int(45)
test(45.8); // float(45.8)
test("45"); // TypeError
test("45.8"); // TypeError
test(""); // TypeError
test("X"); // TypeError
test([]); // TypeError
Mixed Type
●
Distinguishes between:
– Type is missing because I didn't add one yet
– This function really does accept any value
Mixed Type
<?php
function var_dump(mixed $value, mixed ...$value): void {}
function serialize(mixed $value): string {}
Mixed Type
<?php
function var_dump(mixed $value, mixed ...$value): void {}
function serialize(mixed $value): string {}
// "mixed" is a common approximation for generic functions:
function array_reduce(
array $arg, callable $callback,
mixed $initial = null
): mixed {}
Mixed Type
<?php
// For argument types:
// No type same as mixed type
class A {
public function method(mixed $arg) {}
}
class B extends A {
public function method($arg) {}
}
Allowed
Mixed Type
<?php
// For return types:
// No type effectively means mixed|void
class A {
public function method(): mixed {}
}
class B extends A {
public function method() {}
}
Mixed Type
<?php
// For return types:
// No type effectively means mixed|void
class A {
public function method(): mixed {}
}
class B extends A {
public function method() {}
}
Forbidden: Widening return type
Static Return Type
<?php
// Named constructor:
class TestParent {
public function createFromWhatever($whatever): static {
return new static($whatever);
}
}
Static Return Type
<?php
// Named constructor:
class TestParent {
public function createFromWhatever($whatever): static {
return new static($whatever);
}
}
class TestChild extends TestParent {}
// TestChild::createFromWhatever(...)
// must return TestChild, not TestParent!
Static Return Type
<?php
// Fluent methods:
class Test {
public function doWhatever(): static {
// Do whatever.
return $this;
}
}
Static Return Type
<?php
// Wither pattern:
class Test {
public function withWhatever($whatever): static {
$clone = clone $this;
$clone->whatever = $whatever;
return $clone;
}
}
Match Expression
<?php
switch ($operator) {
case '+':
$result = $a + $b;
break;
case '-':
$result = $a - $b;
break;
case '*':
$result = $a * $b;
break;
default:
throw new UnsupportedOperator($operator);
}
Match Expression
<?php
$result = match ($operator) {
'+' => $a + $b,
'-' => $a - $b,
'*' => $a * $b,
default => throw new UnsupportedOperator($operator);
};
Match Expression
<?php
$result = match ($operator) {
'+' => $a + $b,
'-' => $a - $b,
'*' => $a * $b,
default => throw new UnsupportedOperator($operator);
};
Expression with a return value
Match Expression
<?php
$result = match ($operator) {
'+' => $a + $b,
'-' => $a - $b,
'*' => $a * $b,
default => throw new UnsupportedOperator($operator),
};
Expression with a return valueExpression with a return value
Each match clause is an expression
("throw" is an expression now)
Match Expression
<?php
function evalOp($operator, $a, $b) {
return match ($operator) {
'+' => $a + $b,
'-' => $a - $b,
'*' => $a * $b,
};
}
// Match is exhaustive:
evalOp('/', 10, 2); // UnhandledMatchError
Match Expression
<?php
function evalOp($operator, $a, $b) {
return match ($operator) {
'+' => $a + $b,
'-' => $a - $b,
'*' => $a * $b,
};
}
// Match compares using ===, not ==.
evalOp(true, 10, 2); // UnhandledMatchError
Nullsafe Operator
<?php
$name = $session !== null
? $session->getUser()->name
: null;
// Same as:
$name = $session?->getUser()->name;
Nullsafe Operator
<?php
$name = $session?->getUser()?->name;
// Approximately same as:
$name = null;
if ($session !== null) {
$user = $session->getUser();
if ($user !== null) {
$name = $user->name;
}
}
Other Features
●
catch (Exception) without variable
●
$object::class
●
str_contains(), str_starts_with(), str_ends_with()
●
get_debug_type()
●
Stable sorting
●
WeakMap
Backwards Compatibility Breaks
●
Functionality deprecated before PHP 8.0 has
been removed!
●
Full list:
https://github.com/php/php-src/blob/PHP-8.0/UPGRADING
Number to String Comparison
<?php
$validValues = ["foo", "bar", "baz"];
$value = 0;
var_dump(in_array($value, $validValues));
// bool(true)
// ???
Number to String Comparison
<?php
0 == "foo";
// Before:
0 == (int)"foo";
// After:
(string)0 == "foo";
Number to String Comparison
Comparison | Before | After
------------------------------
0 == "0" | true | true
0 == "0.0" | true | true
0 == "foo" | true | false
0 == "" | true | false
42 == " 42" | true | true
42 == "42foo" | true | false
Resource To Object Migration
●
Long term goal: Convert all resources to objects
●
Objects are type-safe and have much better
internal support
Resource To Object Migration
●
Long term goal: Convert all resources to objects
●
Objects are type-safe and have much better
internal support
●
Using "opaque objects"
– Actual object-oriented APIs may be added later
Resource To Object Migration
●
CurlHandle, CurlMultiHandle, CurlShareHandle
●
EnchantBroker, EnchantDictionary
●
GdImage
●
InflateContext, DeflateContext
●
OpenSSLCertificate, OpenSSLCertificateSigningRequest,
OpenSSLAsymmetricKey
●
Shmop
●
Socket, AddressInfo
●
SysvMessageQueue, SysvSemaphore, SysvSharedMemory
●
XmlParser
●
XmlWriter (already had an OO API)
Resource To Object Migration
<?php
$image = imagecreatefrompng($path);
if (!is_resource($image)) {
throw new MalformedImageException;
}
Resource To Object Migration
<?php
$image = imagecreatefrompng($path);
if (!is_resource($image)) {
throw new MalformedImageException;
}
Now a GdImage object on success
Will always throw...
Resource To Object Migration
<?php
$image = imagecreatefrompng($path);
if (false === $image) {
throw new MalformedImageException;
}
Warning → Error exception
●
Many warnings converted to Error exceptions
– TypeError
– ValueError
Warning → Error exception
●
Only allowed for error conditions that imply
programmer error
●
It makes no sense to "handle" the error, code
needs to be fixed instead
Warning → Error exception
<?php
var_dump(strlen([]));
// Warning: strlen() expects parameter 1 to be string,
// array given
// NULL
function strlen(string $str): int|null {}
Warning → Error exception
<?php
var_dump(strlen([]));
// Uncaught TypeError: strlen(): Argument #1 ($str)
// must be of type string, array given
function strlen(string $str): int {}
Warning → Error exception
<?php
var_dump(array_fill(0, -100, "foobar"));
// Warning: array_fill(): Number of elements can't
// be negative
// bool(false)
function array_fill(
int $start_index, int $num, mixed $value
): array|false {}
Warning → Error exception
<?php
var_dump(array_fill(0, -100, "foobar"));
// Uncaught ValueError: array_fill(): Argument #2 ($count)
// must be greater than or equal to 0
function array_fill(
int $start_index, int $count, mixed $value
): array {}
Warning → Error exception
<?php
var_dump(fopen("does_not_exist.txt", "r"));
// Warning: fopen(does_not_exist.txt):
// Failed to open stream: No such file or directory
// bool(false)
Warning → Error exception
<?php
var_dump(fopen("does_not_exist.txt", "r"));
// Warning: fopen(does_not_exist.txt):
// Failed to open stream: No such file or directory
// bool(false)
NOT going to change!
fopen() failure is an environment failure condition,
it does not imply programmer error!
PHP Stubs
●
PHP stub files specify function signatures for
internal functions/methods
●
Used to generate C code for function
registration
PHP Stubs
<?php
function array_search(
mixed $needle, array $haystack, bool $strict = false
): int|string|false {}
PHP Stubs
<?php
function array_search(
mixed $needle, array $haystack, bool $strict = false
): int|string|false {}
ZEND_BEGIN_ARG_WITH_RETURN_TYPE_MASK_EX(
arginfo_array_search, 0, 2,
MAY_BE_LONG|MAY_BE_STRING|MAY_BE_FALSE)
ZEND_ARG_TYPE_INFO(0, needle, IS_MIXED, 0)
ZEND_ARG_TYPE_INFO(0, haystack, IS_ARRAY, 0)
ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(
0, strict, _IS_BOOL, 0, "false")
ZEND_END_ARG_INFO()
PHP Stubs
●
Data available through Reflection:
– ReflectionFunction::getReturnType()
– ReflectionParameter::getType()
– ReflectionParameter::getDefaultValue()
PHP Stubs
<?php
// Stub
class DateTime implements DateTimeInterface {
/** @return DateTime */
public function add(DateInterval $interval) {}
}
// Your code
class MyDateTime extends DateTime {
public function add(DateInterval $interval) {
// Do something
}
}
PHP Stubs
<?php
// Stub
class DateTime implements DateTimeInterface {
/** @return DateTime */
public function add(DateInterval $interval) {}
}
// Your code
class MyDateTime extends DateTime {
public function add(DateInterval $interval) {
// Do something
}
}
Now allowed!
PHP Stubs
<?php
// Stub
class DateTime implements DateTimeInterface {
/** @return DateTime */
public function add(DateInterval $interval) {}
}
// Your code
class MyDateTime extends DateTime {
public function add(DateInterval $interval) {
// Do something
}
}
Now allowed!
A real return type would force all extending
classes to specify it.
PHP Stubs
●
Ties in with many other efforts:
– Union types critical for standard library signatures
– Warning -> Error exception promotions avoid
unnecessary return types
– Resource to object migration allows use as types
– Named arguments based on stubs default values
Thank You!

More Related Content

What's hot (20)

PHP
PHPPHP
PHP
 
HTML 5: Audio And Video
HTML 5: Audio And VideoHTML 5: Audio And Video
HTML 5: Audio And Video
 
jQuery
jQueryjQuery
jQuery
 
PHP - Introduction to PHP Fundamentals
PHP -  Introduction to PHP FundamentalsPHP -  Introduction to PHP Fundamentals
PHP - Introduction to PHP Fundamentals
 
Php introduction
Php introductionPhp introduction
Php introduction
 
Introduction to PHP
Introduction to PHPIntroduction to PHP
Introduction to PHP
 
Php and threads ZTS
Php and threads ZTSPhp and threads ZTS
Php and threads ZTS
 
LLVM Backend Porting
LLVM Backend PortingLLVM Backend Porting
LLVM Backend Porting
 
jQuery from the very beginning
jQuery from the very beginningjQuery from the very beginning
jQuery from the very beginning
 
Session handling in php
Session handling in phpSession handling in php
Session handling in php
 
PHP Cookies and Sessions
PHP Cookies and SessionsPHP Cookies and Sessions
PHP Cookies and Sessions
 
Php
PhpPhp
Php
 
Title, heading and paragraph tags
Title, heading and paragraph tagsTitle, heading and paragraph tags
Title, heading and paragraph tags
 
Pointers in C
Pointers in CPointers in C
Pointers in C
 
Control Structures In Php 2
Control Structures In Php 2Control Structures In Php 2
Control Structures In Php 2
 
Advanced c programming in Linux
Advanced c programming in Linux Advanced c programming in Linux
Advanced c programming in Linux
 
Introduction to PHP
Introduction to PHPIntroduction to PHP
Introduction to PHP
 
Introduction to the LLVM Compiler System
Introduction to the LLVM  Compiler SystemIntroduction to the LLVM  Compiler System
Introduction to the LLVM Compiler System
 
Part II: LLVM Intermediate Representation
Part II: LLVM Intermediate RepresentationPart II: LLVM Intermediate Representation
Part II: LLVM Intermediate Representation
 
php basics
php basicsphp basics
php basics
 

Similar to What's new in PHP 8.0?

Nikita Popov "What’s new in PHP 8.0?"
Nikita Popov "What’s new in PHP 8.0?"Nikita Popov "What’s new in PHP 8.0?"
Nikita Popov "What’s new in PHP 8.0?"Fwdays
 
What's new in PHP 8.0?
What's new in PHP 8.0?What's new in PHP 8.0?
What's new in PHP 8.0?Nikita Popov
 
A Functional Guide to Cat Herding with PHP Generators
A Functional Guide to Cat Herding with PHP GeneratorsA Functional Guide to Cat Herding with PHP Generators
A Functional Guide to Cat Herding with PHP GeneratorsMark Baker
 
PHP7 - Scalar Type Hints & Return Types
PHP7 - Scalar Type Hints & Return TypesPHP7 - Scalar Type Hints & Return Types
PHP7 - Scalar Type Hints & Return TypesEric Poe
 
PHP Conference Asia 2016
PHP Conference Asia 2016PHP Conference Asia 2016
PHP Conference Asia 2016Britta Alex
 
Giới thiệu PHP 7
Giới thiệu PHP 7Giới thiệu PHP 7
Giới thiệu PHP 7ZendVN
 
PHP 5.3 Overview
PHP 5.3 OverviewPHP 5.3 Overview
PHP 5.3 Overviewjsmith92
 
Object Oriented PHP - PART-2
Object Oriented PHP - PART-2Object Oriented PHP - PART-2
Object Oriented PHP - PART-2Jalpesh Vasa
 
Functions in PHP.pptx
Functions in PHP.pptxFunctions in PHP.pptx
Functions in PHP.pptxJapneet9
 
php user defined functions
php user defined functionsphp user defined functions
php user defined functionsvishnupriyapm4
 
Php7 hhvm and co
Php7 hhvm and coPhp7 hhvm and co
Php7 hhvm and coPierre Joye
 
SymfonyCon 2017 php7 performances
SymfonyCon 2017 php7 performancesSymfonyCon 2017 php7 performances
SymfonyCon 2017 php7 performancesjulien pauli
 
Php my sql - functions - arrays - tutorial - programmerblog.net
Php my sql - functions - arrays - tutorial - programmerblog.netPhp my sql - functions - arrays - tutorial - programmerblog.net
Php my sql - functions - arrays - tutorial - programmerblog.netProgrammer Blog
 
Mastering Namespaces in PHP
Mastering Namespaces in PHPMastering Namespaces in PHP
Mastering Namespaces in PHPNick Belhomme
 
Learn PHP Basics
Learn PHP Basics Learn PHP Basics
Learn PHP Basics McSoftsis
 
Unlock The Mystery Of PHPUnit (Wave PHP 2018)
Unlock The Mystery Of PHPUnit (Wave PHP 2018)Unlock The Mystery Of PHPUnit (Wave PHP 2018)
Unlock The Mystery Of PHPUnit (Wave PHP 2018)ENDelt260
 

Similar to What's new in PHP 8.0? (20)

Nikita Popov "What’s new in PHP 8.0?"
Nikita Popov "What’s new in PHP 8.0?"Nikita Popov "What’s new in PHP 8.0?"
Nikita Popov "What’s new in PHP 8.0?"
 
What's new in PHP 8.0?
What's new in PHP 8.0?What's new in PHP 8.0?
What's new in PHP 8.0?
 
Web Technology_10.ppt
Web Technology_10.pptWeb Technology_10.ppt
Web Technology_10.ppt
 
A Functional Guide to Cat Herding with PHP Generators
A Functional Guide to Cat Herding with PHP GeneratorsA Functional Guide to Cat Herding with PHP Generators
A Functional Guide to Cat Herding with PHP Generators
 
PHP Basics
PHP BasicsPHP Basics
PHP Basics
 
PHP7 - Scalar Type Hints & Return Types
PHP7 - Scalar Type Hints & Return TypesPHP7 - Scalar Type Hints & Return Types
PHP7 - Scalar Type Hints & Return Types
 
PHP Conference Asia 2016
PHP Conference Asia 2016PHP Conference Asia 2016
PHP Conference Asia 2016
 
Giới thiệu PHP 7
Giới thiệu PHP 7Giới thiệu PHP 7
Giới thiệu PHP 7
 
PHP 5.3 Overview
PHP 5.3 OverviewPHP 5.3 Overview
PHP 5.3 Overview
 
Object Oriented PHP - PART-2
Object Oriented PHP - PART-2Object Oriented PHP - PART-2
Object Oriented PHP - PART-2
 
Functions in PHP.pptx
Functions in PHP.pptxFunctions in PHP.pptx
Functions in PHP.pptx
 
PHP Basic
PHP BasicPHP Basic
PHP Basic
 
php user defined functions
php user defined functionsphp user defined functions
php user defined functions
 
Php7 hhvm and co
Php7 hhvm and coPhp7 hhvm and co
Php7 hhvm and co
 
SymfonyCon 2017 php7 performances
SymfonyCon 2017 php7 performancesSymfonyCon 2017 php7 performances
SymfonyCon 2017 php7 performances
 
Php my sql - functions - arrays - tutorial - programmerblog.net
Php my sql - functions - arrays - tutorial - programmerblog.netPhp my sql - functions - arrays - tutorial - programmerblog.net
Php my sql - functions - arrays - tutorial - programmerblog.net
 
Mastering Namespaces in PHP
Mastering Namespaces in PHPMastering Namespaces in PHP
Mastering Namespaces in PHP
 
Learn PHP Basics
Learn PHP Basics Learn PHP Basics
Learn PHP Basics
 
Unlock The Mystery Of PHPUnit (Wave PHP 2018)
Unlock The Mystery Of PHPUnit (Wave PHP 2018)Unlock The Mystery Of PHPUnit (Wave PHP 2018)
Unlock The Mystery Of PHPUnit (Wave PHP 2018)
 
Introduction to php
Introduction to phpIntroduction to php
Introduction to php
 

More from Nikita Popov

A whirlwind tour of the LLVM optimizer
A whirlwind tour of the LLVM optimizerA whirlwind tour of the LLVM optimizer
A whirlwind tour of the LLVM optimizerNikita Popov
 
Opaque Pointers Are Coming
Opaque Pointers Are ComingOpaque Pointers Are Coming
Opaque Pointers Are ComingNikita Popov
 
PHP Performance Trivia
PHP Performance TriviaPHP Performance Trivia
PHP Performance TriviaNikita Popov
 
Typed Properties and more: What's coming in PHP 7.4?
Typed Properties and more: What's coming in PHP 7.4?Typed Properties and more: What's coming in PHP 7.4?
Typed Properties and more: What's coming in PHP 7.4?Nikita Popov
 
Static Optimization of PHP bytecode (PHPSC 2017)
Static Optimization of PHP bytecode (PHPSC 2017)Static Optimization of PHP bytecode (PHPSC 2017)
Static Optimization of PHP bytecode (PHPSC 2017)Nikita Popov
 
PHP Language Trivia
PHP Language TriviaPHP Language Trivia
PHP Language TriviaNikita Popov
 
PHP 7 – What changed internally? (Forum PHP 2015)
PHP 7 – What changed internally? (Forum PHP 2015)PHP 7 – What changed internally? (Forum PHP 2015)
PHP 7 – What changed internally? (Forum PHP 2015)Nikita Popov
 
PHP 7 – What changed internally? (PHP Barcelona 2015)
PHP 7 – What changed internally? (PHP Barcelona 2015)PHP 7 – What changed internally? (PHP Barcelona 2015)
PHP 7 – What changed internally? (PHP Barcelona 2015)Nikita Popov
 
PHP 7 – What changed internally?
PHP 7 – What changed internally?PHP 7 – What changed internally?
PHP 7 – What changed internally?Nikita Popov
 

More from Nikita Popov (9)

A whirlwind tour of the LLVM optimizer
A whirlwind tour of the LLVM optimizerA whirlwind tour of the LLVM optimizer
A whirlwind tour of the LLVM optimizer
 
Opaque Pointers Are Coming
Opaque Pointers Are ComingOpaque Pointers Are Coming
Opaque Pointers Are Coming
 
PHP Performance Trivia
PHP Performance TriviaPHP Performance Trivia
PHP Performance Trivia
 
Typed Properties and more: What's coming in PHP 7.4?
Typed Properties and more: What's coming in PHP 7.4?Typed Properties and more: What's coming in PHP 7.4?
Typed Properties and more: What's coming in PHP 7.4?
 
Static Optimization of PHP bytecode (PHPSC 2017)
Static Optimization of PHP bytecode (PHPSC 2017)Static Optimization of PHP bytecode (PHPSC 2017)
Static Optimization of PHP bytecode (PHPSC 2017)
 
PHP Language Trivia
PHP Language TriviaPHP Language Trivia
PHP Language Trivia
 
PHP 7 – What changed internally? (Forum PHP 2015)
PHP 7 – What changed internally? (Forum PHP 2015)PHP 7 – What changed internally? (Forum PHP 2015)
PHP 7 – What changed internally? (Forum PHP 2015)
 
PHP 7 – What changed internally? (PHP Barcelona 2015)
PHP 7 – What changed internally? (PHP Barcelona 2015)PHP 7 – What changed internally? (PHP Barcelona 2015)
PHP 7 – What changed internally? (PHP Barcelona 2015)
 
PHP 7 – What changed internally?
PHP 7 – What changed internally?PHP 7 – What changed internally?
PHP 7 – What changed internally?
 

Recently uploaded

Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...
Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...
Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...Drew Madelung
 
Finology Group – Insurtech Innovation Award 2024
Finology Group – Insurtech Innovation Award 2024Finology Group – Insurtech Innovation Award 2024
Finology Group – Insurtech Innovation Award 2024The Digital Insurer
 
Artificial Intelligence: Facts and Myths
Artificial Intelligence: Facts and MythsArtificial Intelligence: Facts and Myths
Artificial Intelligence: Facts and MythsJoaquim Jorge
 
From Event to Action: Accelerate Your Decision Making with Real-Time Automation
From Event to Action: Accelerate Your Decision Making with Real-Time AutomationFrom Event to Action: Accelerate Your Decision Making with Real-Time Automation
From Event to Action: Accelerate Your Decision Making with Real-Time AutomationSafe Software
 
Exploring the Future Potential of AI-Enabled Smartphone Processors
Exploring the Future Potential of AI-Enabled Smartphone ProcessorsExploring the Future Potential of AI-Enabled Smartphone Processors
Exploring the Future Potential of AI-Enabled Smartphone Processorsdebabhi2
 
Tech Trends Report 2024 Future Today Institute.pdf
Tech Trends Report 2024 Future Today Institute.pdfTech Trends Report 2024 Future Today Institute.pdf
Tech Trends Report 2024 Future Today Institute.pdfhans926745
 
IAC 2024 - IA Fast Track to Search Focused AI Solutions
IAC 2024 - IA Fast Track to Search Focused AI SolutionsIAC 2024 - IA Fast Track to Search Focused AI Solutions
IAC 2024 - IA Fast Track to Search Focused AI SolutionsEnterprise Knowledge
 
GenAI Risks & Security Meetup 01052024.pdf
GenAI Risks & Security Meetup 01052024.pdfGenAI Risks & Security Meetup 01052024.pdf
GenAI Risks & Security Meetup 01052024.pdflior mazor
 
Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...
Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...
Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...apidays
 
04-2024-HHUG-Sales-and-Marketing-Alignment.pptx
04-2024-HHUG-Sales-and-Marketing-Alignment.pptx04-2024-HHUG-Sales-and-Marketing-Alignment.pptx
04-2024-HHUG-Sales-and-Marketing-Alignment.pptxHampshireHUG
 
GenCyber Cyber Security Day Presentation
GenCyber Cyber Security Day PresentationGenCyber Cyber Security Day Presentation
GenCyber Cyber Security Day PresentationMichael W. Hawkins
 
Strategies for Landing an Oracle DBA Job as a Fresher
Strategies for Landing an Oracle DBA Job as a FresherStrategies for Landing an Oracle DBA Job as a Fresher
Strategies for Landing an Oracle DBA Job as a FresherRemote DBA Services
 
Understanding Discord NSFW Servers A Guide for Responsible Users.pdf
Understanding Discord NSFW Servers A Guide for Responsible Users.pdfUnderstanding Discord NSFW Servers A Guide for Responsible Users.pdf
Understanding Discord NSFW Servers A Guide for Responsible Users.pdfUK Journal
 
Powerful Google developer tools for immediate impact! (2023-24 C)
Powerful Google developer tools for immediate impact! (2023-24 C)Powerful Google developer tools for immediate impact! (2023-24 C)
Powerful Google developer tools for immediate impact! (2023-24 C)wesley chun
 
[2024]Digital Global Overview Report 2024 Meltwater.pdf
[2024]Digital Global Overview Report 2024 Meltwater.pdf[2024]Digital Global Overview Report 2024 Meltwater.pdf
[2024]Digital Global Overview Report 2024 Meltwater.pdfhans926745
 
Boost PC performance: How more available memory can improve productivity
Boost PC performance: How more available memory can improve productivityBoost PC performance: How more available memory can improve productivity
Boost PC performance: How more available memory can improve productivityPrincipled Technologies
 
Scaling API-first – The story of a global engineering organization
Scaling API-first – The story of a global engineering organizationScaling API-first – The story of a global engineering organization
Scaling API-first – The story of a global engineering organizationRadu Cotescu
 
Handwritten Text Recognition for manuscripts and early printed texts
Handwritten Text Recognition for manuscripts and early printed textsHandwritten Text Recognition for manuscripts and early printed texts
Handwritten Text Recognition for manuscripts and early printed textsMaria Levchenko
 
Driving Behavioral Change for Information Management through Data-Driven Gree...
Driving Behavioral Change for Information Management through Data-Driven Gree...Driving Behavioral Change for Information Management through Data-Driven Gree...
Driving Behavioral Change for Information Management through Data-Driven Gree...Enterprise Knowledge
 
How to Troubleshoot Apps for the Modern Connected Worker
How to Troubleshoot Apps for the Modern Connected WorkerHow to Troubleshoot Apps for the Modern Connected Worker
How to Troubleshoot Apps for the Modern Connected WorkerThousandEyes
 

Recently uploaded (20)

Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...
Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...
Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...
 
Finology Group – Insurtech Innovation Award 2024
Finology Group – Insurtech Innovation Award 2024Finology Group – Insurtech Innovation Award 2024
Finology Group – Insurtech Innovation Award 2024
 
Artificial Intelligence: Facts and Myths
Artificial Intelligence: Facts and MythsArtificial Intelligence: Facts and Myths
Artificial Intelligence: Facts and Myths
 
From Event to Action: Accelerate Your Decision Making with Real-Time Automation
From Event to Action: Accelerate Your Decision Making with Real-Time AutomationFrom Event to Action: Accelerate Your Decision Making with Real-Time Automation
From Event to Action: Accelerate Your Decision Making with Real-Time Automation
 
Exploring the Future Potential of AI-Enabled Smartphone Processors
Exploring the Future Potential of AI-Enabled Smartphone ProcessorsExploring the Future Potential of AI-Enabled Smartphone Processors
Exploring the Future Potential of AI-Enabled Smartphone Processors
 
Tech Trends Report 2024 Future Today Institute.pdf
Tech Trends Report 2024 Future Today Institute.pdfTech Trends Report 2024 Future Today Institute.pdf
Tech Trends Report 2024 Future Today Institute.pdf
 
IAC 2024 - IA Fast Track to Search Focused AI Solutions
IAC 2024 - IA Fast Track to Search Focused AI SolutionsIAC 2024 - IA Fast Track to Search Focused AI Solutions
IAC 2024 - IA Fast Track to Search Focused AI Solutions
 
GenAI Risks & Security Meetup 01052024.pdf
GenAI Risks & Security Meetup 01052024.pdfGenAI Risks & Security Meetup 01052024.pdf
GenAI Risks & Security Meetup 01052024.pdf
 
Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...
Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...
Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...
 
04-2024-HHUG-Sales-and-Marketing-Alignment.pptx
04-2024-HHUG-Sales-and-Marketing-Alignment.pptx04-2024-HHUG-Sales-and-Marketing-Alignment.pptx
04-2024-HHUG-Sales-and-Marketing-Alignment.pptx
 
GenCyber Cyber Security Day Presentation
GenCyber Cyber Security Day PresentationGenCyber Cyber Security Day Presentation
GenCyber Cyber Security Day Presentation
 
Strategies for Landing an Oracle DBA Job as a Fresher
Strategies for Landing an Oracle DBA Job as a FresherStrategies for Landing an Oracle DBA Job as a Fresher
Strategies for Landing an Oracle DBA Job as a Fresher
 
Understanding Discord NSFW Servers A Guide for Responsible Users.pdf
Understanding Discord NSFW Servers A Guide for Responsible Users.pdfUnderstanding Discord NSFW Servers A Guide for Responsible Users.pdf
Understanding Discord NSFW Servers A Guide for Responsible Users.pdf
 
Powerful Google developer tools for immediate impact! (2023-24 C)
Powerful Google developer tools for immediate impact! (2023-24 C)Powerful Google developer tools for immediate impact! (2023-24 C)
Powerful Google developer tools for immediate impact! (2023-24 C)
 
[2024]Digital Global Overview Report 2024 Meltwater.pdf
[2024]Digital Global Overview Report 2024 Meltwater.pdf[2024]Digital Global Overview Report 2024 Meltwater.pdf
[2024]Digital Global Overview Report 2024 Meltwater.pdf
 
Boost PC performance: How more available memory can improve productivity
Boost PC performance: How more available memory can improve productivityBoost PC performance: How more available memory can improve productivity
Boost PC performance: How more available memory can improve productivity
 
Scaling API-first – The story of a global engineering organization
Scaling API-first – The story of a global engineering organizationScaling API-first – The story of a global engineering organization
Scaling API-first – The story of a global engineering organization
 
Handwritten Text Recognition for manuscripts and early printed texts
Handwritten Text Recognition for manuscripts and early printed textsHandwritten Text Recognition for manuscripts and early printed texts
Handwritten Text Recognition for manuscripts and early printed texts
 
Driving Behavioral Change for Information Management through Data-Driven Gree...
Driving Behavioral Change for Information Management through Data-Driven Gree...Driving Behavioral Change for Information Management through Data-Driven Gree...
Driving Behavioral Change for Information Management through Data-Driven Gree...
 
How to Troubleshoot Apps for the Modern Connected Worker
How to Troubleshoot Apps for the Modern Connected WorkerHow to Troubleshoot Apps for the Modern Connected Worker
How to Troubleshoot Apps for the Modern Connected Worker
 

What's new in PHP 8.0?

  • 1. What's new in PHP 8.0? Nikita Popov
  • 2.
  • 3. PHP 8.0 ● Just-In-Time (JIT) compiler ● Many new language features ● SemVer major version: Backwards incompatible changes
  • 4. Just-In-Time (JIT) Compiler ● Compiles PHP code to x86 machine code to improve performance
  • 5. Just-In-Time (JIT) Compiler ● Compiles PHP code to x86 machine code to improve performance ● Basic usage: – Enable opcache – opcache.jit_buffer_size=128M
  • 6. Just-In-Time (JIT) Compiler bench.php micro_bench.php PHP-Parser amphp Symfony Demo With Preloading 0 0.5 1 1.5 2 2.5 3 3.5 Baseline: Opcache + No JIT
  • 7. Just-In-Time (JIT) Compiler bench.php micro_bench.php PHP-Parser amphp Symfony Demo With Preloading 0 0.5 1 1.5 2 2.5 3 3.5 Baseline: Opcache + No JIT
  • 8. Just-In-Time (JIT) Compiler bench.php micro_bench.php PHP-Parser amphp Symfony Demo With Preloading 0 0.5 1 1.5 2 2.5 3 3.5 Baseline: Opcache + No JIT
  • 9. Just-In-Time (JIT) Compiler bench.php micro_bench.php PHP-Parser amphp Symfony Demo With Preloading 0 0.5 1 1.5 2 2.5 3 3.5 Baseline: Opcache + No JIT
  • 10. Attributes <?php use SymfonyComponentRoutingAnnotationRoute; class SomeController { /** * @Route("/path", name="action") */ public function someAction() { } }
  • 11. Attributes <?php use SymfonyComponentRoutingAnnotationRoute; class SomeController { #[Route("/path", name: "action")] public function someAction() { } }
  • 12. Attributes <?php use SymfonyComponentRoutingAnnotationRoute; class SomeController { #[Route("/path", name: "action")] public function someAction() { } } Class name Constructor arguments
  • 14. Attributes <?php $rm = new ReflectionMethod( SomeController::class, "someAction"); foreach ($rm->getAttributes() as $attr) { var_dump($attr->getName()); // => "SymfonyComponentRoutingAnnotationRoute" var_dump($attr->getArguments()); // => ["/path", "name" => "action"] var_dump($attr->newInstance()); // object(SymfonyComponentRoutingAnnotationRoute) }
  • 15. Attributes <?php $rm = new ReflectionMethod( SomeController::class, "someAction"); foreach ($rm->getAttributes() as $attr) { var_dump($attr->getName()); // => "SymfonyComponentRoutingAnnotationRoute" var_dump($attr->getArguments()); // => ["/path", "name" => "action"] var_dump($attr->newInstance()); // object(SymfonyComponentRoutingAnnotationRoute) } Attribute validation happens HERE.
  • 16. Constructor Promotion <?php class Point { public float $x; public float $y; public float $z; public function __construct( float $x = 0.0, float $y = 0.0, float $z = 0.0, ) { $this->x = $x; $this->y = $y; $this->z = $z; } }
  • 17. Constructor Promotion <?php class Point { public function __construct( public float $x = 0.0, public float $y = 0.0, public float $z = 0.0, ) {} }
  • 18. Constructor Promotion <?php class Point { public function __construct( public float $x = 0.0, public float $y = 0.0, public float $z = 0.0, ) {} } Trailing comma now allowed
  • 19. Named Arguments <?php // Using positional arguments: array_fill(0, 100, 50);
  • 20. Named Arguments <?php // Using positional arguments: array_fill(0, 100, 50); // Using named arguments: array_fill(start_index: 0, count: 100, value: 50);
  • 21. Named Arguments <?php // Using positional arguments: array_fill(0, 100, 50); // Using named arguments: array_fill(start_index: 0, count: 100, value: 50); // Order does not matter! array_fill(value: 50, count: 100, start_index: 0);
  • 22. Named Arguments <?php // Using positional arguments: htmlspecialchars( $string, ENT_COMPAT | ENT_HTML401, 'UTF-8', false);
  • 23. Named Arguments <?php // Using positional arguments: htmlspecialchars( $string, ENT_COMPAT | ENT_HTML401, 'UTF-8', false); // Using named arguments: htmlspecialchars($string, double_encode: false);
  • 24. Named Arguments <?php use SymfonyComponentRoutingAnnotationRoute; class SomeController { #[Route("/path", name: "action")] public function someAction() { // ... } }
  • 25. Named Arguments <?php class Point { public function __construct( public float $x, public float $y, public float $z, ) {} } new Point(x: 2.0, y: 3.1, z: 4.2);
  • 26. Named Arguments <?php class A { public function method($name_a) {} } class B extends A { public function method($name_b) {} } // Error: Unknown named parameter $name_a (new B)->method(name_a: 42); Names not the same
  • 27. Union Types <?php class Number { /** @var int|float $number */ private $number; /** @param int|float $number */ public function setNumber($number) { $this->number = $number; } /** @return int|float */ public function getNumber() { return $this->number; } }
  • 28. Union Types <?php class Number { private int|float $number; public function setNumber(int|float $number) { $this->number = $number; } public function getNumber(): int|float { return $this->number; } }
  • 29. Union Types <?php function strpos( string $haystack, string $needle, int $offset = 0 ): int|false {}
  • 30. Union Types <?php function strpos( string $haystack, string $needle, int $offset = 0 ): int|false {} Very common in standard library
  • 31. Union Types <?php function strpos( string $haystack, string $needle, int $offset = 0 ): int|false {} function array_key_first(array $arg): int|string|null {} ?Type is a shorthand for Type|null now
  • 32. Union Types <?php declare(strict_types=0); function test(int|float|bool $arg) { var_dump($arg); } test(45); // int(45) test(45.8); // float(45.8) test("45"); // int(45) test("45.8"); // float(45.8) test(""); // bool(false) test("X"); // bool(true) test([]); // TypeError
  • 33. Union Types <?php declare(strict_types=1); function test(int|float|bool $arg) { var_dump($arg); } test(45); // int(45) test(45.8); // float(45.8) test("45"); // TypeError test("45.8"); // TypeError test(""); // TypeError test("X"); // TypeError test([]); // TypeError
  • 34. Mixed Type ● Distinguishes between: – Type is missing because I didn't add one yet – This function really does accept any value
  • 35. Mixed Type <?php function var_dump(mixed $value, mixed ...$value): void {} function serialize(mixed $value): string {}
  • 36. Mixed Type <?php function var_dump(mixed $value, mixed ...$value): void {} function serialize(mixed $value): string {} // "mixed" is a common approximation for generic functions: function array_reduce( array $arg, callable $callback, mixed $initial = null ): mixed {}
  • 37. Mixed Type <?php // For argument types: // No type same as mixed type class A { public function method(mixed $arg) {} } class B extends A { public function method($arg) {} } Allowed
  • 38. Mixed Type <?php // For return types: // No type effectively means mixed|void class A { public function method(): mixed {} } class B extends A { public function method() {} }
  • 39. Mixed Type <?php // For return types: // No type effectively means mixed|void class A { public function method(): mixed {} } class B extends A { public function method() {} } Forbidden: Widening return type
  • 40. Static Return Type <?php // Named constructor: class TestParent { public function createFromWhatever($whatever): static { return new static($whatever); } }
  • 41. Static Return Type <?php // Named constructor: class TestParent { public function createFromWhatever($whatever): static { return new static($whatever); } } class TestChild extends TestParent {} // TestChild::createFromWhatever(...) // must return TestChild, not TestParent!
  • 42. Static Return Type <?php // Fluent methods: class Test { public function doWhatever(): static { // Do whatever. return $this; } }
  • 43. Static Return Type <?php // Wither pattern: class Test { public function withWhatever($whatever): static { $clone = clone $this; $clone->whatever = $whatever; return $clone; } }
  • 44. Match Expression <?php switch ($operator) { case '+': $result = $a + $b; break; case '-': $result = $a - $b; break; case '*': $result = $a * $b; break; default: throw new UnsupportedOperator($operator); }
  • 45. Match Expression <?php $result = match ($operator) { '+' => $a + $b, '-' => $a - $b, '*' => $a * $b, default => throw new UnsupportedOperator($operator); };
  • 46. Match Expression <?php $result = match ($operator) { '+' => $a + $b, '-' => $a - $b, '*' => $a * $b, default => throw new UnsupportedOperator($operator); }; Expression with a return value
  • 47. Match Expression <?php $result = match ($operator) { '+' => $a + $b, '-' => $a - $b, '*' => $a * $b, default => throw new UnsupportedOperator($operator), }; Expression with a return valueExpression with a return value Each match clause is an expression ("throw" is an expression now)
  • 48. Match Expression <?php function evalOp($operator, $a, $b) { return match ($operator) { '+' => $a + $b, '-' => $a - $b, '*' => $a * $b, }; } // Match is exhaustive: evalOp('/', 10, 2); // UnhandledMatchError
  • 49. Match Expression <?php function evalOp($operator, $a, $b) { return match ($operator) { '+' => $a + $b, '-' => $a - $b, '*' => $a * $b, }; } // Match compares using ===, not ==. evalOp(true, 10, 2); // UnhandledMatchError
  • 50. Nullsafe Operator <?php $name = $session !== null ? $session->getUser()->name : null; // Same as: $name = $session?->getUser()->name;
  • 51. Nullsafe Operator <?php $name = $session?->getUser()?->name; // Approximately same as: $name = null; if ($session !== null) { $user = $session->getUser(); if ($user !== null) { $name = $user->name; } }
  • 52. Other Features ● catch (Exception) without variable ● $object::class ● str_contains(), str_starts_with(), str_ends_with() ● get_debug_type() ● Stable sorting ● WeakMap
  • 53. Backwards Compatibility Breaks ● Functionality deprecated before PHP 8.0 has been removed! ● Full list: https://github.com/php/php-src/blob/PHP-8.0/UPGRADING
  • 54. Number to String Comparison <?php $validValues = ["foo", "bar", "baz"]; $value = 0; var_dump(in_array($value, $validValues)); // bool(true) // ???
  • 55. Number to String Comparison <?php 0 == "foo"; // Before: 0 == (int)"foo"; // After: (string)0 == "foo";
  • 56. Number to String Comparison Comparison | Before | After ------------------------------ 0 == "0" | true | true 0 == "0.0" | true | true 0 == "foo" | true | false 0 == "" | true | false 42 == " 42" | true | true 42 == "42foo" | true | false
  • 57. Resource To Object Migration ● Long term goal: Convert all resources to objects ● Objects are type-safe and have much better internal support
  • 58. Resource To Object Migration ● Long term goal: Convert all resources to objects ● Objects are type-safe and have much better internal support ● Using "opaque objects" – Actual object-oriented APIs may be added later
  • 59. Resource To Object Migration ● CurlHandle, CurlMultiHandle, CurlShareHandle ● EnchantBroker, EnchantDictionary ● GdImage ● InflateContext, DeflateContext ● OpenSSLCertificate, OpenSSLCertificateSigningRequest, OpenSSLAsymmetricKey ● Shmop ● Socket, AddressInfo ● SysvMessageQueue, SysvSemaphore, SysvSharedMemory ● XmlParser ● XmlWriter (already had an OO API)
  • 60. Resource To Object Migration <?php $image = imagecreatefrompng($path); if (!is_resource($image)) { throw new MalformedImageException; }
  • 61. Resource To Object Migration <?php $image = imagecreatefrompng($path); if (!is_resource($image)) { throw new MalformedImageException; } Now a GdImage object on success Will always throw...
  • 62. Resource To Object Migration <?php $image = imagecreatefrompng($path); if (false === $image) { throw new MalformedImageException; }
  • 63. Warning → Error exception ● Many warnings converted to Error exceptions – TypeError – ValueError
  • 64. Warning → Error exception ● Only allowed for error conditions that imply programmer error ● It makes no sense to "handle" the error, code needs to be fixed instead
  • 65. Warning → Error exception <?php var_dump(strlen([])); // Warning: strlen() expects parameter 1 to be string, // array given // NULL function strlen(string $str): int|null {}
  • 66. Warning → Error exception <?php var_dump(strlen([])); // Uncaught TypeError: strlen(): Argument #1 ($str) // must be of type string, array given function strlen(string $str): int {}
  • 67. Warning → Error exception <?php var_dump(array_fill(0, -100, "foobar")); // Warning: array_fill(): Number of elements can't // be negative // bool(false) function array_fill( int $start_index, int $num, mixed $value ): array|false {}
  • 68. Warning → Error exception <?php var_dump(array_fill(0, -100, "foobar")); // Uncaught ValueError: array_fill(): Argument #2 ($count) // must be greater than or equal to 0 function array_fill( int $start_index, int $count, mixed $value ): array {}
  • 69. Warning → Error exception <?php var_dump(fopen("does_not_exist.txt", "r")); // Warning: fopen(does_not_exist.txt): // Failed to open stream: No such file or directory // bool(false)
  • 70. Warning → Error exception <?php var_dump(fopen("does_not_exist.txt", "r")); // Warning: fopen(does_not_exist.txt): // Failed to open stream: No such file or directory // bool(false) NOT going to change! fopen() failure is an environment failure condition, it does not imply programmer error!
  • 71. PHP Stubs ● PHP stub files specify function signatures for internal functions/methods ● Used to generate C code for function registration
  • 72. PHP Stubs <?php function array_search( mixed $needle, array $haystack, bool $strict = false ): int|string|false {}
  • 73. PHP Stubs <?php function array_search( mixed $needle, array $haystack, bool $strict = false ): int|string|false {} ZEND_BEGIN_ARG_WITH_RETURN_TYPE_MASK_EX( arginfo_array_search, 0, 2, MAY_BE_LONG|MAY_BE_STRING|MAY_BE_FALSE) ZEND_ARG_TYPE_INFO(0, needle, IS_MIXED, 0) ZEND_ARG_TYPE_INFO(0, haystack, IS_ARRAY, 0) ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE( 0, strict, _IS_BOOL, 0, "false") ZEND_END_ARG_INFO()
  • 74. PHP Stubs ● Data available through Reflection: – ReflectionFunction::getReturnType() – ReflectionParameter::getType() – ReflectionParameter::getDefaultValue()
  • 75. PHP Stubs <?php // Stub class DateTime implements DateTimeInterface { /** @return DateTime */ public function add(DateInterval $interval) {} } // Your code class MyDateTime extends DateTime { public function add(DateInterval $interval) { // Do something } }
  • 76. PHP Stubs <?php // Stub class DateTime implements DateTimeInterface { /** @return DateTime */ public function add(DateInterval $interval) {} } // Your code class MyDateTime extends DateTime { public function add(DateInterval $interval) { // Do something } } Now allowed!
  • 77. PHP Stubs <?php // Stub class DateTime implements DateTimeInterface { /** @return DateTime */ public function add(DateInterval $interval) {} } // Your code class MyDateTime extends DateTime { public function add(DateInterval $interval) { // Do something } } Now allowed! A real return type would force all extending classes to specify it.
  • 78. PHP Stubs ● Ties in with many other efforts: – Union types critical for standard library signatures – Warning -> Error exception promotions avoid unnecessary return types – Resource to object migration allows use as types – Named arguments based on stubs default values