PHP версия 8.3 - какво е новото?

PHP версия 8.3 ще бъде пусната за публична употреба на 23 ноември 2023 година. Тя вкарва относително по-малко новости от версии 8.1 и 8.2, но това не значи, че трябва да се подценява. В тази статия ще разгледаме нововъведенията, които се предоставят, както и промени, които могат да засегнат някои PHP програми.

Съдържание

  • Поддръжка на версии
  • Новости
    • Типизирани константи в класове
    • Нова json_validate() функция
    • Поддръжка за динамично извличане на константа от клас и член от Enum
    • Нова информация в gc_status():
    • Нов метод \Random\Randomizer::getBytesFromString()
    • Нови \Random\Randomizer::getFloat() и nextFloat() методи
    • Поддръжка на резервни стойности за Environment Variables в PHP INI файлове
    • PHP CLI Lint (php -l) поддръжка на няколко файла
    • Поддръжка на вградени PHP класове за class_alias() функцията
    • Нова функция stream_context_set_options()
  • Промени в синтаксиса/функционалността
    • unserialize(): E_NOTICE става E_WARNING
    • Промени в изходния код на highlight_file() and highlight_string() фунцкиите.
    • Подробни грешки за DateTime
    • Добавени типове при деклриране на константи в някои класове на PHP разширения
    • Промяна на формата на стойността $_SERVER['SERVER_SOFTWARE'] от вградения в PHP сървър
  • Деприкации
    • Извикване на get_class() и get_parent_class() без аргументи.
  • Заключение

Поддръжка на версии

На първо място, важно е да споменем малко за поддръжката на различни PHP версии. Версия 8.0 не се поддържа и подобрява от 26ти ноември 2022г., а ъпдейтите по сигурността ще спрат на 26ти ноември 2023г. Поддръжката на 8.1 ще спре ден по-рано, а именно на 25ти, като ще има поддръжка на сигурността точно една година - до 25.11.2024г. Версии 8.2 и 8.3 ще продължат да бъдат поддържани до приблизително същите дати, но през 2024 и 2025 г., а поддръжката по сигурността е удължена с една година - съответно до 2025 и 2026 г.

Поддръжка на PHP версии

Новости

Типизирани константи в класове

PHP 8.3 включва поддръжка за деклариране на тип за PHP Class константи. Това гарантира типова съвместимост на константите, когато дъщерните класове и имплементацията на интерфейса ги заместват.

Преди PHP 8.3 не беше възможно програмно да се наложи съвместимост на типове.

Примери:

class Object
{
    const string CONSTANT = 'string';
}
class Object {
    const string CONSTANT = 1; // извежда грешка
    //Fatal error: Cannot use int as value for class constant Object::CONSTANT of type string
}

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

Тази функция се използва за валидирабне на JSON низове. Ако даден JSON е валиден връща true, в противен случай - false.

json_validate('[1, 2, 3]'); // true
json_validate('{1, 2, 3]'); // false

Поддръжка за динамично извличане на константа от клас и член от Enum

От версия 8.3 вече е възможно извличане на константа от клас или на член от Enum чрез променлива. В по-стари версии това би довело до грешка.

class Object {
    public const CONST = 'const';
}

$const_name = 'CONST';

echo Object::{$const_name}; // 'const'
enum SomeEnum: int {
    case Member = 42;
}

$member_name = 'Member';

echo SomeEnum::{$member_name}->value; // 42

Нова информация в gc_status():

Функцията gc_status() се използва за показване на статистика относно PHP Garbage Collector-а. До сега тя връщаше масив с 4 ключа:

Поле Тип Описание
runs Integer Брой пъти, в които garbage collector-ът е стартиран.
collected Integer Броят на събраните обекти.
threshold Integer Броят на root-ове в буфера, които ще задействат garbage collection.
roots Integer Текущият брой root-ове в буфера.

Във версия 8.3 са добавени още 8 нови стойности в статистиката:

Поле Тип Описание
running Boolean true ако GC работи в момента. false ако не.
protected Boolean true ако garbage collector-ът е защитен и root добавките са забранени. false ако не.
full Boolean true, ако размерът на буфера за събиране на отпадъци надвишава GC_MAX_BUF_SIZE.
buffer_size Integer Текущ размер на буфера за събиране на отпадъци.
application_time Float Общо време за прилагане, зададено в секунди (включително collector_time).
collector_time Float Време прекарано в цикли за събиране в секунди (включително destructor_time и free_time).
destructor_time Float Времето, прекарано в изпълнение на деструктори.
free_time Float Времето, изразходвано за освобождаване на стойности.

Нов метод \Random\Randomizer::getBytesFromString()

PHP има разширението Random, което предоставя класа Randomizer. Във версия 8.3 той получава новата функция getBytesFromString(), която връща последователност от произволни числа от подаден низ от символи.

Пример:

$rng = new Random\Randomizer();
$chars = 'AEIOU';

$rng->getBytesFromString($chars, 1); // "E"
$rng->getBytesFromString($chars, 5); // "AIIEO"
$rng->getBytesFromString($chars, 10); // "IEAUAIIOUE"

Първият параметър е низът от символи, от който функцията взима произволните стойности, а вторият е броят на произволни символи, които искаме.

Важно е да се спомене, че присъствието на даден символ повече пъти от друг, ще увеличи шансовете му да бъде избран, както и че функцията работи на ниво “байт”. Това ще означава, че не е подходяща за употреба върху многобайтови символи като: букви от кирилицата, емоджита и др.

Нови \Random\Randomizer::getFloat() и nextFloat() методи

Още нововъведения в Randomizer класа са функциите getFloat() и nextFloat().

getFloat() позволява да се вземе произволно число с плаваща запетая между $min и $max, като може да се определи дали тези два параметъра са включителни или не, посредством трети параметър $boundary, който е от тип \Random\IntervalBoundary Enum.

$rng = new Random\Randomizer();
$rng->getFloat(0, 10, \Random\IntervalBoundary::OpenOpen); // 9.3835746900717

Различните стойности на \Random\IntervalBoundary са:

enum IntervalBoundary {
	case ClosedOpen;   // $min е включено, $max е изключено
	case ClosedClosed; // $min е включено, $max е включено
	case OpenClosed;   // $min е изключено, $max е включено
	case OpenOpen;     // $min е изключено, $max е изключено
}

Методът nextFloat() от своя стана, е идентичен на getFloat(0, 1, \\Random\\IntervalBoundary::ClosedOpen).

$rng = new Random\Randomizer();
$rng->nextFloat(); // 0.21185336351144

Поддръжка на резервни стойности за Environment Variables в PHP INI файлове

Да разгледаме следния пример: Имаме файл php.ini с променлива session.name, която приема стойността си от променливата на средата (Environment Variable) SESSION_NAME.

session.name = ${SESSION_NAME}

В следния случай, ако нямаме зададена стойност на SESSION_NAME, то при извикване на ini_get('session.name'); ще получим празен string.

В PHP 8.3 се добавя поддръжка за резервни стойности за INI файловете, което ще означава, че можем да дефинираме такава стойност за session.name. В този случай ще получим резервната стойност (Session) вместо празен string.

session.name = ${SESSION_NAME:-Session}

PHP CLI Lint (php -l) поддръжка на няколко файла

PHP има вграден софтуер за проверка за грешки, наречен “linter”, който може да проверява даден файл за синтактични грешки и проблеми.

php -l script.php
// No syntax errors detected in script.php

От версия 8.3 натам, обаче, той вече поддържа подаването на няколко файла наведнъж.

php -l script.php api.php
// No syntax errors detected in script.php
// No syntax errors detected in api.php

Поддръжка на вградени PHP класове за class_alias() функцията

PHP позволява създаване на клас копие на друг клас с единствена разлика името. Това става чрез функцията class_alias(). В PHP 8.3 е добавена поддръжка за създаване на такива класове от вградени класове (такива, които не са създадени от потребителя). Това не бе възможно в по-стари версии.

// Не е позволено в PHP < 8.3
class_alias('stdClass', 'MyNewClass');

// ValueError: class_alias(): Argument #1 ($class) must be a user-defined class name, internal class name given

Нова функция stream_context_set_options()

В PHP има функция stream_context_set_option, която има 2 дефиниции:

function stream_context_set_option(
	$stream_or_context,
	string $wrapper,
	string $option,
	mixed $value
): bool {}

function stream_context_set_option($stream_or_context, array $options): bool {}

Новата функция stream_context_set_options()ще върши същото и ще поддържа само 2-рата дефиниция.

В PHP 8.4 първата дефиниция на stream_context_set_option() ще бъде depricated, а във версия 9.0 изцяло премахната.

Промени в синтаксиса/функционалността

unserialize(): E_NOTICE става E_WARNING

unserialize() е функция в PHP, която се използва за конвертиране на сериализирани стрингове във валидни PHP променливи.

$array = ['apple', 'banana', 'orange'];
$serialized = serialize($array);
// "a:3:{i:0;s:5:"apple";i:1;s:6:"banana";i:2;s:6:"orange";}"

$usserialized = unserialize($serialized);
// ['apple', 'banana', 'orange']

Когато на unserialize() се подаде неправилен низ от символи, който не може да бъде обработен, в предходните версии на PHP, функцията илъчва E_NOTICE. Това вече няма да е така и вместо това тя ще излъчва E_WARNING.

Промени в изходния код на highlight_file() and highlight_string() фунцкиите.

PHP има функциите highlight_file() и highlight_string(), които служат за форматиране на PHP код в HTML. Те приемат файл или низ съдържащ PHP код и предоставят синтактично маркиран код готов за употреба в HTML.

Във версия 8.3 промените са:

  • Целият изходен код е ограден в <pre> таг,
  • Не конвертира новите редове в <br/> тагове, което водиу до многоредов HTML изходен код;

Преди 8.3:

<code><span style="color: #000000"> <span style="color: #0000BB">&lt;?php<br /></span><span style="color: #007700">function&nbsp;</span><span style="color: #0000BB">hello</span><span style="color: #007700">():&nbsp;</span><span style="color: #0000BB">void&nbsp;</span><span style="color: #007700">{<br />&nbsp;&nbsp;&nbsp;&nbsp;echo&nbsp;</span><span style="color: #DD0000">"Hello&nbsp;World"</span><span style="color: #007700">;<br />}<br /><br /></span><span style="color: #0000BB">hello</span><span style="color: #007700">();</span> </span> </code>

След 8.3:

<pre><code style="color: #000000"><span style="color: #0000BB">&lt;?php
</span><span style="color: #007700">function </span><span style="color: #0000BB">hello</span><span style="color: #007700">(): </span><span style="color: #0000BB">void </span><span style="color: #007700">{
    echo </span><span style="color: #DD0000">"Hello World"</span><span style="color: #007700">;
}

</span><span style="color: #0000BB">hello</span><span style="color: #007700">();</span></code></pre>

Подробни грешки за DateTime

До сега грешките, които разширението DateTime, можеше да връща бяха най-основните \Exception и \Error. За да има по-добро разделение на грешките, във версия 8.3 ще бъдат добавени девет нови подкласа на тези грешки.

Throwable
  ├── Error
  |     └── DateError
  |             ├── DateObjectError
  │             └── DateRangeError
  └── Exception
        └── DateException
                ├── DateInvalidTimeZoneException
                ├── DateInvalidOperationException
                ├── DateMalformedStringException
                ├── DateMalformedIntervalStringException
                └── DateMalformedPeriodStringException
  • DateError - получават се ако основната база данни timelib е повредена. Това значи, че нещо не е наред със самата настройка на PHP,
    • DateObjectError - възниква, когато обект Date/Time не е правилно инициализиран,
    • DateRangeError - при опит за обработка на дата, която надвишава максималната целочислена стойност за PHP,
  • DateException - за невалидни стойности, предоставени от потребителя,
    • DateInvalidTimeZoneException - невалидна часова зона или задаване на отместване на часовата зона извън диапазона,
    • DateInvalidOperationException - извършване на невалидна операция с DateTime обект
    • DateMalformedStringException - не може да се извлече валидна дата/час от даден низ
    • DateMalformedIntervalStringException - не може да се извлече валиден интервал от даден низ
    • DateMalformedPeriodStringException - не може да се извлече валиден период от даден низ

Добавени типове при деклриране на константи в някои класове на PHP разширения

Както вече разбрахме, от PHP 8.3 имаме възможността да декларираме типизирани константи в класове.

class Obejct {
    public const string CONST = 'Const';
}

По този начин са решили да обновят някои класове в някои PHP допълнения. Това само улеснява употребата им понеже вече ще е ясно каква е върнатата стойност по всяко време. Засегнатите класове са:

  • класът \Phar от Phar разширението
  • класът \SNMP от SNMP разширението
  • класът \ZipArchive от Zip разширението

Промяна на формата на стойността $_SERVER['SERVER_SOFTWARE'] от вградения в PHP сървър

PHP има вграден сървър, който може да се използва за тестване на апликации, без нужда от сложни конфигурации на Apache или NGinx. До сега стойността на супер-глобалната променлива $_SERVER['SERVER_SOFTWARE'], при употребата на този сървър беше в разрез с изискванието наложено от RFC3875 - 4.1.17. В PHP 8.3 обаче, стойността е променена, така че да е с валиден формат спрямо RFC-то.

PHP 8.2.0 Development Server   // PHP 8.2
PHP/8.3.0 (Development Server) // PHP 8.3

Деприкации

Извикване на get_class() и get_parent_class() без аргументи.

get_class() се използва за да се вземе името на класа от чийто тип е даден обект, а get_parent_class() - името на наследения клас. Досега те можеха да се използват по два начина:

  • С подаване на параметър
echo get_class(new stdClass()); // "stdClass"
  • В контекста на обект
class Object
{
   public function __construct() {
       echo get_class(); // "Object"
   }
}

Вторият начин вече ще даде deprecation notice, а във версия 9.0 ще доведе до грешка ArgumentCountError след като бъде премахнат изцяло. Това важи и за двете функции, въпреки, че сме дали пример само с едната.

Възможни алтернативи за get_class() са:

$object::class; // Добавено във версия 8.0

class Object
{
    public function __construct() {
        echo __CLASS__;
        // или
        echo get_class($this);
    }
}

Възможни алтернативи за get_parent_class():

get_parent_class($object);

class Object extends BaseObject
{
    public function __construct() {
        echo parent::class;
        // или
        echo get_parent_class($this);
    }
}

Заключение

Като заключение можем да добавим само, че екипът зад PHP продължава да полага големи усилия за разработката и подобряването на езика. Най-новият ъпдейт, PHP 8.3, представлява още една стъпка напред в развитието на PHP и носи със себе си множество полезни функционалности и оптимизации.

Като PHP програмисти, ние можем да потвърдим, че всяко ново издание допринася значително за подобряването на ежедневната разработка на софтуер. С нетърпение очакваме всички нови версии на езика и с нетърпение очакваме да видим как те ще подпомогнат и оптимизират нашата работа в бъдеще.

Вярваме, че PHP остава едно от най-силните средства за уеб разработка и че ще продължи да се развива и да предоставя иновации за всички програмисти по света.

За повече информация може да посетите:
https://php.watch/versions/8.3
https://php.watch/versions/8.3/releases
https://www.php.net/supported-versions.php

Статия от Александър Найденов

Като възпитаник на ТУЕС - София, Алекс работи активно в сферата на уеб разработката. Стреми се да разширява своите умения и опит в тази област. Разработва PHP / Laravel приложения. В допълнение на това, има страст към Python и JavaScript, които счита за вълнуващи.

Социални мрежи:
Още статии от автора

Абонирайте се за нашия бюлетин

С абонамента си получаваш повече актуални новини и нашите специални промо оферти

Абонирайте се за нашия бюлетин