PHP 8.3

История констант классов

Таймлайн развития констант классов

Переопределение констант до PHP 8.3

                
                    // PHP < 8.3

                    namespace Symfony\Component\HttpKernel;

                    interface HttpKernelInterface
                    {
                        public const MAIN_REQUEST = 1;
                    }

                    interface MessedUpKernel extends HttpKernelInterface
                    {
                                                    ✅😢
                        public const MAIN_REQUEST = [];
                    }
                
            

Типизированные константы в PHP 8.3

                
                    // PHP >= 8.3

                    namespace Symfony\Component\HttpKernel;

                    interface HttpKernelInterface
                    {
                        public const int MAIN_REQUEST = 1;
                    }

                    interface MessedUpKernel extends HttpKernelInterface
                    {
                                                    ❌😊
                        public const MAIN_REQUEST = [];
                    }

                    $reflClass = new ReflectionClass(HttpKernelInterface::class);
                    $reflClass->getReflectionConstant('MAIN_REQUEST')->getType();
                
            

RFC

Что можно получить динамически?

                
                    // переменные
                    $$variableName

                    // свойства
                    $object->$propertyName
                    MyClass::${$staticPropertyName}

                    // методы
                    $object->{$methodName}()
                    MyClass::{$staticMethodName}()

                    // классы в статических вызовах
                    $className::$staticProperty
                    $className::staticMethod()

                    // константы класса???
                
            

Динамический доступ
к константам класса в PHP 8.3

                
                    enum AwesomeLanguages
                    {
                        case PHP;
                    }

                    $constantName = 'PHP';

                    // PHP < 8.3
                    constant(AwesomeLanguages::class . "::{$constantName}");

                    // PHP >= 8.3
                    AwesomeLanguages::{$constantName};
                
            

RFC

Произвольные инициализаторы статических переменных

                
                    // PHP < 8.3
                    function x(): void
                    {
                                                 ❌🤔
                        static $staticVariable = [new SplFileInfo(__FILE__)];
                    }

                    // PHP >= 8.3
                    function x(): void
                    {
                                                 ✅😊
                        static $staticVariable = [new SplFileInfo(__FILE__)];
                    }
                
            

RFC

Переопределение методов до PHP 8.3

                
                    // PHP < 8.3

                    use PHPUnit\Framework\TestCase;
                    use Symfony\Component\Filesystem\Filesystem;

                    final class MyTest extends TestCase
                    {
                                           ✅😢
                        protected function taerDown(): void
                        {
                            (new Filesystem())->remove(__DIR__ . '/generated');
                        }
                    }
                
            

Атрибут #[Override] в PHP 8.3

                
                    // PHP >= 8.3

                    use PHPUnit\Framework\TestCase;
                    use Symfony\Component\Filesystem\Filesystem;

                    final class MyTest extends TestCase
                    {
                        #[Override]        ❌😊
                        protected function taerDown(): void
                        {
                            (new Filesystem())->remove(__DIR__ . '/generated');
                        }
                    }
                
            

RFC

Глубокое клонирование
readonly свойств до PHP 8.3

                
                    // PHP < 8.3

                    final readonly class PhpRelease
                    {
                        public function __construct(
                            public string $version,
                            public string $manager,
                            public DateTime $date,
                        ) {}

                        public function __clone(): void
                        {
                                        ❌
                            $this->date = clone $this->date;
                        }
                    }
                
            

Глубокое клонирование
readonly свойств в PHP 8.3

                
                    // PHP >= 8.3

                    final readonly class PhpRelease
                    {
                        public function __construct(
                            public string $version,
                            public string $manager,
                            public DateTime $date,
                        ) {}

                        public function __clone(): void
                        {
                                        ✅
                            $this->date = clone $this->date;
                        }
                    }
                
            

RFC

Хотелка: клонирование
с частичным переопределением

                
                    // PHP 8.4 🙏

                    final readonly class PhpRelease
                    {
                        public function __construct(
                            public string $version,
                            public string $manager,
                            public DateTime $date,
                        ) {}

                        public function withDate(DateTime $date): self
                        {
                            return clone $this with {
                                date: $date,
                            };
                        }
                    }
                
            

RFC

Валидация JSON до PHP 8.3

                
                    // PHP < 8.3

                    function json_validate(string $string): bool
                    {
                        json_decode($string);

                        return json_last_error() === JSON_ERROR_NONE;
                    }
                
            
                
                    // PHP < 8.3

                    function json_validate(string $string): bool
                    {
                        try {
                            json_decode($string, flags: JSON_THROW_ON_ERROR);

                            return true;
                        } catch (JsonException) {
                            return false;
                        }
                    }
                
            

Новая функция json_validate() в PHP 8.3

                
                    // PHP >= 8.3

                    json_validate('{"Hello": "World!"}'); // true

                    json_validate('{"Hello": }'); // false
                
            

RFC | Документация | Symfony полифил

Какой ключ будет у второго элемента?

                
                    $array = [];

                    $array[-5] = 'b';
                    $array[] = 'c';

                    var_dump($array);
                
            
                
                    // PHP < 8.3
                    array(2) {
                      [-5] => string(1) "b"
                      [0] => string(1) "c"
                    }

                    // PHP >= 8.3
                    array(2) {
                      [-5] => string(1) "b"
                      [-4] => string(1) "c"
                    }
                
            

Какие ключи будут в массиве?

                
                    $array = [];

                    $array[] = 'a';
                    $array[-5] = 'b';
                    $array[] = 'c';
                    $array[5] = 'd';
                    $array[] = 'e';

                    var_dump($array);
                
            
                
                    // PHP < 8.3 && >= 8.3
                    array(5) {
                      [0] => string(1) "a"
                      [-5] => string(1) "b"
                      [1] => string(1) "c"
                      [5] => string(1) "d"
                      [6] => string(1) "e"
                    }
                
            

Обновление Randomizer в PHP 8.3

                
                    $randomizer = new Random\Randomizer();

                    echo $randomizer->nextFloat(); // 0.57721566490153 🤔

                    echo $randomizer->getFloat(-M_E, M_PI); // 2.1484303282097

                    echo $dogName = $randomizer->getBytesFromString('My', 4); // MyMy
                
            

RFC | Документация

Что ещё почитать и посмотреть

Краткая инструкция по обновлению

                
                    composer why-not php '^8.3'
                
            
                
                    composer require php '^8.3'
                
            

Не забываем про Rector!

                
                    composer require --dev rector/rector
                
            
                
                    // rector.php

                    return static function (RectorConfig $rectorConfig): void {
                        $rectorConfig->parallel();
                        $rectorConfig->paths([
                            __DIR__ . '/src',
                            __DIR__ . '/tests',
                        ]);
                        $rectorConfig->sets([
                            LevelSetList::UP_TO_PHP_83, ✅
                        ]);
                    };
                
            
                
                    php vendor/bin/rector process
                
            

Прогресс или стагнация?

4.0.02000, MayZend Engine
4.1.02001, DecemberПроизводительность, улучшена подд. Windows
4.2.02002, AprilСуперглобальные переменные
4.3.02002, DecemberCLI, Streams API
4.4.02005, JulyMaintenance release
5.0.02004, JulyZend Engine 2, ООП, SimpleXML, SOAP, MySQLi, SQLite
5.1.02005, NovemberПереписана обработка дат, производительность
5.2.02006, NovemberУлучшена работа с памятью, JSON, ZIP, обработка загруженных файлов
5.3.02009, JuneНеймспейсы, LSB, замыкания, goto
5.4.02012, FebruaryТрейты, [], встроенный сервер
5.5.02013, JuneГенераторы, finally, ::class, OPcache
5.6.02014, AugustОператор ..., распаковка массивов, импорт функций
7.0.02015, DecemberZend Engine 3, скалярные и возвр. типы, ??, <=>, анонимные классы
7.1.02016, NovemberNullable типы, видимость констант, void, iterable
7.2.02017, NovemberТип object, Sodium
7.3.02018, DecemberГибкий heredoc, конечная запятая в вызовах, улучшен GC
7.4.02019, NovemberТипизация свойств, стрелочные ф-ции, ??=, preloading, FFI
8.0.02020, NovemberNamed аргументы, #[Attribute], promoted св-ва, |-типы, match, JIT
8.1.02021, NovemberEnum, Fiber, (...), &-типы, never, readonly, new в инициализаторах
8.2.02022, December#[SensitiveParameter], null, false типы, readonly классы
8.3.02023, NovemberТипы констант классов, #[Override], глубокое клонирование readonly

Всех с релизом 🎉

PHP cannot die!

@vudaltsov / Пых / PHP Point