Денис Васишак, Студия "Флаг"
class Foo
{
public string $version;
public ?int $number;
public Bar $bar;
}
Нельзя использовать типы void и callable
class A {
private bool $a;
public int $b;
public ?int $c;
}
class B extends A {
public string $a; // legal, because A::$a is private
public ?int $b; // ILLEGAL
public int $c; // ILLEGAL
}
class Foo
{
public int $bar;
}
$foo = new Foo;
var_dump($foo->bar);
//Fatal error: Uncaught Error: Typed property Foo::$bar
//must not be accessed before initialization
//PHP 7.3
$users = array_filter($users, function ($user) use ($name) {
return $user->name === $name;
}
//PHP 7.4
users = array_filter($users, fn($user) => $user->name === $name);
В сигнатуре стрелочной функции, как и в обычной функции, можно указывать типы, дефолты и прочее
fn(array $x) => $x;
fn(): int => $x;
fn($x = 42) => $x;
fn(&$x) => $x;
fn&($x) => $x;
fn($x, ...$rest) => $rest;
Замыкание переменных
$y = 1;
//PHP 7.3
$fn1 = function ($x) use ($y) {
return $x + $y;
};
//PHP 7.4
$fn1 = fn($x) => $x + $y;
//PHP 7.3
$user->created_at = $user->created_at ?? now();
//PHP 7.4
$user->created_at ??= now();
Данное изменение позволяет изменять тип параметра на один из его супертипов. В свою очередь возвращаемый тип можно заменить на его подтип
interface Factory {
function make(): object;
}
class UserFactory implements Factory {
function make(): User;
}
interface Concatable {
function concat(Iterator $input);
}
class Collection implements Concatable {
// accepts all iterables, not just Iterator
function concat(iterable $input) {/* . . . */}
}
$arrayA = [1, 2, 3];
$arrayB = [4, 5];
$result = [0, ...$arrayA, ...$arrayB, 6 ,7];
//[0, 1, 2, 3, 4, 5, 6, 7]
Интерфейс внешних функций (FFI) позволяет писать код на C непосредственно в PHP-коде. Это означает, что расширения PHP могут быть написаны на чистом PHP.
// create FFI object, loading libc and exporting function printf()
$ffi = FFI::cdef(
"int printf(const char *format, ...);", // this is regular C declaration
"libc.so.6");
// call C printf()
$ffi->printf("Hello %s!\n", "world");
On server startup – before any application code is run – we may load a certain set of PHP files into memory – and make their contents “permanently available” to all subsequent requests that will be served by that server. All the functions and classes defined in these files will be available to requests out of the box, exactly like internal entities.
1 ? 2 : 3 ? 4 : 5; // deprecated
(1 ? 2 : 3) ? 4 : 5; // ok
echo "sum: " . $a + $b; // deprecated warning
//PHP NOW
echo ("sum: " . $a) + $b;
//PHP 8
echo "sum :" . ($a + $b);
Пользовательская сериализация объектов (RFC)
class A {
private $prop_a;
public function __serialize(): array {
return ["prop_a" => $this->prop_a];
}
public function __unserialize(array $data) {
$this->prop_a = $data["prop_a"];
}
}
class B extends A {
private $prop_b;
public function __serialize(): array {
return [
"prop_b" => $this->prop_b,
"parent_data" => parent::__serialize(),
];
}
public function __unserialize(array $data) {
parent::__unserialize($data["parent_data"]);
$this->prop_b = $data["prop_b"];
}
}
class Foo {
public function __toString()
{
throw new Exception('Hello there');
}
}
1_000_000_000 // int
6.674_083e-11; // float
299_792_458; // decimal
0xCAFE_F00D; // hexadecimal
0b0101_1111; // binary
0137_041; // octal
Слабые ссылки позволяют сохранить ссылку на объект, которая не препятствует уничтожению этого объекта. Например, они полезны для реализации кэш-подобных структур.
$object = new stdClass;
$weakRef = WeakReference::create($object);
var_dump($weakRef->get()); // object(stdClass)#1 (0) {}
unset($object);
var_dump($weakRef->get()); // null