
Привет.
Параллельно с разработкой PHP 7.4 идет работа над следующим крупным релизом языка - PHP 8.0. Хоть его релиз состоится не так скоро, - в конце 2020 года, - не вижу причин для того, чтобы уже сейчас начать собирать информацию о том, что войдет в финальную версию. Как и предыдущие чейнджлоги, данный будет обновляться вплоть до выпуска стабильной версии.
Содержание
- Вызов фатальной ошибки для несовместимых сигнатур методов
- Массивы, начинающиеся с отрицательного индекса
TypeError
для внутренних функций- JIT
Изменения
Вызов фатальной ошибки для несовместимых сигнатур методов
Ошибки наследования из-за несовместимых сигнатур методов при наследовании (LSP) теперь всегда будут генерировать фатальную ошибку (сейчас в ряде случаев могут генерировать предупреждение).
class C1 {
public function method($a): array {}
}
class C2 extends C1 {
public function method($a): int {}
}
// Fatal error: Declaration of C2::method($a): int must be compatible with C1::method($a): array
Массивы, начинающиеся с отрицательного индекса
Будет изменено правило, используемое при генерации целочисленных ключей массивов (например, функцией array_fill
):
...если ключ не был указан, то будет взят максимальный из существующих целочисленных индексов, и новым ключом будет это максимальное значение (но не менее 0) плюс 1.
Теперь ключи массива всегда будут генерироваться по правилу n + 1
, то есть новый ключ будет равен предыдущему ключу + 1, игнорируя минимальное значение.
$a = array_fill(-2, 3, true);
$b = [-2 => true, true, true];
$c = ["string" => true, -2 => true, true, true];
unset($c["string"]);
$d[-2] = true;
$d[] = true;
$d[] = true;
// php <= 7.4
array(3) {
[-2]=>
bool(true)
[0]=>
bool(true)
[1]=>
bool(true)
}
// php 8.0
array(3) {
[-2]=>
bool(true)
[-1]=>
bool(true)
[0]=>
bool(true)
}
TypeError
для внутренних функций
В то время как передача некорректных параметров в пользовательские функции всегда вызывает TypeError
, поведение внутренних функций зависит от нескольких факторов, но по-умолчанию выдается предупреждение и возвращается null
.
function foo(int $bar) {}
foo("not an int");
// TypeError: Argument 1 passed to foo() must be of the type int, string given
var_dump(strlen(new stdClass));
// Warning: strlen() expects parameter 1 to be string, object given
// NULL
Есть так же порядка 150 функций, которые будут возвращать false
. Но, если включен strict_types
, поведение будет аналогично пользовательским функциям.
declare(strict_types=1);
var_dump(strlen(new stdClass));
// TypeError: strlen() expects parameter 1 to be string, object given
В PHP 8.0 внутренние API-интерфейсы анализа всегда будут генерировать TypeError
в случае, если анализ завершился неудачно. Это касается и ArgumentCountError
(наследника TypeError
). Функции, которые обрабатывают параметры вручную (не используют типизацию аргументов), так же будут следовать этому поведению.
JIT
Если вкраце, JIT (Just In TIme), - компилятор, преобразующий генерируемый PHP байткод в специфичный для текущей аппаратной платформы машинный код, способный напрямую исполняться процессором, минуя Zend VM.
Он практически бесполезен для PHP как языка веб-приложений, т.к. скорость выполнения на CPU не является большой проблемой и не отнимает много времени. Но может помочь в машинном обучении, математических расчетах, анализе данных, 2D и 3D рендеринге. (OpenNet)
До этого момента развивающийся отдельно от PHP, JIT будет доступен "из коробки" в версии 8.0, а в php.ini
появятся новые настройки для работы с компилятором.