Русский
Русский
English
Статистика
Реклама

Перевод PHP 8 пробуем новые возможности


PHP 8 уже на этапе release candidate, версия RC 3 вышла 29 октября, а полноценный релиз назначен на 26 ноября. Так что пора взглянуть на новые возможности, которые нас ждут в PHP 8. График релизов можно посмотреть здесь. А официальное руководство по обновлению на новую версию лежит тут.

Добавлена поддержка типов union (RFC)


Тип union принимает значения разных других типов, а не только какого-то одного.

<?phpdeclare(strict_types=1); class Number {    private int|float $number;     public function setNumber(int|float $number): void {        $this->number = $number;    }     public function getNumber(): int|float {        return $this->number;    }} /** * We can pass both floats or integer values * to the number object. Try passing a string. */$number = new Number(); $number->setNumber(5); dump($number->getNumber()); $number->setNumber(11.54); dump($number->getNumber()); exit;

Добавлены WeakMap (RFC)


Слабые карты (weak maps) позволяют создавать связи между объектами и произвольными значениями (как и SplObjectStorage), при этом объекты, используемые в качестве ключей, не защищаются от сборщика мусора. Если сборщик уничтожает такой объект, тот просто удаляется из карты.

Это очень полезная фича. Она позволяет нам ещё меньше думать об утечках памяти в коде. Хотя для большинства PHP-разработчиков это не должно быть проблемой, но стоит обращать внимание при создании долгоиграющих процессов, например, используя ReactPHP. С WeakMaps ссылки на объекты автоматически собираются сборщиком мусора, когда объект становится недоступен.

Если вы сделаете то же самое с массивом, то ссылки на объект сохранятся, что приведёт к утечке памяти.

<?phpdeclare(strict_types=1); class FooBar {    public WeakMap $cache;        public function __construct() {      $this->cache = new WeakMap();    }     public function getSomethingWithCaching(object $obj) {        return $this->cache[$obj] ??= $this->computeSomethingExpensive($obj);    }        public function computeSomethingExpensive(object $obj) {    dump("I got called");    return rand(1, 100);    }} $cacheObject = new stdClass; $obj = new FooBar;// "I got called" only will be printed once$obj->getSomethingWithCaching($cacheObject);$obj->getSomethingWithCaching($cacheObject); dump(count($obj->cache)); // When unsetting our object, the WeakMap frees up memoryunset($cacheObject); dump(count($obj->cache)); exit;

Новое исключение ValueError


В PHP 8 появился новый встроенный класс исключений ValueError. Он дополняет собой \Exception. PHP бросает такое исключение каждый раз, когда вы передаёте функции значение правильного типа, однако его нельзя использовать в этой операции. Раньше в таких случаях выдавалось предупреждение. Примеры:

<?phpdeclare(strict_types=1); /** * We pass an array to array_rand, * which is of the correct type. But * array_rand expects non-empty arrays. * * This throws a ValueError exception. */array_rand([], 0); /** * The depth argument for json_decode is a * valid integer, but it must be greater than 0 */json_decode('{}', true, -1);

При определении функций можно использовать вариативный аргумент


Вариативным аргументом теперь можно заменить любое количество параметров функции, если их типы совместимы. Например, следующий код некорректен:

<?phpdeclare(strict_types=1); class A {    public function method(int $many, string $parameters, $here) {     }}class B extends A {    public function method(...$everything) {        dd($everything);    }} $b = new B();$b->method('i can be overwritten!');exit;

Возвращаемый тип static (RFC)


Возвращаемый тип static теперь можно использовать для определения ситуации, что метод возвращает класс, для которого этот метод и был вызван, даже если он был унаследован (позднее статическое связывание).

<?phpdeclare(strict_types=1); class Test {    public function doWhatever(): static {        // Do whatever.        return $this;    }} exit;

Литерал имени класса для объекта (RFC)


Теперь можно извлекать имя класса объекта с помощью $object::class. Результат будет такой же, как в случае с get_class($object).

<?phpdeclare(strict_types=1); auth()->loginUsingId(1); dump(auth()->user()::class); // Or with a temporary variable$user = auth()->user(); dump($user::class);exit;

Настройки синтаксиса переменных (RFC)


New и instanceof теперь можно использовать с произвольными выражениями: new (выражение)(...$args) и $obj instanceof (выражение).

<?phpdeclare(strict_types=1); class Foo {}class Bar {}  $class = new (collect(['Foo', 'Bar'])->random()); dd($class); exit;

Интерфейс Stringable (RFC)


В PHP 8 появился новый интерфейс Stringable, который добавляется автоматически, как только класс реализует метод __toString. Вам не нужно явно реализовывать этот интерфейс.

<?phpdeclare(strict_types=1); class Foo {    public function __toString() {        return 'I am a class';    }} $obj = new Foo;dump($obj instanceof Stringable); exit;

Теперь трейты могут определять абстрактные приватные методы (RFC)


<?phpdeclare(strict_types=1);  trait MyTrait {    abstract private function neededByTheTrait(): string;     public function doSomething() {        return strlen($this->neededByTheTrait());    }} class TraitUser {    use MyTrait;     // This is allowed:    private function neededByTheTrait(): string { }     // This is forbidden (incorrect return type)    // private function neededByTheTrait(): stdClass { }     // This is forbidden (non-static changed to static)    // private static function neededByTheTrait(): string { }} exit;

throw теперь можно использовать как выражение (RFC)


Выражение throw теперь можно использовать там, где допускаются только выражения: в стрелочных функциях, coalesce-операторах тернарных условных операторах (ternary/elvis).

<?phpdeclare(strict_types=1); $callable = fn() => throw new Exception(); $nullableValue = null; // $value is non-nullable.$value = $nullableValue ?? throw new \InvalidArgumentException();  exit;

В параметрах списка теперь допускается опциональная висящая запятая (RFC)


По аналогии с висящей запятой в массивах, теперь можно определять её и в параметрах списка.

<?phpdeclare(strict_types=1); function method_with_many_arguments(    $a,     $b,    $c,    $d,) {    dump("this is valid syntax");} method_with_many_arguments(    1,    2,    3,    4,); exit;

Ловля исключений без сохранения в переменной (RFC)


Теперь можно писать catch (исключение) для ловли исключений без их сохранения в переменной.

<?phpdeclare(strict_types=1); $nullableValue = null; try {    $value = $nullableValue ?? throw new \InvalidArgumentException();} catch (\InvalidArgumentException) {    dump("Something went wrong");}  exit;

Добавлена поддержка типа mixed (RFC)


В PHP 8 появился новый тип mixed. Он может быть эквивалентен типам array, bool, callable, int, float, null, object, resource, string.

<?phpdeclare(strict_types=1); function debug_function(mixed ...$data) {    dump($data);} debug_function(1, 'string', []); exit;

Добавлена поддержка атрибутов


Есть несколько предложений по внедрению атрибутов в PHP 8:


Это одно из крупнейших изменений в PHP 8. Возможно, сначала с ними не так легко будет разобраться. Если кратко, то атрибуты позволяют добавлять метаданные в PHP-функции, параметры, классы и т.д. Эти метаданные можно потом программно извлекать. Если в PHP 7 или ниже вам потребуется парсить doclock`и, атрибуты помогут обратиться к этой информации, глубоко интегрированной в сам PHP.

Чтобы было понятнее, представим, что вашим пользователям нужно дать возможность добавлять промежуточное ПО в контроллер класса или метода с помощью использования атрибута.

<?phpdeclare(strict_types=1);// First, we need to define the attribute. An Attribute itself is just a plain PHP class, that is annotated as an Attribute itself. #[Attribute]class ApplyMiddleware{    public array $middleware = [];     public function __construct(...$middleware) {        $this->middleware = $middleware;    }} // This adds the attribute to the MyController class, with the "auth" middleware as an argument. #[ApplyMiddleware('auth')]class MyController{    public function index() {}} // We can then retrieve all ApplyMiddleware attributes on our class using reflection// And read the given middleware arguments. $reflectionClass = new ReflectionClass(MyController::class); $attributes = $reflectionClass->getAttributes(ApplyMiddleware::class); foreach ($attributes as $attribute) {    $middlewareAttribute = $attribute->newInstance();    dump($middlewareAttribute->middleware);} exit;

Добавлена поддержка продвижения свойств конструктора (RFC)


Предложено добавить простой синтаксис, позволяющий комбинировать конструктор с определением свойств:

<?phpdeclare(strict_types=1); class User {    public function __construct(        public int $id,        public string $name,    ) {}} $user = new User(1, 'Marcel'); dump($user->id);dump($user->name); exit;

Добавлена поддержка выражения match (RFC)


Предложено добавить новое выражение match, которое аналогично switch, только с более безопасной семантикой и возможностью возвращать значения.

<?phpdeclare(strict_types=1); echo match (1) {    0 => 'Foo',    1 => 'Bar',    2 => 'Baz',}; exit;

Добавлена поддержка оператора nullsafe (?->) (RFC)


Когда результат левой части оператора равен null, исполнение всей цепочки останавливается, а её результат приравнивается к null. В противном случае цепочка ведёт себя как обычный оператор ->.

<?phpdeclare(strict_types=1); class User {    public function getAddress() {}} $user = new User(); $country = $user?->getAddress()?->country?->iso_code; dump($country); exit;

Добавлена поддержка именованных аргументов (RFC)


Именование позволяет передавать аргументы функции в зависимости от имени параметра, а не от его позиции. То есть значения аргументов становятся самодокументирующимися, а аргументы перестают зависеть от порядка перечисления, поэтому можно произвольно пропускать значения по умолчанию.

<?phpdeclare(strict_types=1); array_fill(start_index: 0, num: 100, value: 50); exit;
Источник: habr.com
К списку статей
Опубликовано: 29.10.2020 20:09:21
0

Сейчас читают

Комментариев (0)
Имя
Электронная почта

Блог компании mail.ru group

Разработка веб-сайтов

Php

Программирование

Laravel

Php8

Будущее наступило

Никто не читает теги

Категории

Последние комментарии

  • Имя: Макс
    24.08.2022 | 11:28
    Я разраб в IT компании, работаю на арбитражную команду. Мы работаем с приламы и сайтами, при работе замечаются постоянные баны и лаги. Пацаны посоветовали сервис по анализу исходного кода,https://app Подробнее..
  • Имя: 9055410337
    20.08.2022 | 17:41
    поможем пишите в телеграм Подробнее..
  • Имя: sabbat
    17.08.2022 | 20:42
    Охренеть.. это просто шикарная статья, феноменально круто. Большое спасибо за разбор! Надеюсь как-нибудь с тобой связаться для обсуждений чего-либо) Подробнее..
  • Имя: Мария
    09.08.2022 | 14:44
    Добрый день. Если обладаете такой информацией, то подскажите, пожалуйста, где можно найти много-много материала по Yggdrasil и его уязвимостях для написания диплома? Благодарю. Подробнее..
© 2006-2024, personeltest.ru