Slide 1

Slide 1 text

What's new in PHP 8.3

Slide 2

Slide 2 text

About me — ! Christian Leo-Pernold — "#$%&'()*⛰,-. — / @[email protected] — ⭐ github.com/mazedlx — 1 mazedlx.net — 2 https://www.linkedin.com/in/ mazedlx 2/54

Slide 3

Slide 3 text

Version History and EOL 1,2 5.6 2018-12-31 (5 years ago) 7.0 2019-01-19 (5 years ago) 7.1 2019-12-31 (4 years ago) 7.2 2020-11-30 (3 years ago) 7.3 2021-12-06 (2 years ago) 7.4 2022-11-28 (1 year ago) 8.0 2023-11-26 (2 months ago) 8.1 2023-11-25 (2 months ago) 8.2 2024-12-08 (9 months from now) 1,2 https://www.php.net/supported-versions.php and https://www.php.net/eol.php 3/54

Slide 4

Slide 4 text

PHP 8.3 was released on 2023-11-23 will reach EOL on 2025-11-23 4/54

Slide 5

Slide 5 text

New Features 5/54

Slide 6

Slide 6 text

Readonly amendments 6/54

Slide 7

Slide 7 text

readonly class Post { public function __construct( public DateTime $createdAt, ) {} public function __clone() { $this->createdAt = new DateTime(); // This is allowed, // even though `createdAt` is a readonly property. } } 7/54

Slide 8

Slide 8 text

Typed class constants 8/54

Slide 9

Slide 9 text

class Foo { const string BAR = 'baz'; } 9/54

Slide 10

Slide 10 text

#[Override] a!ribute 10/54

Slide 11

Slide 11 text

abstract class Parent { public function methodWithDefaultImplementation(): int { return 1; } } final class Child extends Parent { #[Override] public function methodWithDefaultImplementation(): int { return 2; // The overridden method } } y 11/54

Slide 12

Slide 12 text

Negative indices in arrays 12/54

Slide 13

Slide 13 text

$array = []; $array[-5] = 'a'; $array[] = 'b'; // Pre 8.3 [ -5 => 'a', 0 => 'b' ] // 8.3 [ -5 => 'a', -4 => 'b', ] 13/54

Slide 14

Slide 14 text

Anonymous readonly classes 14/54

Slide 15

Slide 15 text

$class = new readonly class { public function __construct( public string $foo = 'bar', ) {} }; 15/54

Slide 16

Slide 16 text

The new json_validate() function 16/54

Slide 17

Slide 17 text

json_validate(string $json, int $depth = 512, int $flags = 0): bool 17/54

Slide 18

Slide 18 text

Randomizer additions 18/54

Slide 19

Slide 19 text

Randomizer::getBytesFromString(string $string, int $length): string 19/54

Slide 20

Slide 20 text

Randomizer::getFloat( float $min, float $max, IntervalBoundary $boundary = IntervalBoundary::ClosedOpen ): float 20/54

Slide 21

Slide 21 text

Randomizer::nextFloat(): float {} // shorthand for getFloat(0, 1, IntervalBoundary::ClosedOpen) 21/54

Slide 22

Slide 22 text

Dynamic class constant fetch 22/54

Slide 23

Slide 23 text

class Foo { const BAR = 'bar'; } $name = 'BAR'; // Instead of this: constant(Foo::class . '::' . $name); // You can now do this: Foo::{$name}; 23/54

Slide 24

Slide 24 text

More Appropriate Date/Time Exceptions 24/54

Slide 25

Slide 25 text

DateRangeError: // Epoch doesn't fit in a PHP integer DateMalformedIntervalStringException // Only non-special relative time specifications are supported for subtraction DateInvalidOperationException // String '%s' contains non-relative elements 25/54

Slide 26

Slide 26 text

Improved unserialize() error handling 26/54

Slide 27

Slide 27 text

unserialize() will now always emit a E_WARNING when running into problems instead of sometimes an E_NOTICE. 27/54

Slide 28

Slide 28 text

Changes to the range() function 28/54

Slide 29

Slide 29 text

— TypeError when passing objects, resources, or arrays as the boundary inputs — ValueError — when passing 0 as $step — when using a negative $step for increasing ranges 29/54

Slide 30

Slide 30 text

— E_WARNING — when $start or $end is an empty string — when $start or $end is a non-numeric string and greater than 1 byte (e.g. 'aa') — when the type of $start and $end differ (e.g. range(1, 'z')) — when $step is a float and the boundaries are non- numeric strings (e.g. range('a', 'b', 0.5)) 30/54

Slide 31

Slide 31 text

range() produces a list of characters, if one boundary is a string digit instead of casting the other input to int (e.g. range('8', 'c')) [ 0 => "8", 1 => "9", 2 => ":", 3 => ";", ... 8 => "@", 9 => "A", 10 => "B", ... 33 => "Y", 34 => "Z", 35 => "[", ... 41 => "a", 42 => "b", 43 => "c", ] 31/54

Slide 32

Slide 32 text

Traits and static properties 32/54

Slide 33

Slide 33 text

From the changelog[^3](https://www.php.net/manual/en/ migration83.incompatible.php): Uses of traits with static properties will now redeclare static properties inherited from the parent class. This will create a separate static property storage for the current class. This is analogous to adding the static property to the class directly without traits. 33/54

Slide 34

Slide 34 text

Stack overflow detection 34/54

Slide 35

Slide 35 text

PHP 8.3 adds two new ini directives called zend.max_allowed_stack_size and zend.reserved_stack_size. 35/54

Slide 36

Slide 36 text

Programs that are close to overflowing the call stack may now throw an Error when using more than the difference between zend.max_allowed_stack_size and zend.reserved_stack_size. 36/54

Slide 37

Slide 37 text

New mb_str_pad() function 37/54

Slide 38

Slide 38 text

function mb_str_pad( string $string, int $length, string $pad_string = " ", int $pad_type = STR_PAD_RIGHT, ?string $encoding = null, ): string {} 38/54

Slide 39

Slide 39 text

Magic method closures and named arguments 39/54

Slide 40

Slide 40 text

class Test { public function __call($name, $args) { var_dump($name, $args); } public static function __callStatic($name, $args) { var_dump($name, $args); } } 40/54

Slide 41

Slide 41 text

$test = new Test(); $closure = $test->magic(...); $closure(a: 'hello', b: 'world'); 41/54

Slide 42

Slide 42 text

Invariant constant visibility 42/54

Slide 43

Slide 43 text

interface I { public const FOO = 'foo'; } class C implements I { private const FOO = 'foo'; } // PHP Fatal error: Access level to C::FOO must be public (as in interface I) 43/54

Slide 44

Slide 44 text

The small deprecations RFC 44/54

Slide 45

Slide 45 text

— Deprecate passing negative $widths to mb_strimwidth() — Deprecate and remove the NumberFormatter::TYPE_CURRENCY constant — Deprecate and remove the broken pre-PHP 7.1 Mt19937 implementation (MT_RAND_PHP) — Deprecate and remove calling ldap_connect() with 2 parameters $host and $port — Deprecate remains of string evaluated code assertions [^4](https://wiki.php.net/rfc/assert-string-eval- cleanup) 45/54

Slide 46

Slide 46 text

Small, but notable changes 46/54

Slide 47

Slide 47 text

— When using FFI5, C functions that have a return type of void now return null instead of returning FFI\CData:void — posix_getrlimit() now takes an optional $res parameter to allow fetching a single resource limit. — gc_status() has four new fields: running, protected, full, and buffer_size. — get_class() and get_parent_class() function calls without arguments are now deprecated 5 Foreign function interface, allows us to call C code from userland 47/54

Slide 48

Slide 48 text

— class_alias() now supports creating an alias of an internal class. — mysqli_poll() now raises a ValueError when the read nor error arguments are passed. — array_pad() is now only limited by the maximum number of elements an array can have. Before, it was only possible to add at most 1.048.576 elements at a time. 48/54

Slide 49

Slide 49 text

— New posix functions: posix_sysconf(), posix_pathconf(), posix_fpathconf(), and posix_eaccess() — Executing proc_get_status() multiple times will now always return the right value on posix systems. — opcache.consistency_checks ini directive was removed — Improved array_sum() and array_product()[^6](https:// wiki.php.net/rfc/saner-array-sum-product) 49/54

Slide 50

Slide 50 text

But wait! There's more! 50/54

Slide 51

Slide 51 text

highlight_file and highlight_string output HTML is now wrapped within
tags, and new- line characters are no longer convertes to
php -l can now lint multiple files at once 51/54

Slide 52

Slide 52 text

Where to go from here? — Read the blog post https://stitcher.io/blog/new-in- php-83 — Also https://php.watch/versions/8.3 — Follow @brendtgd on Twitter (or don't if you don't like Elon) — Download PHP 8.3 now! 52/54

Slide 53

Slide 53 text

Thanks! Slides can be found at speakerdeck.com/mazedlx 53/54

Slide 54

Slide 54 text

54/54