[Разработка веб-сайтов, PHP, Программирование, Laravel] PHP 8 — пробуем новые возможности (перевод)
Автор
Сообщение
news_bot ®
Стаж: 6 лет 9 месяцев
Сообщений: 27286
PHP 8 уже на этапе release candidate, версия RC 3 вышла 29 октября, а полноценный релиз назначен на 26 ноября. Так что пора взглянуть на новые возможности, которые нас ждут в PHP 8. График релизов можно посмотреть здесь. А официальное руководство по обновлению на новую версию лежит тут.
Добавлена поддержка типов union (RFC)
Тип union принимает значения разных других типов, а не только какого-то одного.
<?php
declare(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 ссылки на объекты автоматически собираются сборщиком мусора, когда объект становится недоступен.
Если вы сделаете то же самое с массивом, то ссылки на объект сохранятся, что приведёт к утечке памяти.
<?php
declare(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 memory
unset($cacheObject);
dump(count($obj->cache));
exit;
Новое исключение ValueError
В PHP 8 появился новый встроенный класс исключений ValueError. Он дополняет собой \Exception. PHP бросает такое исключение каждый раз, когда вы передаёте функции значение правильного типа, однако его нельзя использовать в этой операции. Раньше в таких случаях выдавалось предупреждение. Примеры:
<?php
declare(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);
При определении функций можно использовать вариативный аргумент
Вариативным аргументом теперь можно заменить любое количество параметров функции, если их типы совместимы. Например, следующий код некорректен:
<?php
declare(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 теперь можно использовать для определения ситуации, что метод возвращает класс, для которого этот метод и был вызван, даже если он был унаследован (позднее статическое связывание).
<?php
declare(strict_types=1);
class Test {
public function doWhatever(): static {
// Do whatever.
return $this;
}
}
exit;
Литерал имени класса для объекта (RFC)
Теперь можно извлекать имя класса объекта с помощью $object::class. Результат будет такой же, как в случае с get_class($object).
<?php
declare(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 (выражение).
<?php
declare(strict_types=1);
class Foo {}
class Bar {}
$class = new (collect(['Foo', 'Bar'])->random());
dd($class);
exit;
Интерфейс Stringable (RFC)
В PHP 8 появился новый интерфейс Stringable, который добавляется автоматически, как только класс реализует метод __toString. Вам не нужно явно реализовывать этот интерфейс.
<?php
declare(strict_types=1);
class Foo {
public function __toString() {
return 'I am a class';
}
}
$obj = new Foo;
dump($obj instanceof Stringable);
exit;
Теперь трейты могут определять абстрактные приватные методы (RFC)
<?php
declare(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).
<?php
declare(strict_types=1);
$callable = fn() => throw new Exception();
$nullableValue = null;
// $value is non-nullable.
$value = $nullableValue ?? throw new \InvalidArgumentException();
exit;
В параметрах списка теперь допускается опциональная висящая запятая (RFC)
По аналогии с висящей запятой в массивах, теперь можно определять её и в параметрах списка.
<?php
declare(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 (исключение) для ловли исключений без их сохранения в переменной.
<?php
declare(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.
<?php
declare(strict_types=1);
function debug_function(mixed ...$data) {
dump($data);
}
debug_function(1, 'string', []);
exit;
Добавлена поддержка атрибутов
Есть несколько предложений по внедрению атрибутов в PHP 8:
- https://wiki.php.net/rfc/attributes_v2
- https://wiki.php.net/rfc/attribute_amendments
- https://wiki.php.net/rfc/shorter_attribute_syntax
- https://wiki.php.net/rfc/shorter_attribute_syntax_change
Это одно из крупнейших изменений в PHP 8. Возможно, сначала с ними не так легко будет разобраться. Если кратко, то атрибуты позволяют добавлять метаданные в PHP-функции, параметры, классы и т.д. Эти метаданные можно потом программно извлекать. Если в PHP 7 или ниже вам потребуется парсить doclock`и, атрибуты помогут обратиться к этой информации, глубоко интегрированной в сам PHP.
Чтобы было понятнее, представим, что вашим пользователям нужно дать возможность добавлять промежуточное ПО в контроллер класса или метода с помощью использования атрибута.
<?php
declare(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)
Предложено добавить простой синтаксис, позволяющий комбинировать конструктор с определением свойств:
<?php
declare(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, только с более безопасной семантикой и возможностью возвращать значения.
<?php
declare(strict_types=1);
echo match (1) {
0 => 'Foo',
1 => 'Bar',
2 => 'Baz',
};
exit;
Добавлена поддержка оператора nullsafe (?->) (RFC)
Когда результат левой части оператора равен null, исполнение всей цепочки останавливается, а её результат приравнивается к null. В противном случае цепочка ведёт себя как обычный оператор ->.
<?php
declare(strict_types=1);
class User {
public function getAddress() {}
}
$user = new User();
$country = $user?->getAddress()?->country?->iso_code;
dump($country);
exit;
Добавлена поддержка именованных аргументов (RFC)
Именование позволяет передавать аргументы функции в зависимости от имени параметра, а не от его позиции. То есть значения аргументов становятся самодокументирующимися, а аргументы перестают зависеть от порядка перечисления, поэтому можно произвольно пропускать значения по умолчанию.
<?php
declare(strict_types=1);
array_fill(start_index: 0, num: 100, value: 50);
exit;
===========
Источник:
habr.com
===========
===========
Автор оригинала: Marcel Pociot
===========Похожие новости:
- [Программирование, IT-эмиграция, Карьера в IT-индустрии] Работа в Amazon, Google и США: личный опыт Евгения Ким
- [Программирование, Scala] 5 уроков, которые я извлек для себя, продолжая осваивать ZIO (перевод)
- [Программирование] Правда о регистре символов, которую должны знать программисты (перевод)
- [Разработка веб-сайтов, JavaScript, Программирование] Примеры использования наблюдателей в JavaScript
- [Системное администрирование, Программирование, DevOps, Kubernetes] Что такое GitOps? Расширяем DevOps на Kubernetes и дальше (перевод)
- [Разработка веб-сайтов] Перевод: Кто такой Full Stack разработчик?
- [Программирование, .NET] Старт работы с Excel на C#
- [Программирование, Анализ и проектирование систем, Промышленное программирование] Принципы объектно-ориентированного программирования
- [Облачные вычисления, DevOps, Облачные сервисы, Kubernetes] Как устроен Kubernetes as a Service на платформе Mail.ru Cloud Solutions
- [Ненормальное программирование, Программирование] Пять самых сложных языков программирования на свете (перевод)
Теги для поиска: #_razrabotka_vebsajtov (Разработка веб-сайтов), #_php, #_programmirovanie (Программирование), #_laravel, #_php, #_php8, #_buduschee_nastupilo (будущее наступило), #_nikto_ne_chitaet_tegi (никто не читает теги), #_blog_kompanii_mail.ru_group (
Блог компании Mail.ru Group
), #_razrabotka_vebsajtov (
Разработка веб-сайтов
), #_php, #_programmirovanie (
Программирование
), #_laravel
Вы не можете начинать темы
Вы не можете отвечать на сообщения
Вы не можете редактировать свои сообщения
Вы не можете удалять свои сообщения
Вы не можете голосовать в опросах
Вы не можете прикреплять файлы к сообщениям
Вы не можете скачивать файлы
Текущее время: 22-Ноя 22:35
Часовой пояс: UTC + 5
Автор | Сообщение |
---|---|
news_bot ®
Стаж: 6 лет 9 месяцев |
|
PHP 8 уже на этапе release candidate, версия RC 3 вышла 29 октября, а полноценный релиз назначен на 26 ноября. Так что пора взглянуть на новые возможности, которые нас ждут в PHP 8. График релизов можно посмотреть здесь. А официальное руководство по обновлению на новую версию лежит тут. Добавлена поддержка типов union (RFC) Тип union принимает значения разных других типов, а не только какого-то одного. <?php
declare(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 ссылки на объекты автоматически собираются сборщиком мусора, когда объект становится недоступен. Если вы сделаете то же самое с массивом, то ссылки на объект сохранятся, что приведёт к утечке памяти. <?php
declare(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 memory unset($cacheObject); dump(count($obj->cache)); exit; Новое исключение ValueError В PHP 8 появился новый встроенный класс исключений ValueError. Он дополняет собой \Exception. PHP бросает такое исключение каждый раз, когда вы передаёте функции значение правильного типа, однако его нельзя использовать в этой операции. Раньше в таких случаях выдавалось предупреждение. Примеры: <?php
declare(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); При определении функций можно использовать вариативный аргумент Вариативным аргументом теперь можно заменить любое количество параметров функции, если их типы совместимы. Например, следующий код некорректен:
<?php
declare(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 теперь можно использовать для определения ситуации, что метод возвращает класс, для которого этот метод и был вызван, даже если он был унаследован (позднее статическое связывание). <?php
declare(strict_types=1); class Test { public function doWhatever(): static { // Do whatever. return $this; } } exit; Литерал имени класса для объекта (RFC) Теперь можно извлекать имя класса объекта с помощью $object::class. Результат будет такой же, как в случае с get_class($object). <?php
declare(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 (выражение). <?php
declare(strict_types=1); class Foo {} class Bar {} $class = new (collect(['Foo', 'Bar'])->random()); dd($class); exit; Интерфейс Stringable (RFC) В PHP 8 появился новый интерфейс Stringable, который добавляется автоматически, как только класс реализует метод __toString. Вам не нужно явно реализовывать этот интерфейс. <?php
declare(strict_types=1); class Foo { public function __toString() { return 'I am a class'; } } $obj = new Foo; dump($obj instanceof Stringable); exit; Теперь трейты могут определять абстрактные приватные методы (RFC) <?php
declare(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). <?php
declare(strict_types=1); $callable = fn() => throw new Exception(); $nullableValue = null; // $value is non-nullable. $value = $nullableValue ?? throw new \InvalidArgumentException(); exit; В параметрах списка теперь допускается опциональная висящая запятая (RFC) По аналогии с висящей запятой в массивах, теперь можно определять её и в параметрах списка. <?php
declare(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 (исключение) для ловли исключений без их сохранения в переменной. <?php
declare(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. <?php
declare(strict_types=1); function debug_function(mixed ...$data) { dump($data); } debug_function(1, 'string', []); exit; Добавлена поддержка атрибутов Есть несколько предложений по внедрению атрибутов в PHP 8:
Это одно из крупнейших изменений в PHP 8. Возможно, сначала с ними не так легко будет разобраться. Если кратко, то атрибуты позволяют добавлять метаданные в PHP-функции, параметры, классы и т.д. Эти метаданные можно потом программно извлекать. Если в PHP 7 или ниже вам потребуется парсить doclock`и, атрибуты помогут обратиться к этой информации, глубоко интегрированной в сам PHP. Чтобы было понятнее, представим, что вашим пользователям нужно дать возможность добавлять промежуточное ПО в контроллер класса или метода с помощью использования атрибута. <?php
declare(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) Предложено добавить простой синтаксис, позволяющий комбинировать конструктор с определением свойств: <?php
declare(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, только с более безопасной семантикой и возможностью возвращать значения. <?php
declare(strict_types=1); echo match (1) { 0 => 'Foo', 1 => 'Bar', 2 => 'Baz', }; exit; Добавлена поддержка оператора nullsafe (?->) (RFC) Когда результат левой части оператора равен null, исполнение всей цепочки останавливается, а её результат приравнивается к null. В противном случае цепочка ведёт себя как обычный оператор ->.
<?php
declare(strict_types=1); class User { public function getAddress() {} } $user = new User(); $country = $user?->getAddress()?->country?->iso_code; dump($country); exit; Добавлена поддержка именованных аргументов (RFC) Именование позволяет передавать аргументы функции в зависимости от имени параметра, а не от его позиции. То есть значения аргументов становятся самодокументирующимися, а аргументы перестают зависеть от порядка перечисления, поэтому можно произвольно пропускать значения по умолчанию.
<?php
declare(strict_types=1); array_fill(start_index: 0, num: 100, value: 50); exit; =========== Источник: habr.com =========== =========== Автор оригинала: Marcel Pociot ===========Похожие новости:
Блог компании Mail.ru Group ), #_razrabotka_vebsajtov ( Разработка веб-сайтов ), #_php, #_programmirovanie ( Программирование ), #_laravel |
|
Вы не можете начинать темы
Вы не можете отвечать на сообщения
Вы не можете редактировать свои сообщения
Вы не можете удалять свои сообщения
Вы не можете голосовать в опросах
Вы не можете прикреплять файлы к сообщениям
Вы не можете скачивать файлы
Вы не можете отвечать на сообщения
Вы не можете редактировать свои сообщения
Вы не можете удалять свои сообщения
Вы не можете голосовать в опросах
Вы не можете прикреплять файлы к сообщениям
Вы не можете скачивать файлы
Текущее время: 22-Ноя 22:35
Часовой пояс: UTC + 5