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 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"><?php<br /></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">{<br /> echo </span><span style="color: #DD0000">"Hello 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"><?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