SlideShare a Scribd company logo
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?"
Release schedule (tentative)
June 18th PHP 8.0 Alpha 1
July 28th PHP 8.0 Feature freeze
December 3rd PHP 8.0 Release
Nikita Popov "What’s new in PHP 8.0?"
Just-In-Time (JIT) Compiler
●
Compiles PHP code to x86 machine code
●
Performance improvements mostly apply to
math heavy code
Just-In-Time (JIT) Compiler
●
Compiles PHP code to x86 machine code
●
Performance improvements mostly apply to
math heavy code
●
Part of opcache:
– opcache.jit=on
– opcache.jit_buffer_size=128M
Attributes
<?php
/** @Entity */
class User {
/**
* @Id
* @Column(type="integer")
* @GeneratedValue
*/
private $id;
}
Attributes
<?php
use DoctrineORMAttributes as ORM;
<<ORMEntity>>
class User {
<<ORMId>>
<<ORMColumn("integer")>>
<<ORMGeneratedValue>>
private $id;
}
Attributes
<?php
use DoctrineORMAttributes as ORM;
<<ORMEntity>>
class User {
<<ORMId>>
<<ORMColumn("integer")>>
<<ORMGeneratedValue>>
private $id;
}
Class name
Constructor arguments
Attributes
<?php
namespace DoctrineORMAttributes;
use PhpAttribute;
<<PhpAttribute>>
class Column {
public function __construct(string $type) { … }
}
Attributes
<?php
$rc = new ReflectionClass(User::class);
foreach ($rc->getAttributes() as $attr) {
var_dump($attr->getName());
// => "DoctrineORMAttributesEntity"
var_dump($attr->getArguments());
// => []
var_dump($attr->newInstance());
// object(DoctrineORMAttributesEntity) ...
}
Attributes
<?php
$rc = new ReflectionClass(User::class);
foreach ($rc->getAttributes() as $attr) {
var_dump($attr->getName());
// => "DoctrineORMAttributesEntity"
var_dump($attr->getArguments());
// => []
var_dump($attr->newInstance());
// object(DoctrineORMAttributesEntity) ...
}
Attribute validation happens HERE.
Attributes: Limitations
●
No named parameters:
– @Column(type="string", unique=true)
– <<Column("string", ['unique' => true])>>
Attributes: Limitations
●
No named parameters:
– @Column(type="string", unique=true)
– <<Column("string", ['unique' => true])>>
●
No nested attributes:
– @AssertAll({ @AssertNotBlank,
@AssertLength(min=5) })
Attributes: Limitations
●
No named parameters:
– @Column(type="string", unique=true)
– <<Column("string", ['unique' => true])>>
●
No nested attributes:
– @AssertAll({ @AssertNotBlank,
@AssertLength(min=5) })
"new" currently not supported in constant expressions
Attributes: Use-Cases
●
Replaces phpdoc annotations in Doctrine,
Symfony, etc…
●
May add internal attributes:
– <<Deprecated("Use xyz instead")>>
– <<Jit>>, <<NoJit>>
Union Types
●
Existing union types:
– ?Type = Type|null
– iterable = Traversable|array
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
●
Tricky interaction with "weak types"
●
Type must be part of union, or...
●
Scalars are coerced to int, float, string, bool, in
order of preference
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
// Mixed is a common approximation for generic functions:
function array_reduce<K, V, R>(
array<K, V> $arg,
callable(R, V): R $callback, R $initial = null
): R {}
Mixed Type
<?php
// Mixed is a common approximation for generic functions:
function array_reduce<K, V, R>(
array<K, V> $arg,
callable(R, V): R $callback, R $initial = null
): R {}
// Back down to earth:
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
// Wither pattern:
class Test {
public function withWhatever($whatever): static {
$clone = clone $this;
$clone->whatever = $whatever;
return $clone;
}
}
Static Return Type
<?php
// Fluent methods:
class Test {
public function doWhatever(): static {
// Do whatever.
return $this;
}
}
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 in parameters lists
now allowed
str_contains etc.
<?php
function str_contains(
string $haystack, string $needle
): bool {
return false !== strpos($haystack, $needle);
}
str_contains etc.
<?php
function str_contains(
string $haystack, string $needle
): bool {}
function str_starts_with(
string $haystack, string $needle
): bool {}
function str_ends_with(
string $haystack, string $needle
): bool {}
str_contains etc.
●
No multibyte variants
●
All of these functions are safe to use on UTF-8!
(If you don't use UTF-8, that's your problem)
WeakMap
<?php
$map = new WeakMap;
$obj = new stdClass;
$map[$obj] = $dataForObj;
unset($obj); // $obj automatically dropped from WeakMap!
WeakMap
<?php
class FooBar {
private WeakMap $cache;
public function getSomethingWithCaching(object $obj) {
return $this->cache[$obj]
??= $this->computeSomethingExpensive($obj);
}
}
Backwards Compatibility Breaks
●
Everything deprecated before PHP 8.0 has
been removed!
●
Full list:
https://github.com/php/php-src/blob/master/UPGRADING
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
(This is why we do not support a "resource"
type.)
Resource To Object Migration
●
Usually based on "opaque objects"
●
Actual object-oriented APIs may be added later
Resource To Object Migration
●
Migrated in previous versions
– EnchantBroker, EnchantDictionary
– GdImage
– SysvMessageQueue
– SysvSemaphore
– XmlParser
– XmlWriter (already had an OO API)
– … more are in progress
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
We'll 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 ($num)
// must be greater than or equal to 0
function array_fill(
int $start_index, int $num, 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.
Nikita Popov "What’s new in PHP 8.0?"
3v4l.org
Travis CI
php:
- nightly
install:
- |
if [ $TRAVIS_PHP_VERSION = 'nightly' ]; then
composer install --ignore-platform-reqs;
else
composer install;
fi
Many libraries are not formally
compatible with PHP 8 (yet)
Docker
●
https://github.com/devilbox/docker-php-fpm-8.0
Thank You!

More Related Content

PDF
Effective Scala (JavaDay Riga 2013)
PDF
Javascript basic course
PPTX
Java Annotations and Pre-processing
PPTX
Java best practices
PDF
Quick swift tour
PDF
Serializing EMF models with Xtext
PDF
Flutter 是什麼?用 Flutter 會省到時間嗎? @ GDG Devfest2020
PPT
Groovy presentation
Effective Scala (JavaDay Riga 2013)
Javascript basic course
Java Annotations and Pre-processing
Java best practices
Quick swift tour
Serializing EMF models with Xtext
Flutter 是什麼?用 Flutter 會省到時間嗎? @ GDG Devfest2020
Groovy presentation

What's hot (20)

DOC
EMF Tips n Tricks
PDF
Basics of JavaScript
PPT
A Deeper look into Javascript Basics
PDF
A Re-Introduction to JavaScript
PPT
The JavaScript Programming Language
PDF
JavaScript Programming
PPT
Introduction to Javascript
PPTX
Groovy Programming Language
PDF
Working with Cocoa and Objective-C
PPT
Intermediate JavaScript
PPTX
Javascript Basics
PDF
JavaScript Basics and Best Practices - CC FE & UX
PDF
The Xtext Grammar Language
PPT
JavaScript Basics
PDF
walkmod - JUG talk
PDF
A Gentle Introduction To Object Oriented Php
PDF
Effective Scala: Programming Patterns
PDF
Fundamental JavaScript [UTC, March 2014]
PPTX
002. Introducere in type script
PPT
EMF Tips n Tricks
Basics of JavaScript
A Deeper look into Javascript Basics
A Re-Introduction to JavaScript
The JavaScript Programming Language
JavaScript Programming
Introduction to Javascript
Groovy Programming Language
Working with Cocoa and Objective-C
Intermediate JavaScript
Javascript Basics
JavaScript Basics and Best Practices - CC FE & UX
The Xtext Grammar Language
JavaScript Basics
walkmod - JUG talk
A Gentle Introduction To Object Oriented Php
Effective Scala: Programming Patterns
Fundamental JavaScript [UTC, March 2014]
002. Introducere in type script
Ad

Similar to Nikita Popov "What’s new in PHP 8.0?" (20)

PDF
PHP 8: Process & Fixing Insanity
PDF
What's new in PHP 8.0?
PDF
Living With Legacy Code
PDF
Mirror, mirror on the wall: Building a new PHP reflection library (DPC 2016)
PDF
API first with Swagger and Scala by Slava Schmidt
PDF
Mirror, mirror on the wall - Building a new PHP reflection library (Nomad PHP...
PDF
Unit Testing from Setup to Deployment
ODP
Lambda Chops - Recipes for Simpler, More Expressive Code
PDF
Building Testable PHP Applications
PPT
Hacking with hhvm
PPTX
How to write not breakable unit tests
PDF
Object Oriented PHP - PART-2
PDF
Drupaljam xl 2019 presentation multilingualism makes better programmers
PDF
Effective PHP. Part 1
PDF
Diving into HHVM Extensions (php[tek] 2016)
PPTX
Php basics
PPT
SystemVerilog OOP Ovm Features Summary
PDF
The Swift Compiler and Standard Library
PDF
FP in Java - Project Lambda and beyond
PDF
Leveling Up With Unit Testing - php[tek] 2023
PHP 8: Process & Fixing Insanity
What's new in PHP 8.0?
Living With Legacy Code
Mirror, mirror on the wall: Building a new PHP reflection library (DPC 2016)
API first with Swagger and Scala by Slava Schmidt
Mirror, mirror on the wall - Building a new PHP reflection library (Nomad PHP...
Unit Testing from Setup to Deployment
Lambda Chops - Recipes for Simpler, More Expressive Code
Building Testable PHP Applications
Hacking with hhvm
How to write not breakable unit tests
Object Oriented PHP - PART-2
Drupaljam xl 2019 presentation multilingualism makes better programmers
Effective PHP. Part 1
Diving into HHVM Extensions (php[tek] 2016)
Php basics
SystemVerilog OOP Ovm Features Summary
The Swift Compiler and Standard Library
FP in Java - Project Lambda and beyond
Leveling Up With Unit Testing - php[tek] 2023
Ad

More from Fwdays (20)

PDF
"Mastering UI Complexity: State Machines and Reactive Patterns at Grammarly",...
PDF
"Effect, Fiber & Schema: tactical and technical characteristics of Effect.ts"...
PPTX
"Computer Use Agents: From SFT to Classic RL", Maksym Shamrai
PPTX
"Як ми переписали Сільпо на Angular", Євген Русаков
PDF
"AI Transformation: Directions and Challenges", Pavlo Shaternik
PDF
"Validation and Observability of AI Agents", Oleksandr Denisyuk
PPTX
"Autonomy of LLM Agents: Current State and Future Prospects", Oles` Petriv
PDF
"Beyond English: Navigating the Challenges of Building a Ukrainian-language R...
PPTX
"Co-Authoring with a Machine: What I Learned from Writing a Book on Generativ...
PPTX
"Human-AI Collaboration Models for Better Decisions, Faster Workflows, and Cr...
PDF
"AI is already here. What will happen to your team (and your role) tomorrow?"...
PPTX
"Is it worth investing in AI in 2025?", Alexander Sharko
PDF
''Taming Explosive Growth: Building Resilience in a Hyper-Scaled Financial Pl...
PDF
"Scaling in space and time with Temporal", Andriy Lupa.pdf
PDF
"Database isolation: how we deal with hundreds of direct connections to the d...
PDF
"Scaling in space and time with Temporal", Andriy Lupa .pdf
PPTX
"Provisioning via DOT-Chain: from catering to drone marketplaces", Volodymyr ...
PPTX
" Observability with Elasticsearch: Best Practices for High-Load Platform", A...
PPTX
"How to survive Black Friday: preparing e-commerce for a peak season", Yurii ...
PPTX
"Istio Ambient Mesh in production: our way from Sidecar to Sidecar-less",Hlib...
"Mastering UI Complexity: State Machines and Reactive Patterns at Grammarly",...
"Effect, Fiber & Schema: tactical and technical characteristics of Effect.ts"...
"Computer Use Agents: From SFT to Classic RL", Maksym Shamrai
"Як ми переписали Сільпо на Angular", Євген Русаков
"AI Transformation: Directions and Challenges", Pavlo Shaternik
"Validation and Observability of AI Agents", Oleksandr Denisyuk
"Autonomy of LLM Agents: Current State and Future Prospects", Oles` Petriv
"Beyond English: Navigating the Challenges of Building a Ukrainian-language R...
"Co-Authoring with a Machine: What I Learned from Writing a Book on Generativ...
"Human-AI Collaboration Models for Better Decisions, Faster Workflows, and Cr...
"AI is already here. What will happen to your team (and your role) tomorrow?"...
"Is it worth investing in AI in 2025?", Alexander Sharko
''Taming Explosive Growth: Building Resilience in a Hyper-Scaled Financial Pl...
"Scaling in space and time with Temporal", Andriy Lupa.pdf
"Database isolation: how we deal with hundreds of direct connections to the d...
"Scaling in space and time with Temporal", Andriy Lupa .pdf
"Provisioning via DOT-Chain: from catering to drone marketplaces", Volodymyr ...
" Observability with Elasticsearch: Best Practices for High-Load Platform", A...
"How to survive Black Friday: preparing e-commerce for a peak season", Yurii ...
"Istio Ambient Mesh in production: our way from Sidecar to Sidecar-less",Hlib...

Recently uploaded (20)

PDF
GamePlan Trading System Review: Professional Trader's Honest Take
PDF
Empathic Computing: Creating Shared Understanding
PDF
Optimiser vos workloads AI/ML sur Amazon EC2 et AWS Graviton
PPTX
Big Data Technologies - Introduction.pptx
PDF
Unlocking AI with Model Context Protocol (MCP)
PDF
Shreyas Phanse Resume: Experienced Backend Engineer | Java • Spring Boot • Ka...
PDF
cuic standard and advanced reporting.pdf
PDF
Machine learning based COVID-19 study performance prediction
PDF
[발표본] 너의 과제는 클라우드에 있어_KTDS_김동현_20250524.pdf
PDF
Approach and Philosophy of On baking technology
PDF
Per capita expenditure prediction using model stacking based on satellite ima...
PDF
Blue Purple Modern Animated Computer Science Presentation.pdf.pdf
PDF
Advanced methodologies resolving dimensionality complications for autism neur...
PPTX
20250228 LYD VKU AI Blended-Learning.pptx
PDF
The Rise and Fall of 3GPP – Time for a Sabbatical?
PDF
Build a system with the filesystem maintained by OSTree @ COSCUP 2025
PPTX
VMware vSphere Foundation How to Sell Presentation-Ver1.4-2-14-2024.pptx
PDF
How UI/UX Design Impacts User Retention in Mobile Apps.pdf
PDF
Chapter 3 Spatial Domain Image Processing.pdf
PDF
Advanced IT Governance
GamePlan Trading System Review: Professional Trader's Honest Take
Empathic Computing: Creating Shared Understanding
Optimiser vos workloads AI/ML sur Amazon EC2 et AWS Graviton
Big Data Technologies - Introduction.pptx
Unlocking AI with Model Context Protocol (MCP)
Shreyas Phanse Resume: Experienced Backend Engineer | Java • Spring Boot • Ka...
cuic standard and advanced reporting.pdf
Machine learning based COVID-19 study performance prediction
[발표본] 너의 과제는 클라우드에 있어_KTDS_김동현_20250524.pdf
Approach and Philosophy of On baking technology
Per capita expenditure prediction using model stacking based on satellite ima...
Blue Purple Modern Animated Computer Science Presentation.pdf.pdf
Advanced methodologies resolving dimensionality complications for autism neur...
20250228 LYD VKU AI Blended-Learning.pptx
The Rise and Fall of 3GPP – Time for a Sabbatical?
Build a system with the filesystem maintained by OSTree @ COSCUP 2025
VMware vSphere Foundation How to Sell Presentation-Ver1.4-2-14-2024.pptx
How UI/UX Design Impacts User Retention in Mobile Apps.pdf
Chapter 3 Spatial Domain Image Processing.pdf
Advanced IT Governance

Nikita Popov "What’s new in PHP 8.0?"

  • 4. Release schedule (tentative) June 18th PHP 8.0 Alpha 1 July 28th PHP 8.0 Feature freeze December 3rd PHP 8.0 Release
  • 6. Just-In-Time (JIT) Compiler ● Compiles PHP code to x86 machine code ● Performance improvements mostly apply to math heavy code
  • 7. Just-In-Time (JIT) Compiler ● Compiles PHP code to x86 machine code ● Performance improvements mostly apply to math heavy code ● Part of opcache: – opcache.jit=on – opcache.jit_buffer_size=128M
  • 8. Attributes <?php /** @Entity */ class User { /** * @Id * @Column(type="integer") * @GeneratedValue */ private $id; }
  • 9. Attributes <?php use DoctrineORMAttributes as ORM; <<ORMEntity>> class User { <<ORMId>> <<ORMColumn("integer")>> <<ORMGeneratedValue>> private $id; }
  • 10. Attributes <?php use DoctrineORMAttributes as ORM; <<ORMEntity>> class User { <<ORMId>> <<ORMColumn("integer")>> <<ORMGeneratedValue>> private $id; } Class name Constructor arguments
  • 11. Attributes <?php namespace DoctrineORMAttributes; use PhpAttribute; <<PhpAttribute>> class Column { public function __construct(string $type) { … } }
  • 12. Attributes <?php $rc = new ReflectionClass(User::class); foreach ($rc->getAttributes() as $attr) { var_dump($attr->getName()); // => "DoctrineORMAttributesEntity" var_dump($attr->getArguments()); // => [] var_dump($attr->newInstance()); // object(DoctrineORMAttributesEntity) ... }
  • 13. Attributes <?php $rc = new ReflectionClass(User::class); foreach ($rc->getAttributes() as $attr) { var_dump($attr->getName()); // => "DoctrineORMAttributesEntity" var_dump($attr->getArguments()); // => [] var_dump($attr->newInstance()); // object(DoctrineORMAttributesEntity) ... } Attribute validation happens HERE.
  • 14. Attributes: Limitations ● No named parameters: – @Column(type="string", unique=true) – <<Column("string", ['unique' => true])>>
  • 15. Attributes: Limitations ● No named parameters: – @Column(type="string", unique=true) – <<Column("string", ['unique' => true])>> ● No nested attributes: – @AssertAll({ @AssertNotBlank, @AssertLength(min=5) })
  • 16. Attributes: Limitations ● No named parameters: – @Column(type="string", unique=true) – <<Column("string", ['unique' => true])>> ● No nested attributes: – @AssertAll({ @AssertNotBlank, @AssertLength(min=5) }) "new" currently not supported in constant expressions
  • 17. Attributes: Use-Cases ● Replaces phpdoc annotations in Doctrine, Symfony, etc… ● May add internal attributes: – <<Deprecated("Use xyz instead")>> – <<Jit>>, <<NoJit>>
  • 18. Union Types ● Existing union types: – ?Type = Type|null – iterable = Traversable|array
  • 19. 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; } }
  • 20. 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; } }
  • 21. Union Types <?php function strpos( string $haystack, string $needle, int $offset = 0 ): int|false {}
  • 22. Union Types <?php function strpos( string $haystack, string $needle, int $offset = 0 ): int|false {} Very common in standard library
  • 23. 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
  • 24. Union Types ● Tricky interaction with "weak types" ● Type must be part of union, or... ● Scalars are coerced to int, float, string, bool, in order of preference
  • 25. 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
  • 26. 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
  • 27. Mixed Type ● Distinguishes between: – Type is missing because I didn't add one yet – This function really does accept any value
  • 28. Mixed Type <?php function var_dump(mixed $value, mixed ...$value): void {} function serialize(mixed $value): string {}
  • 29. Mixed Type <?php // Mixed is a common approximation for generic functions: function array_reduce<K, V, R>( array<K, V> $arg, callable(R, V): R $callback, R $initial = null ): R {}
  • 30. Mixed Type <?php // Mixed is a common approximation for generic functions: function array_reduce<K, V, R>( array<K, V> $arg, callable(R, V): R $callback, R $initial = null ): R {} // Back down to earth: function array_reduce( array $arg, callable $callback, mixed $initial = null ): mixed {}
  • 31. 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
  • 32. 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() {} }
  • 33. 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
  • 34. Static Return Type <?php // Named constructor: class TestParent { public function createFromWhatever($whatever): static { return new static($whatever); } }
  • 35. 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!
  • 36. Static Return Type <?php // Wither pattern: class Test { public function withWhatever($whatever): static { $clone = clone $this; $clone->whatever = $whatever; return $clone; } }
  • 37. Static Return Type <?php // Fluent methods: class Test { public function doWhatever(): static { // Do whatever. return $this; } }
  • 38. 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; } }
  • 39. Constructor Promotion <?php class Point { public function __construct( public float $x = 0.0, public float $y = 0.0, public float $z = 0.0, ) {} }
  • 40. 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 in parameters lists now allowed
  • 41. str_contains etc. <?php function str_contains( string $haystack, string $needle ): bool { return false !== strpos($haystack, $needle); }
  • 42. str_contains etc. <?php function str_contains( string $haystack, string $needle ): bool {} function str_starts_with( string $haystack, string $needle ): bool {} function str_ends_with( string $haystack, string $needle ): bool {}
  • 43. str_contains etc. ● No multibyte variants ● All of these functions are safe to use on UTF-8! (If you don't use UTF-8, that's your problem)
  • 44. WeakMap <?php $map = new WeakMap; $obj = new stdClass; $map[$obj] = $dataForObj; unset($obj); // $obj automatically dropped from WeakMap!
  • 45. WeakMap <?php class FooBar { private WeakMap $cache; public function getSomethingWithCaching(object $obj) { return $this->cache[$obj] ??= $this->computeSomethingExpensive($obj); } }
  • 46. Backwards Compatibility Breaks ● Everything deprecated before PHP 8.0 has been removed! ● Full list: https://github.com/php/php-src/blob/master/UPGRADING
  • 47. Resource To Object Migration ● Long term goal: Convert all resources to objects ● Objects are type-safe and have much better internal support
  • 48. Resource To Object Migration ● Long term goal: Convert all resources to objects ● Objects are type-safe and have much better internal support (This is why we do not support a "resource" type.)
  • 49. Resource To Object Migration ● Usually based on "opaque objects" ● Actual object-oriented APIs may be added later
  • 50. Resource To Object Migration ● Migrated in previous versions – EnchantBroker, EnchantDictionary – GdImage – SysvMessageQueue – SysvSemaphore – XmlParser – XmlWriter (already had an OO API) – … more are in progress
  • 51. Resource To Object Migration <?php $image = imagecreatefrompng($path); if (!is_resource($image)) { throw new MalformedImageException; }
  • 52. Resource To Object Migration <?php $image = imagecreatefrompng($path); if (!is_resource($image)) { throw new MalformedImageException; } Now a GdImage object on success We'll always throw...
  • 53. Resource To Object Migration <?php $image = imagecreatefrompng($path); if (false === $image) { throw new MalformedImageException; }
  • 54. Warning → Error exception ● Many warnings converted to Error exceptions – TypeError – ValueError
  • 55. 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
  • 56. Warning → Error exception <?php var_dump(strlen([])); // Warning: strlen() expects parameter 1 to be string, // array given // NULL function strlen(string $str): int|null {}
  • 57. 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 {}
  • 58. 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 {}
  • 59. Warning → Error exception <?php var_dump(array_fill(0, -100, "foobar")); // Uncaught ValueError: array_fill(): Argument #2 ($num) // must be greater than or equal to 0 function array_fill( int $start_index, int $num, mixed $value ): array {}
  • 60. 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)
  • 61. 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!
  • 62. PHP Stubs ● PHP stub files specify function signatures for internal functions/methods ● Used to generate C code for function registration
  • 63. PHP Stubs <?php function array_search( mixed $needle, array $haystack, bool $strict = false ): int|string|false {}
  • 64. 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()
  • 65. PHP Stubs ● Data available through Reflection: – ReflectionFunction::getReturnType() – ReflectionParameter::getType() – ReflectionParameter::getDefaultValue()
  • 66. 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 } }
  • 67. 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!
  • 68. 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.
  • 71. Travis CI php: - nightly install: - | if [ $TRAVIS_PHP_VERSION = 'nightly' ]; then composer install --ignore-platform-reqs; else composer install; fi Many libraries are not formally compatible with PHP 8 (yet)