SlideShare uma empresa Scribd logo
1 de 73
Baixar para ler offline
Release schedule (tentative)
June 18th PHP 8.0 Alpha 1
July 28th PHP 8.0 Feature freeze
December 3rd PHP 8.0 Release
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.
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!

Mais conteúdo relacionado

Mais procurados

Being functional in PHP (DPC 2016)
Being functional in PHP (DPC 2016)Being functional in PHP (DPC 2016)
Being functional in PHP (DPC 2016)David de Boer
 
Opaque Pointers Are Coming
Opaque Pointers Are ComingOpaque Pointers Are Coming
Opaque Pointers Are ComingNikita 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
 
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
 
"How was it to switch from beautiful Perl to horrible JavaScript", Viktor Tur...
"How was it to switch from beautiful Perl to horrible JavaScript", Viktor Tur..."How was it to switch from beautiful Perl to horrible JavaScript", Viktor Tur...
"How was it to switch from beautiful Perl to horrible JavaScript", Viktor Tur...Fwdays
 
Zend Certification Preparation Tutorial
Zend Certification Preparation TutorialZend Certification Preparation Tutorial
Zend Certification Preparation TutorialLorna Mitchell
 
The promise of asynchronous PHP
The promise of asynchronous PHPThe promise of asynchronous PHP
The promise of asynchronous PHPWim Godden
 
Diving into HHVM Extensions (php[tek] 2016)
Diving into HHVM Extensions (php[tek] 2016)Diving into HHVM Extensions (php[tek] 2016)
Diving into HHVM Extensions (php[tek] 2016)James Titcumb
 
Jsphp 110312161301-phpapp02
Jsphp 110312161301-phpapp02Jsphp 110312161301-phpapp02
Jsphp 110312161301-phpapp02Seri Moth
 
PHP data structures (and the impact of php 7 on them), phpDay Verona 2015, Italy
PHP data structures (and the impact of php 7 on them), phpDay Verona 2015, ItalyPHP data structures (and the impact of php 7 on them), phpDay Verona 2015, Italy
PHP data structures (and the impact of php 7 on them), phpDay Verona 2015, ItalyPatrick Allaert
 
Creating own language made easy
Creating own language made easyCreating own language made easy
Creating own language made easyIngvar Stepanyan
 
Perl.Hacks.On.Vim
Perl.Hacks.On.VimPerl.Hacks.On.Vim
Perl.Hacks.On.VimLin Yo-An
 
Fantastic DSL in Python
Fantastic DSL in PythonFantastic DSL in Python
Fantastic DSL in Pythonkwatch
 
Create your own PHP extension, step by step - phpDay 2012 Verona
Create your own PHP extension, step by step - phpDay 2012 VeronaCreate your own PHP extension, step by step - phpDay 2012 Verona
Create your own PHP extension, step by step - phpDay 2012 VeronaPatrick Allaert
 
Cli the other sapi pbc11
Cli the other sapi pbc11Cli the other sapi pbc11
Cli the other sapi pbc11Combell NV
 
JSConf: All You Can Leet
JSConf: All You Can LeetJSConf: All You Can Leet
JSConf: All You Can Leetjohndaviddalton
 

Mais procurados (20)

Being functional in PHP (DPC 2016)
Being functional in PHP (DPC 2016)Being functional in PHP (DPC 2016)
Being functional in PHP (DPC 2016)
 
Opaque Pointers Are Coming
Opaque Pointers Are ComingOpaque Pointers Are Coming
Opaque Pointers Are Coming
 
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 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)
 
"How was it to switch from beautiful Perl to horrible JavaScript", Viktor Tur...
"How was it to switch from beautiful Perl to horrible JavaScript", Viktor Tur..."How was it to switch from beautiful Perl to horrible JavaScript", Viktor Tur...
"How was it to switch from beautiful Perl to horrible JavaScript", Viktor Tur...
 
Zend Certification Preparation Tutorial
Zend Certification Preparation TutorialZend Certification Preparation Tutorial
Zend Certification Preparation Tutorial
 
The promise of asynchronous PHP
The promise of asynchronous PHPThe promise of asynchronous PHP
The promise of asynchronous PHP
 
Diving into HHVM Extensions (php[tek] 2016)
Diving into HHVM Extensions (php[tek] 2016)Diving into HHVM Extensions (php[tek] 2016)
Diving into HHVM Extensions (php[tek] 2016)
 
Jsphp 110312161301-phpapp02
Jsphp 110312161301-phpapp02Jsphp 110312161301-phpapp02
Jsphp 110312161301-phpapp02
 
PHP data structures (and the impact of php 7 on them), phpDay Verona 2015, Italy
PHP data structures (and the impact of php 7 on them), phpDay Verona 2015, ItalyPHP data structures (and the impact of php 7 on them), phpDay Verona 2015, Italy
PHP data structures (and the impact of php 7 on them), phpDay Verona 2015, Italy
 
Creating own language made easy
Creating own language made easyCreating own language made easy
Creating own language made easy
 
Perl.Hacks.On.Vim
Perl.Hacks.On.VimPerl.Hacks.On.Vim
Perl.Hacks.On.Vim
 
Introduction in php
Introduction in phpIntroduction in php
Introduction in php
 
Your code is not a string
Your code is not a stringYour code is not a string
Your code is not a string
 
Fantastic DSL in Python
Fantastic DSL in PythonFantastic DSL in Python
Fantastic DSL in Python
 
Create your own PHP extension, step by step - phpDay 2012 Verona
Create your own PHP extension, step by step - phpDay 2012 VeronaCreate your own PHP extension, step by step - phpDay 2012 Verona
Create your own PHP extension, step by step - phpDay 2012 Verona
 
Cli the other sapi pbc11
Cli the other sapi pbc11Cli the other sapi pbc11
Cli the other sapi pbc11
 
SPL, not a bridge too far
SPL, not a bridge too farSPL, not a bridge too far
SPL, not a bridge too far
 
JSConf: All You Can Leet
JSConf: All You Can LeetJSConf: All You Can Leet
JSConf: All You Can Leet
 

Semelhante a What's new in PHP 8.0?

PHP 8: Process & Fixing Insanity
PHP 8: Process & Fixing InsanityPHP 8: Process & Fixing Insanity
PHP 8: Process & Fixing InsanityGeorgePeterBanyard
 
Living With Legacy Code
Living With Legacy CodeLiving With Legacy Code
Living With Legacy CodeRowan Merewood
 
API first with Swagger and Scala by Slava Schmidt
API first with Swagger and Scala by  Slava SchmidtAPI first with Swagger and Scala by  Slava Schmidt
API first with Swagger and Scala by Slava SchmidtJavaDayUA
 
Mirror, mirror on the wall - Building a new PHP reflection library (Nomad PHP...
Mirror, mirror on the wall - Building a new PHP reflection library (Nomad PHP...Mirror, mirror on the wall - Building a new PHP reflection library (Nomad PHP...
Mirror, mirror on the wall - Building a new PHP reflection library (Nomad PHP...James Titcumb
 
Unit Testing from Setup to Deployment
Unit Testing from Setup to DeploymentUnit Testing from Setup to Deployment
Unit Testing from Setup to DeploymentMark Niebergall
 
Lambda Chops - Recipes for Simpler, More Expressive Code
Lambda Chops - Recipes for Simpler, More Expressive CodeLambda Chops - Recipes for Simpler, More Expressive Code
Lambda Chops - Recipes for Simpler, More Expressive CodeIan Robertson
 
Building Testable PHP Applications
Building Testable PHP ApplicationsBuilding Testable PHP Applications
Building Testable PHP Applicationschartjes
 
How to write not breakable unit tests
How to write not breakable unit testsHow to write not breakable unit tests
How to write not breakable unit testsRafal Ksiazek
 
Object Oriented PHP - PART-2
Object Oriented PHP - PART-2Object Oriented PHP - PART-2
Object Oriented PHP - PART-2Jalpesh Vasa
 
Drupaljam xl 2019 presentation multilingualism makes better programmers
Drupaljam xl 2019 presentation   multilingualism makes better programmersDrupaljam xl 2019 presentation   multilingualism makes better programmers
Drupaljam xl 2019 presentation multilingualism makes better programmersAlexander Varwijk
 
Introduction to Javascript
Introduction to JavascriptIntroduction to Javascript
Introduction to JavascriptAmit Tyagi
 
SystemVerilog OOP Ovm Features Summary
SystemVerilog OOP Ovm Features SummarySystemVerilog OOP Ovm Features Summary
SystemVerilog OOP Ovm Features SummaryAmal Khailtash
 
The Swift Compiler and Standard Library
The Swift Compiler and Standard LibraryThe Swift Compiler and Standard Library
The Swift Compiler and Standard LibrarySantosh Rajan
 
FP in Java - Project Lambda and beyond
FP in Java - Project Lambda and beyondFP in Java - Project Lambda and beyond
FP in Java - Project Lambda and beyondMario Fusco
 
Leveling Up With Unit Testing - php[tek] 2023
Leveling Up With Unit Testing - php[tek] 2023Leveling Up With Unit Testing - php[tek] 2023
Leveling Up With Unit Testing - php[tek] 2023Mark Niebergall
 
Functional Javascript
Functional JavascriptFunctional Javascript
Functional Javascriptguest4d57e6
 
Xopus Application Framework
Xopus Application FrameworkXopus Application Framework
Xopus Application FrameworkJady Yang
 

Semelhante a What's new in PHP 8.0? (20)

PHP 8: Process & Fixing Insanity
PHP 8: Process & Fixing InsanityPHP 8: Process & Fixing Insanity
PHP 8: Process & Fixing Insanity
 
Living With Legacy Code
Living With Legacy CodeLiving With Legacy Code
Living With Legacy Code
 
API first with Swagger and Scala by Slava Schmidt
API first with Swagger and Scala by  Slava SchmidtAPI first with Swagger and Scala by  Slava Schmidt
API first with Swagger and Scala by Slava Schmidt
 
Mirror, mirror on the wall - Building a new PHP reflection library (Nomad PHP...
Mirror, mirror on the wall - Building a new PHP reflection library (Nomad PHP...Mirror, mirror on the wall - Building a new PHP reflection library (Nomad PHP...
Mirror, mirror on the wall - Building a new PHP reflection library (Nomad PHP...
 
Unit Testing from Setup to Deployment
Unit Testing from Setup to DeploymentUnit Testing from Setup to Deployment
Unit Testing from Setup to Deployment
 
Lambda Chops - Recipes for Simpler, More Expressive Code
Lambda Chops - Recipes for Simpler, More Expressive CodeLambda Chops - Recipes for Simpler, More Expressive Code
Lambda Chops - Recipes for Simpler, More Expressive Code
 
Building Testable PHP Applications
Building Testable PHP ApplicationsBuilding Testable PHP Applications
Building Testable PHP Applications
 
Hacking with hhvm
Hacking with hhvmHacking with hhvm
Hacking with hhvm
 
How to write not breakable unit tests
How to write not breakable unit testsHow to write not breakable unit tests
How to write not breakable unit tests
 
Object Oriented PHP - PART-2
Object Oriented PHP - PART-2Object Oriented PHP - PART-2
Object Oriented PHP - PART-2
 
Drupaljam xl 2019 presentation multilingualism makes better programmers
Drupaljam xl 2019 presentation   multilingualism makes better programmersDrupaljam xl 2019 presentation   multilingualism makes better programmers
Drupaljam xl 2019 presentation multilingualism makes better programmers
 
Effective PHP. Part 1
Effective PHP. Part 1Effective PHP. Part 1
Effective PHP. Part 1
 
Introduction to Javascript
Introduction to JavascriptIntroduction to Javascript
Introduction to Javascript
 
Php basics
Php basicsPhp basics
Php basics
 
SystemVerilog OOP Ovm Features Summary
SystemVerilog OOP Ovm Features SummarySystemVerilog OOP Ovm Features Summary
SystemVerilog OOP Ovm Features Summary
 
The Swift Compiler and Standard Library
The Swift Compiler and Standard LibraryThe Swift Compiler and Standard Library
The Swift Compiler and Standard Library
 
FP in Java - Project Lambda and beyond
FP in Java - Project Lambda and beyondFP in Java - Project Lambda and beyond
FP in Java - Project Lambda and beyond
 
Leveling Up With Unit Testing - php[tek] 2023
Leveling Up With Unit Testing - php[tek] 2023Leveling Up With Unit Testing - php[tek] 2023
Leveling Up With Unit Testing - php[tek] 2023
 
Functional Javascript
Functional JavascriptFunctional Javascript
Functional Javascript
 
Xopus Application Framework
Xopus Application FrameworkXopus Application Framework
Xopus Application Framework
 

Último

Manulife - Insurer Transformation Award 2024
Manulife - Insurer Transformation Award 2024Manulife - Insurer Transformation Award 2024
Manulife - Insurer Transformation Award 2024The Digital Insurer
 
Corporate and higher education May webinar.pptx
Corporate and higher education May webinar.pptxCorporate and higher education May webinar.pptx
Corporate and higher education May webinar.pptxRustici Software
 
"I see eyes in my soup": How Delivery Hero implemented the safety system for ...
"I see eyes in my soup": How Delivery Hero implemented the safety system for ..."I see eyes in my soup": How Delivery Hero implemented the safety system for ...
"I see eyes in my soup": How Delivery Hero implemented the safety system for ...Zilliz
 
ProductAnonymous-April2024-WinProductDiscovery-MelissaKlemke
ProductAnonymous-April2024-WinProductDiscovery-MelissaKlemkeProductAnonymous-April2024-WinProductDiscovery-MelissaKlemke
ProductAnonymous-April2024-WinProductDiscovery-MelissaKlemkeProduct Anonymous
 
Architecting Cloud Native Applications
Architecting Cloud Native ApplicationsArchitecting Cloud Native Applications
Architecting Cloud Native ApplicationsWSO2
 
Apidays New York 2024 - The Good, the Bad and the Governed by David O'Neill, ...
Apidays New York 2024 - The Good, the Bad and the Governed by David O'Neill, ...Apidays New York 2024 - The Good, the Bad and the Governed by David O'Neill, ...
Apidays New York 2024 - The Good, the Bad and the Governed by David O'Neill, ...apidays
 
Apidays New York 2024 - Accelerating FinTech Innovation by Vasa Krishnan, Fin...
Apidays New York 2024 - Accelerating FinTech Innovation by Vasa Krishnan, Fin...Apidays New York 2024 - Accelerating FinTech Innovation by Vasa Krishnan, Fin...
Apidays New York 2024 - Accelerating FinTech Innovation by Vasa Krishnan, Fin...apidays
 
Cyberprint. Dark Pink Apt Group [EN].pdf
Cyberprint. Dark Pink Apt Group [EN].pdfCyberprint. Dark Pink Apt Group [EN].pdf
Cyberprint. Dark Pink Apt Group [EN].pdfOverkill Security
 
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
 
Ransomware_Q4_2023. The report. [EN].pdf
Ransomware_Q4_2023. The report. [EN].pdfRansomware_Q4_2023. The report. [EN].pdf
Ransomware_Q4_2023. The report. [EN].pdfOverkill Security
 
AXA XL - Insurer Innovation Award Americas 2024
AXA XL - Insurer Innovation Award Americas 2024AXA XL - Insurer Innovation Award Americas 2024
AXA XL - Insurer Innovation Award Americas 2024The Digital Insurer
 
DEV meet-up UiPath Document Understanding May 7 2024 Amsterdam
DEV meet-up UiPath Document Understanding May 7 2024 AmsterdamDEV meet-up UiPath Document Understanding May 7 2024 Amsterdam
DEV meet-up UiPath Document Understanding May 7 2024 AmsterdamUiPathCommunity
 
DBX First Quarter 2024 Investor Presentation
DBX First Quarter 2024 Investor PresentationDBX First Quarter 2024 Investor Presentation
DBX First Quarter 2024 Investor PresentationDropbox
 
EMPOWERMENT TECHNOLOGY GRADE 11 QUARTER 2 REVIEWER
EMPOWERMENT TECHNOLOGY GRADE 11 QUARTER 2 REVIEWEREMPOWERMENT TECHNOLOGY GRADE 11 QUARTER 2 REVIEWER
EMPOWERMENT TECHNOLOGY GRADE 11 QUARTER 2 REVIEWERMadyBayot
 
Connector Corner: Accelerate revenue generation using UiPath API-centric busi...
Connector Corner: Accelerate revenue generation using UiPath API-centric busi...Connector Corner: Accelerate revenue generation using UiPath API-centric busi...
Connector Corner: Accelerate revenue generation using UiPath API-centric busi...DianaGray10
 
Finding Java's Hidden Performance Traps @ DevoxxUK 2024
Finding Java's Hidden Performance Traps @ DevoxxUK 2024Finding Java's Hidden Performance Traps @ DevoxxUK 2024
Finding Java's Hidden Performance Traps @ DevoxxUK 2024Victor Rentea
 
AWS Community Day CPH - Three problems of Terraform
AWS Community Day CPH - Three problems of TerraformAWS Community Day CPH - Three problems of Terraform
AWS Community Day CPH - Three problems of TerraformAndrey Devyatkin
 
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
 
Cloud Frontiers: A Deep Dive into Serverless Spatial Data and FME
Cloud Frontiers:  A Deep Dive into Serverless Spatial Data and FMECloud Frontiers:  A Deep Dive into Serverless Spatial Data and FME
Cloud Frontiers: A Deep Dive into Serverless Spatial Data and FMESafe Software
 

Último (20)

Manulife - Insurer Transformation Award 2024
Manulife - Insurer Transformation Award 2024Manulife - Insurer Transformation Award 2024
Manulife - Insurer Transformation Award 2024
 
Corporate and higher education May webinar.pptx
Corporate and higher education May webinar.pptxCorporate and higher education May webinar.pptx
Corporate and higher education May webinar.pptx
 
"I see eyes in my soup": How Delivery Hero implemented the safety system for ...
"I see eyes in my soup": How Delivery Hero implemented the safety system for ..."I see eyes in my soup": How Delivery Hero implemented the safety system for ...
"I see eyes in my soup": How Delivery Hero implemented the safety system for ...
 
ProductAnonymous-April2024-WinProductDiscovery-MelissaKlemke
ProductAnonymous-April2024-WinProductDiscovery-MelissaKlemkeProductAnonymous-April2024-WinProductDiscovery-MelissaKlemke
ProductAnonymous-April2024-WinProductDiscovery-MelissaKlemke
 
Architecting Cloud Native Applications
Architecting Cloud Native ApplicationsArchitecting Cloud Native Applications
Architecting Cloud Native Applications
 
Apidays New York 2024 - The Good, the Bad and the Governed by David O'Neill, ...
Apidays New York 2024 - The Good, the Bad and the Governed by David O'Neill, ...Apidays New York 2024 - The Good, the Bad and the Governed by David O'Neill, ...
Apidays New York 2024 - The Good, the Bad and the Governed by David O'Neill, ...
 
Apidays New York 2024 - Accelerating FinTech Innovation by Vasa Krishnan, Fin...
Apidays New York 2024 - Accelerating FinTech Innovation by Vasa Krishnan, Fin...Apidays New York 2024 - Accelerating FinTech Innovation by Vasa Krishnan, Fin...
Apidays New York 2024 - Accelerating FinTech Innovation by Vasa Krishnan, Fin...
 
Cyberprint. Dark Pink Apt Group [EN].pdf
Cyberprint. Dark Pink Apt Group [EN].pdfCyberprint. Dark Pink Apt Group [EN].pdf
Cyberprint. Dark Pink Apt Group [EN].pdf
 
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
 
Ransomware_Q4_2023. The report. [EN].pdf
Ransomware_Q4_2023. The report. [EN].pdfRansomware_Q4_2023. The report. [EN].pdf
Ransomware_Q4_2023. The report. [EN].pdf
 
AXA XL - Insurer Innovation Award Americas 2024
AXA XL - Insurer Innovation Award Americas 2024AXA XL - Insurer Innovation Award Americas 2024
AXA XL - Insurer Innovation Award Americas 2024
 
DEV meet-up UiPath Document Understanding May 7 2024 Amsterdam
DEV meet-up UiPath Document Understanding May 7 2024 AmsterdamDEV meet-up UiPath Document Understanding May 7 2024 Amsterdam
DEV meet-up UiPath Document Understanding May 7 2024 Amsterdam
 
DBX First Quarter 2024 Investor Presentation
DBX First Quarter 2024 Investor PresentationDBX First Quarter 2024 Investor Presentation
DBX First Quarter 2024 Investor Presentation
 
EMPOWERMENT TECHNOLOGY GRADE 11 QUARTER 2 REVIEWER
EMPOWERMENT TECHNOLOGY GRADE 11 QUARTER 2 REVIEWEREMPOWERMENT TECHNOLOGY GRADE 11 QUARTER 2 REVIEWER
EMPOWERMENT TECHNOLOGY GRADE 11 QUARTER 2 REVIEWER
 
Connector Corner: Accelerate revenue generation using UiPath API-centric busi...
Connector Corner: Accelerate revenue generation using UiPath API-centric busi...Connector Corner: Accelerate revenue generation using UiPath API-centric busi...
Connector Corner: Accelerate revenue generation using UiPath API-centric busi...
 
+971581248768>> SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHA...
+971581248768>> SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHA...+971581248768>> SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHA...
+971581248768>> SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHA...
 
Finding Java's Hidden Performance Traps @ DevoxxUK 2024
Finding Java's Hidden Performance Traps @ DevoxxUK 2024Finding Java's Hidden Performance Traps @ DevoxxUK 2024
Finding Java's Hidden Performance Traps @ DevoxxUK 2024
 
AWS Community Day CPH - Three problems of Terraform
AWS Community Day CPH - Three problems of TerraformAWS Community Day CPH - Three problems of Terraform
AWS Community Day CPH - Three problems of Terraform
 
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
 
Cloud Frontiers: A Deep Dive into Serverless Spatial Data and FME
Cloud Frontiers:  A Deep Dive into Serverless Spatial Data and FMECloud Frontiers:  A Deep Dive into Serverless Spatial Data and FME
Cloud Frontiers: A Deep Dive into Serverless Spatial Data and FME
 

What's new in PHP 8.0?

  • 1.
  • 2.
  • 3.
  • 4. Release schedule (tentative) June 18th PHP 8.0 Alpha 1 July 28th PHP 8.0 Feature freeze December 3rd PHP 8.0 Release
  • 5.
  • 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.
  • 69.
  • 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)