It should be noted that typed properties internally are never initialized to a default null. Unless of course you initialize them to null yourself. That's why you will always going to encounter this error if you try to access them before initialization.
**Typed property foo::$bar must not be accessed before initialization**
<?php
class User
{
public $id;
public string $name; // Typed property (Uninitialized)
public ?string $age = null; // Typed property (Initialized)
}
$user = new User;
var_dump(is_null($user->id)); // bool(true)
var_dump(is_null($user->name)); // PHP Fatal error: Typed property User::$name must not be accessed before initialization
var_dump(is_null($user->age));// bool(true)
?>
Another thing worth noting is that it's not possible to initialize a property of type object to anything other than null. Since the evaluation of properties happens at compile-time and object instantiation happens at runtime. One last thing, callable type is not supported due to its context-dependent behavior.Нови одлики
Почист и полокален преглед на PHP референцата, со задржана структура од PHP.net и подобра читливост за примери, секции и белешки.
Нови одлики
Референца за `migration74.new-features.php` со подобрена типографија и навигација.
Нови одлики
PHP јадро
Типизирани својства
Својствата на класата сега поддржуваат декларации за тип.
<?php
class User {
public int $id;
public string $name;
}
?>$user->id може да биде доделено само int вредности и $user->name може да биде доделено само string values.
Функции со стрелки
Функции со стрелки обезбедуваат кратенка за дефинирање функции со имплицитно врзување на опсегот по вредност.
<?php
$factor = 10;
$nums = array_map(fn($n) => $n * $factor, [1, 2, 3, 4]);
// $nums = array(10, 20, 30, 40);
?>Ограничена коваријанса на типот на враќање и контраваријанса на типот на аргументот
Следнава шифра сега ќе работи:
<?php
class A {}
class B extends A {}
class Producer {
public function method(): A {}
}
class ChildProducer extends Producer {
public function method(): B {}
}
?><?php
/**
* These classes satisfy the LSP requirements, because C is a subtype of A.
* However, at the time class B is declared, class C is not yet available
*/
class A
{
public function method(): A {}
}
class B extends A
{
// Fatal error: Could not check compatibility between B::method():C and
// A::method(): A, because class С is not available
public function method(): С {}
}
class C extends B {}
?>Оператор за доделување на спојување на нула
<?php
$array['key'] ??= computeDefault();
// is roughly equivalent to
if (!isset($array['key'])) {
$array['key'] = computeDefault();
}
?>Распакување внатре во низи
<?php
$parts = ['apple', 'pear'];
$fruits = ['banana', 'orange', ...$parts, 'watermelon'];
// ['banana', 'orange', 'apple', 'pear', 'watermelon'];
?>Сепаратор на нумерички литерал
Нумеричките литерали можат да содржат подвлекувања помеѓу цифрите.
<?php
6.674_083e-11; // float
299_792_458; // decimal
0xCAFE_F00D; // hexadecimal
0b0101_1111; // binary
?>Слаби референци
Слаби референци му дозволуваат на програмерот да задржи референца на објект што не го спречува објектот да биде уништен.
Дозволи исклучоци од __toString()
Фрлање исклучоци од __toString() сега е дозволено. Претходно ова резултираше со фатална грешка. Постоечките отстранливи фатални грешки во конверзиите на низи беа претворени во Грешка exceptions.
CURL
CURLFile сега поддржува стрим обвивки покрај обични имиња на датотеки, ако екстензијата е изградена против libcurl >= 7.56.0.
Филтер
На FILTER_VALIDATE_FLOAT филтерот сега поддржува
min_range and max_range
опции, со исто значење како FILTER_VALIDATE_INT.
FFI
FFI е нова екстензија, која обезбедува едноставен начин за повикување на нативни функции, пристап до нативни променливи и креирање/пристап до структури на податоци дефинирани во C библиотеки.
GD
Додаден е IMG_FILTER_SCATTER филтер за слика за примена на филтер за расејување на слики.
Хеш
Додадено crc32c хеш користејќи го полиномот на Castagnoli. Оваа CRC32 варијанта се користи од системи за складирање, како што се iSCSI, SCTP, Btrfs и ext4.
Повеќебајтни низи
Додаден е mb_str_split() функција, која обезбедува иста функционалност како str_split(), но работи на кодови наместо бајти.
OPcache
Поддршка за претходно вчитување на код е додадена.
Регуларни изрази (компатибилни со Perl)
На preg_replace_callback() and preg_replace_callback_array()
функциите сега прифаќаат дополнителен flags аргумент, со поддршка за
PREG_OFFSET_CAPTURE and PREG_UNMATCHED_AS_NULL знаменца. Ова влијае на форматот на низата за совпаѓања што се предава на функцијата за повикување.
PDO
Корисничкото име и лозинката сега можат да се специфицираат како дел од PDO DSN за драјверите mysql, mssql, sybase, dblib, firebird и oci. Претходно ова беше поддржано само од драјверот pgsql. Ако корисничко име/лозинка е специфицирано и во конструкторот и во DSN, конструкторот има предност.
Сега е можно да се избегнат прашалници во SQL прашања за да се избегне нивното толкување како заменски места за параметри. Пишување ??
овозможува испраќање на еден прашалник до базата на податоци и на пр. користење на постоечкиот JSON клуч на PostgreSQL (?) оператор.
PDO_OCI
Некои драјвери можеби не имплементираат е сега достапен.
PDO_SQLite
PDOStatement::getAttribute(PDO::SQLITE_ATTR_READONLY_STATEMENT)
овозможува проверка дали изјавата е само за читање, т.е. ако не менува база на податоци.
PDO::setAttribute(PDO::SQLITE_ATTR_EXTENDED_RESULT_CODES, true)
овозможува користење на SQLite3 проширени кодови за резултати во Пример #1 Преземање на SQLSTATE код
and - Преземи го SQLSTATE поврзан со последната операција на рачката на изјавата.
SQLite3
Додадено SQLite3::lastExtendedErrorCode() за добивање на последниот проширен код за резултат.
Додадено SQLite3::enableExtendedResultCodes($enable = true), што ќе направи (PHP 5 >= 5.3.0, PHP 7, PHP 8)
враќа проширени кодови за резултати.
Стандардно
strip_tags() со низа од имиња на тагови
strip_tags() сега прифаќа и низа од дозволени тагови: наместо strip_tags($str, '<a><p>')
сега можете да напишете strip_tags($str, ['a', 'p']).
Прилагодена серијализација на објекти
Додаден е нов механизам за прилагодена серијализација на објекти, кој користи два нови магични методи: __serialize
and __unserialize.
<?php
// Returns array containing all the necessary state of the object.
public function __serialize(): array
{
}
// Restores the object state from the given data array.
public function __unserialize(array $data): void
{
}
?>Функции за спојување низи без аргументи
array_merge() and array_merge_recursive()
сега може да се повикаат без никакви аргументи, во кој случај ќе вратат празна низа. Ова е корисно во комбинација со операторот за ширење, на пр. array_merge(...$arrays).
proc_open() function
proc_open() сега прифаќа низа наместо стринг за командата. Во овој случај процесот ќе се отвори директно (без поминување низ шел) и PHP ќе се погрижи за секое потребно бегство од аргументи.
<?php
proc_open(['php', '-r', 'echo "Hello World\n";'], $descriptors, $pipes);
?>
proc_open() сега поддржува
redirect and null descriptors.
<?php
// Like 2>&1 on the shell
proc_open($cmd, [1 => ['pipe', 'w'], 2 => ['redirect', 1]], $pipes);
// Like 2>/dev/null or 2>nul on the shell
proc_open($cmd, [1 => ['pipe', 'w'], 2 => ['null']], $pipes);
?>argon2i(d) без libargon
password_hash() сега ги има имплементациите argon2i и argon2id од екстензијата sodium кога PHP е изграден без libargon.
Белешки од корисници 2 забелешки
<?php
// How to get property type? For example for testing:
class Foo
{
private int $num;
private bool $isPositive;
private $notes;
}
$reflection = new \ReflectionClass(Foo::class);
$classProperties = $reflection->getProperties(\ReflectionProperty::IS_PRIVATE);
foreach ($classProperties as $classProperty) {
var_dump((string) $classProperty->getType());
}
/**
* Result:
* "int"
* "bool"
* ""
*/