Лекция
Привет, Вы узнаете о том , что такое php 8, Разберем основные их виды и особенности использования. Еще будет много подробных примеров и описаний. Для того чтобы лучше понимать что такое php 8 , настоятельно рекомендую прочитать все из категории Выполнение скриптов на стороне сервера PHP (LAMP) NodeJS (Backend) .
php 8 , новая основная версия PHP, как ожидается, выйдет 3 декабря 2020 года . Сейчас он находится в очень активной разработке, поэтому, вероятно, многое изменится в ближайшие месяцы.
В этом посте я буду держать актуальный список того, что ожидается: новые функции, улучшения производительности и критические изменения. Поскольку PHP 8 является новой основной версией, существует большая вероятность взлома вашего кода. Однако если вы были в курсе последних выпусков, обновление не должно быть слишком сложным, поскольку большинство критических изменений ранее не использовались в версиях 7. *.
Помимо внесения изменений, в PHP 8 также есть несколько приятных новых функций, таких как JIT-компилятор и типы объединения ; и это еще не все!
PHP 8 все еще находится в активной разработке, поэтому этот список со временем будет расти и изменятся.
Учитывая динамически типизированную природу PHP, существует множество случаев, когда типы объединения могут быть полезны. Типы объединения представляют собой набор из двух или более типов, которые указывают, что может использоваться любой из них.
public function foo(Foo|Bar $input): int|float;
Обратите внимание, что он voidникогда не может быть частью типа объединения, так как он указывает «вообще никакого возвращаемого значения». Кроме того, nullableсоюзы могут быть написаны с использованием |nullили с использованием существующей ?записи:
public function foo(Foo|null $foo): void; public function bar(?Bar $bar): void;
JIT - компилятор обещает значительные улучшения производительности, хотя и не всегда в контексте веб-запросов.
На данный момент не было сделано никаких точных ориентиров, но они обязательно придут.
как это работает?
Есть так называемый «монитор», который будет смотреть на код во время его работы. Когда этот монитор обнаруживает повторяющиеся части вашего кода, он помечает эти части как «теплые» или «горячие», в зависимости от частоты.
Эти горячие части можно скомпилировать как оптимизированный машинный код и использовать на лету вместо реального кода.
JIT-компилятор может значительно улучшить производительность вашей программы, но это сложно сделать правильно.
Однако, поскольку PHP чаще всего используется в веб-контексте, мы также должны измерить влияние JIT.
Оказывается, что, к сожалению, при обработке веб-запроса кода гораздо меньше. Это не означает, что JIT вообще не может улучшить производительность сети, но мы также не увидим подобных улучшений , как в случае с фрактальным примером.
Это причина, чтобы отказаться от JIT? Точно нет! Есть веские аргументы, чтобы добавить его, хотя это может не оказать влияния на производительность, на которую мы надеемся.
Это веские аргументы в пользу JIT.
Однако имея машинный код в качестве вывода, будет сложнее отлаживать возможные ошибки в JIT-компиляторе PHP.
Атрибуты, обычно известные как аннотации на других языках, предлагают способ добавлять метаданные в классы, не анализируя докблоки.
Вот пример того, как выглядят атрибуты из RFC:
use App\Attributes\ExampleAttribute; <> class Foo { <> public const FOO = 'foo'; <> public $x; <> public function foo(<> $bar) { } }
<> class ExampleAttribute { public $value; public function __construct($value) { $this->value = $value; } }
Хотя возвращение уже было возможно self, staticон не был допустимым типом возврата до PHP 8.
Учитывая динамически типизированный характер PHP, эта функция будет полезна для многих разработчиков.
class Foo { public function test(): static { return new static(); } }
Этот RFC превращается throw из выражения в выражение, что позволяет создавать исключения во многих новых местах:
$triggerError = fn () => throw new MyError(); $foo = $bar['offset'] ?? throw new OffsetDoesNotExist('offset');
Построенный на RFC слабых ссылок, который был добавлен в PHP 7.4, WeakMapв PHP 8 добавлена реализация, в которой WeakMapsхранятся ссылки на объекты, которые не препятствуют сборке мусора этими объектами.
Возьмите пример ORM, они часто реализуют кэши, которые содержат ссылки на классы сущностей, чтобы улучшить производительность отношений между сущностями. Об этом говорит сайт https://intellect.icu . Эти объекты сущности нельзя собирать, пока кеш имеет ссылку на них, даже если кеш является единственной ссылкой на них.
Если этот слой кэширования использует слабые ссылки и карты вместо этого, PHP будет собирать эти объекты мусором, когда ничто больше не ссылается на них. Особенно в случае ORM, которые могут управлять несколькими сотнями, если не тысячами объектов в запросе; слабые карты могут предложить лучший, более дружественный к ресурсам способ работы с этими объектами.
Вот как выглядят слабые карты, пример из RFC:
class Foo { private WeakMap $cache; public function getSomethingWithCaching(object $obj): object { return $this->cache[$obj] ??= $this->computeSomethingExpensive($obj); } }
Небольшая, но полезная новая функция: теперь можно использовать ::class для объектах,
вместо того, чтобы использовать get_class() их. Это работает так же, как get_class().
$foo = new Foo(); var_dump($foo::class);
Уже возможно при вызове функции, в списках параметров все еще отсутствовала поддержка запятой. Теперь это разрешено в PHP 8, что означает, что вы можете делать следующее:
public function( string $parameterA, int $parameterB, Foo $objectfoo, ) { // … }
Вы уже можете создать DateTimeобъект из DateTimeImmutableобъекта, используя DateTime::createFromImmutable($immutableDateTime), но наоборот было сложно. Добавляя DateTime::createFromInterface()и DatetimeImmutable::createFromInterface()теперь есть обобщенный способ конвертировать DateTimeи DateTimeImmutableобъекты друг в друга.
DateTime::createFromInterface(DateTimeInterface $other); DateTimeImmutable::createFromInterface(DateTimeInterface $other);
Stringable Интерфейс может быть использован для ввода подсказок все , что строка или орудия __toString(). Кроме того, всякий раз, когда класс реализует __toString(), он автоматически реализует интерфейс за кулисами, и нет необходимости вручную его реализовывать.
class Foo { public function __toString(): string { return 'foo'; } } function bar(Stringable $stringable) { /* … */ } bar(new Foo()); bar('abc');
Некоторые могут сказать, что это давно пора, но нам, наконец, больше не нужно полагаться на то strpos, чтобы узнать, содержит ли строка другую строку.
Вместо этого:
if (strpos('string with lots of words', 'words') !== false) { /* … */ }
Теперь вы можете сделать это
if (str_contains('string with lots of words', 'words')) { /* … */ }
Две другие давно назревшие, эти две функции теперь добавлены в ядро.
str_starts_with('haystack', 'hay'); // true str_ends_with('haystack', 'stack'); // true
Новая fdiv()функция делает что - то подобное , как fmod()и intdiv()функции, что позволяет деления на 0. Вместо ошибок вы получите INF, -INFили NAN, в зависимости от случая.
get_debug_type()возвращает тип переменной. Похоже, что gettype() подошел бы?
Но get_debug_type() возвращает более полезный вывод для массивов, строк, анонимных классов и объектов.
Например, вызов gettype()класса \Foo\Bar вернется object. Использование get_debug_type()вернет имя класса.
Полный список различий между get_debug_type()и gettype()можно найти в RFC.
Примеси смогут содержать абстрактные методы, которые должны быть реализованы классами, использующими их.
Однако есть предостережение: до PHP 8 сигнатура этих реализаций методов не проверялась.
Следующее было верным:
trait Test { abstract public function test(int $input): int; } class UsesTrait { use Test; public function test($input) { return $input; } }
PHP 8 будет выполнять правильную проверку подписи метода при использовании признака и реализации его абстрактных методов.
Это означает, что вам нужно написать это вместо:
class UsesTrait { use Test; public function test(int $input): int { return $input; } }
token_get_all() Функция возвращает массив значений. Этот RFC добавляет PhpToken класс с PhpToken::getAll() методом. Эта реализация работает с объектами вместо простых значений. Он потребляет меньше памяти и его легче читать.
Из RFC: «Унифицированный синтаксис переменной RFC разрешил ряд несоответствий в синтаксисе переменной PHP.
Этот RFC намеревается решить небольшую порцию пропущенных дел».
https://wiki.php.net/rfc/variable_syntax_tweaks
Много людей просили добавить соответствующие аннотации типов для всех внутренних функций.
Это была давняя проблема, и, наконец, ее можно было решить со всеми изменениями, внесенными в PHP в предыдущих версиях
. Это означает, что внутренние функции и методы будут иметь полную информацию о типе в рефлексии.
Как упоминалось ранее: это серьезное обновление и, следовательно, будут серьезные изменения. Лучшее, что можно сделать, это взглянуть на полный список критических изменений в документе UPGRADING .
https://github.com/php/php-src/blob/master/UPGRADING#L20
Многие из этих критических изменений устарели в предыдущих версиях 7. *, поэтому, если вы были в курсе последних лет, не так уж сложно перейти на PHP 8.
Пользовательские функции в PHP уже сгенерируют TypeErrors, но внутренние функции - нет, они скорее выдают предупреждения и возвращают null. Начиная с PHP 8 поведение внутренних функций стало согласованным.
Множество ошибок, которые ранее вызывали только предупреждения или уведомления, были преобразованы в правильные ошибки. Следующие предупреждения были изменены.
Вполне возможно, что это изменение может выявить ошибки, которые снова были скрыты до PHP 8.
Обязательно установите их display_errors=Off на своих продакшн серверах!
Теперь E_ALLвместо всего, кроме E_NOTICEи E_DEPRECATED. Это означает, что может появиться много ошибок, которые ранее незаметно игнорировались, хотя, возможно, уже существовали до PHP 8.
Из RFC: текущий режим ошибок по умолчанию для PDO - бесшумный. Это означает, что при возникновении ошибки SQL никакие ошибки или предупреждения не могут выдаваться и не генерируются исключения, если разработчик не реализует свою собственную явную обработку ошибок.
Этот RFC изменяет ошибку по умолчанию, которая изменится на PDO::ERRMODE_EXCEPTIONPHP 8.
Хотя это изменение уже устарело в PHP 7.4, теперь это изменение вступает в силу. Если бы вы написали что-то вроде этого:
echo "sum: " . $a + $b;
PHP ранее интерпретировал бы это так:
echo ("sum: " . $a) + $b;
PHP 8 сделает так, чтобы он интерпретировался так:
echo "sum: " . ($a + $b);
До PHP 8 можно было применять арифметические или побитовые операторы к массивам, ресурсам или объектам. Это больше не возможно и выдаст TypeError:
[] % [42]; $object + 4;
Три сигнатуры методов классов рефлексии были изменены:
ReflectionClass::newInstance($args); ReflectionFunction::invoke($args); ReflectionMethod::invoke($object, $args);
Теперь стали:
ReflectionClass::newInstance(...$args); ReflectionFunction::invoke(...$args); ReflectionMethod::invoke($object, ...$args);
В руководстве по обновлению указано, что если вы расширяете эти классы и по-прежнему хотите поддерживать как PHP 7, так и PHP 8, допускаются следующие подписи:
ReflectionClass::newInstance($arg = null, ...$args); ReflectionFunction::invoke($arg = null, ...$args); ReflectionMethod::invoke($object, $arg = null, ...$args);
Во время разработки PHP 7. * было добавлено несколько устаревших версий, которые теперь завершены в PHP 8.
Исследование, описанное в статье про php 8, подчеркивает ее значимость в современном мире. Надеюсь, что теперь ты понял что такое php 8 и для чего все это нужно, а если не понял, или есть замечания, то не стесняйся, пиши или спрашивай в комментариях, с удовольствием отвечу. Для того чтобы глубже понять настоятельно рекомендую изучить всю информацию из категории Выполнение скриптов на стороне сервера PHP (LAMP) NodeJS (Backend)
Комментарии
Оставить комментарий
Выполнение скриптов на стороне сервера PHP (LAMP) NodeJS (Backend)
Термины: Выполнение скриптов на стороне сервера PHP (LAMP) NodeJS (Backend)