Справочник по PHP 7.2
Справочник по PHP 7.1
PHP 7 был выпущен 3 декабря 2015 года. Он содержит ряд новых функций, изменений и недостатков обратной совместимости, которые описаны ниже.
Производительность
Функции
Комбинированный оператор сравнения
Нулевой оператор объединения
Объявления скалярного типа
Объявления возвращаемого типа
Анонимные классы
Синтаксис escape-кода Unicode
Метод закрытия call()
Фильтрованная unserialize()
Класс IntlChar
Ожидания
Объявления группового use
Выражения, возвращающие генератор
Делегирование генератора
Целочисленное деление с помощью intdiv()
Параметры session_start()
Функция preg_replace_callback_array()
CSPRNG-функции
Поддержка констант массива в define()
Дополнения к отражению
Изменения
Ослабление ограничений на зарезервированные слова
Единый синтаксис переменных
Исключения в движке
Перебрасываемый интерфейс
Целочисленная семантика
Расширение JSON заменено на JSOND
Сбой ZPP при переполнении
Исправления в поведении foreach()
Изменения в поведении list()
Изменения в делении по нулевой семантике
Исправления в возвращаемых значениях пользовательского обработчика сеансов.
Устаревание конструкторов PHP 4-го стиля
Удаление date.timezone Предупреждение
Удаление альтернативных тегов PHP
Удаление нескольких блоков по умолчанию в операторах Switch
Удаление переопределения параметров с повторяющимися именами
Удаление API-интерфейсов мертвого сервера
Удаление поддержки шестнадцатеричных чисел в числовых строках
Удаление устаревшей функциональности
Реклассификация и удаление уведомлений E_STRICT
Устаревшая опция Salt для password_hash()
Ошибка недопустимых восьмеричных литералов
Изменение возвращаемого значения substr()
Часто задаваемые вопросы
Что случилось с PHP 6?
Бесспорно, самое главное в PHP 7 — это невероятный прирост производительности, который он обеспечивает приложениям. Это результат рефакторинга Zend Engine с целью использования более компактных структур данных и меньшего количества выделений/освобождений кучи.
Прирост производительности в реальных приложениях будет разным, хотя многие приложения, по-видимому, получают прирост производительности примерно на 100%, а также с меньшим потреблением памяти!
Рефакторинг кодовой базы также предоставляет дополнительные возможности для будущей оптимизации (например, JIT-компиляции). Таким образом, похоже, что в будущих версиях PHP также будет наблюдаться повышение производительности.
Сравнение диаграмм производительности PHP 7:
Ускорение Интернета с помощью PHP 7
Ориентиры из выступления Расмуса в Сиднее
Комбинированный оператор сравнения (или оператор космического корабля) — это сокращенная запись для выполнения трехстороннего сравнения двух операндов. Он имеет целочисленное возвращаемое значение, которое может быть:
положительное целое число (если левый операнд больше правого операнда)
0 (если оба операнда равны)
отрицательное целое число (если правый операнд больше левого операнда)
Этот оператор имеет тот же приоритет, что и операторы равенства ( ==
, !=
, ===
, !==
), и ведет себя точно так же, как и другие операторы свободного сравнения ( <
, >=
и т. д.). Он также неассоциативен, как и они, поэтому объединение операндов в цепочку (например, 1 <=> 2 <=> 3
) не допускается.
// сравнивает строки лексическиvar_dump('PHP' <=> 'Node'); // int(1)// сравнивает числа по sizevar_dump(123 <=> 456); // int(-1)// сравнивает соответствующие элементы массива с одним-другимvar_dump(['a', 'b'] <=> ['a', 'b']); // целое(0)
Объекты несопоставимы, поэтому использование их в качестве операндов с этим оператором приведет к неопределенному поведению.
RFC: комбинированный оператор сравнения
Нулевой оператор объединения (или тернарный оператор isset) — это сокращенная запись для выполнения проверок isset()
в тернарном операторе. Это обычное дело в приложениях, поэтому именно для этой цели был введен новый синтаксис.
// Код до PHP 7 $route = isset($_GET['route']) ? $_GET['route'] : 'index';// Код PHP 7+ $route = $_GET['route'] ?? 'индекс';
RFC: оператор нулевого объединения
Объявления скалярных типов бывают двух видов: принудительные (по умолчанию) и строгие . Теперь можно применять следующие типы параметров (принудительно или строго): строки ( string
), целые числа ( int
), числа с плавающей запятой ( float
) и логические значения ( bool
). Они дополняют другие типы, представленные в версиях PHP 5.x: имена классов, интерфейсы, array
и callable
.
// Функция принудительного режима sumOfInts(int ...$ints) { return array_sum($ints); }var_dump(sumOfInts(2, '3', 4.1)); // целое(9)
Чтобы включить строгий режим, в верхней части файла необходимо разместить одну директиву declare()
. Это означает, что строгость ввода скаляров настраивается отдельно для каждого файла. Эта директива влияет не только на объявления типов параметров, но также на тип возвращаемого значения функции (см. Объявления типа возвращаемого значения), встроенные функции PHP и функции из загруженных расширений.
Если проверка типа не удалась, выдается исключение TypeError
(см. Исключения в движке). Единственная снисходительность, присутствующая при строгой типизации, — это автоматическое преобразование целых чисел в числа с плавающей запятой (но не наоборот), когда целое число предоставляется в контексте с плавающей запятой.
объявлять(strict_types=1);функция умножения(float $x, float $y) { вернуть $x * $y; } функция add(int $x, int $y) { вернуть $x + $y; }var_dump(умножить(2, 3.5)); // float(7)var_dump(add('2', 3)); // Неустранимая ошибка: Uncaught TypeError: Аргумент 1, переданный в add(), должен иметь целочисленный тип, заданную строку...
Обратите внимание, что при выполнении проверки типов применяется только контекст вызова . Это означает, что строгая типизация применяется только к вызовам функций/методов, а не к определениям функций/методов. В приведенном выше примере две функции могли быть объявлены либо в строгом, либо в принудительном файле, но пока они вызываются в строгом файле, будут применяться строгие правила типизации.
Британская Колумбия Брейки
Классы с именами int
, string
, float
и bool
теперь запрещены.
RFC: объявления скалярных типов
Объявления типа возвращаемого значения позволяют указать тип возвращаемого значения функции, метода или замыкания. Поддерживаются следующие типы возвращаемых значений: string
, int
, float
, bool
, array
, callable
, self
(только методы), parent
(только методы), Closure
, имя класса и имя интерфейса.
функция arraysSum(массив ...$arrays): array{ return array_map(function(array $array): int { return array_sum($array); }, $массивы); }print_r(arraysSum([1,2,3], [4,5,6], [7,8,9]));/* OutputArray( [0] => 6 [1] => 15 [2] => 24)*/
Что касается подтипов, для возвращаемых типов была выбрана инвариантность . Это просто означает, что когда метод либо переопределяется в подтипированном классе, либо реализуется, как определено в контракте, его тип возвращаемого значения должен точно соответствовать методу, который он (пере) реализует.
класс A {}класс B расширяет A {}класс C { тест публичной функции(): A { вернуть новый A; } }класс D расширяет C { // переопределяющий метод C::test() : общедоступная функция test() : B // Фатальная ошибка из-за несоответствия дисперсии { вернуть новый B; } }
Переопределяющий метод D::test() : B
вызывает ошибку E_COMPILE_ERROR
, поскольку ковариация не допускается. Чтобы это работало, метод D::test()
должен иметь возвращаемый тип A
класс A {}интерфейс SomeInterface {тест публичной функции(): A; }класс B реализует SomeInterface { public function test() : A // все хорошо! { вернуть ноль; // Неустранимая ошибка: Uncaught TypeError: Возвращаемое значение B::test() должно быть экземпляром A, возвращается ноль... } }
На этот раз реализованный метод вызывает исключение TypeError
(см. Исключения в движке) при выполнении. Это связано с тем, что null
не является допустимым типом возвращаемого значения — может быть возвращен только экземпляр класса A
RFC: объявления возвращаемых типов
Анонимные классы полезны, когда необходимо создать простые одноразовые объекты.
// Класс кода до версии PHP 7 Logger { журнал общедоступной функции ($msg) {эхо $msg; } }$util->setLogger(new Logger());// Код PHP 7+ $util->setLogger(new class { public function log($msg) {эхо $msg; } });
Они могут передавать аргументы своим конструкторам, расширять другие классы, реализовывать интерфейсы и использовать черты, как это может делать обычный класс:
класс SomeClass {}интерфейс SomeInterface {}trait SomeTrait {}var_dump(new class(10) расширяет SomeClass реализует SomeInterface { Private $num; публичная функция __construct($num) { $this->num = $num; } используйте SomeTrait; });/** Вывод:object(class@anonymous)#1 (1) { ["Код командной строки0x104c5b612":"class@anonymous":private]=> int(10)}*/
Вложение анонимного класса в другой класс не дает ему доступа к каким-либо частным или защищенным методам или свойствам этого внешнего класса. Чтобы использовать защищенные свойства или методы внешнего класса, анонимный класс может расширить внешний класс. Чтобы использовать частные или защищенные свойства внешнего класса в анонимном классе, их необходимо передать через его конструктор:
<?phpclass Внешний {частное $prop = 1; защищенный $prop2 = 2; защищенная функция func1() {возврат 3; } публичная функция func2() { return new class($this->prop) расширяет Outer {private $prop3; публичная функция __construct($prop) { $this->prop3 = $prop; } публичная функция func3() { return $this->prop2 + $this->prop3 + $this->func1(); } }; } }echo (новый внешний)->func2()->func3(); // 6
RFC: анонимные классы
Это позволяет выводить кодовую точку Юникода в кодировке UTF-8 либо в виде строки в двойных кавычках, либо в виде Heredoc. Принимается любой действительный код, 0
в начале не являются обязательными.
эхо "u{аа}"; // ªecho "u{0000aa}"; // ª (то же самое, что и раньше, но с необязательными ведущими нулями)echo "u{9999}"; // 香
RFC: синтаксис escape-кода Unicode
Новый метод call()
для замыканий используется как сокращенный способ вызова замыкания при привязке к нему области объекта. Это создает более производительный и компактный код, устраняя необходимость создания промежуточного замыкания перед его вызовом.
class A {private $x = 1;}// Код до PHP 7 $getXCB = function() {return $this->x;};$getX = $getXCB->bindTo(new A, 'A'); // промежуточное эхо закрытия $getX(); // 1// PHP 7+ code$getX = function() {return $this->x;};echo $getX->call(new A); // 1
RFC: Закрытие::call
unserialize()
Эта функция призвана обеспечить лучшую безопасность при десериализации объектов на ненадежных данных. Это предотвращает возможные внедрения кода, позволяя разработчику включать в белый список классы, которые можно десериализовать.
// преобразует все объекты в объект __PHP_Incomplete_Class object$data = unserialize($foo, ["allowed_classes" => false]); // преобразует все объекты в объект __PHP_Incomplete_Class, кроме объектов MyClass и MyClass2$data = unserialize($foo, [" разрешенные_классы" => ["MyClass", "MyClass2"]]); // поведение по умолчанию (то же самое, что и отсутствие второго аргумента) который принимает все классы$data = unserialize($foo, ["allowed_classes" => true]);
RFC: фильтрованная unserialize()
IntlChar
Новый класс IntlChar
призван предоставить дополнительные функции ICU. Сам класс определяет ряд статических методов и констант, которые можно использовать для управления символами Юникода.
printf('%x', IntlChar::CODEPOINT_MAX); // 10ffffecho IntlChar::charName('@'); // КОММЕРЧЕСКИЙ ATvar_dump(IntlChar::ispunct('!')); // логическое значение (истина)
Чтобы использовать этот класс, необходимо установить расширение Intl
.
Британская Колумбия Брейки
Классы в глобальном пространстве имен не должны называться IntlChar
.
RFC: класс IntlChar
Ожидания — это обратно совместимое усовершенствование старой функции assert()
. Они позволяют использовать утверждения с нулевой стоимостью в рабочем коде и предоставляют возможность генерировать пользовательские исключения в случае ошибки.
Прототип функции assert()
выглядит следующим образом:
void assert (mixed $expression [, mixed $message]);
Как и в старом API, если $expression
является строкой, она будет вычислена. Если первый аргумент ложный, утверждение не выполняется. Второй аргумент может быть либо простой строкой (вызывающей срабатывание AssertionError), либо пользовательским объектом исключения, содержащим сообщение об ошибке.
ini_set('assert.Exception', 1);class CustomError расширяет AssertionError {}assert(false, new CustomError('Некоторое сообщение об ошибке'));
Эта функция включает в себя две настройки PHP.ini (вместе со значениями по умолчанию):
zend.assertions = 1
утверждение.исключение = 0
zend.assertions имеет три значения:
1 = генерировать и выполнять код (режим разработки)
0 = генерировать код и переходить к нему во время выполнения
-1 = не генерировать код (нулевая стоимость, производственный режим)
Assert.Exception означает, что исключение генерируется в случае сбоя утверждения. По умолчанию эта функция отключена, чтобы сохранить совместимость со старой функцией assert()
.
RFC: Ожидания
use
Это дает возможность группировать несколько объявлений use
в соответствии с родительским пространством имен. Это делается для устранения многословия кода при импорте нескольких классов, функций или констант, находящихся в одном пространстве имен.
// Код PHP 7use somenamespaceClassA;use somenamespaceClassB;use somenamespaceClassC as C;use function somenamespacefn_a;use function somenamespacefn_b;use function somenamespace fn_c;use const somenamespaceConstA;use const somenamespaceConstB;use const somenamespaceConstC;// PHP 7+ использование кода somenamespace{ClassA, ClassB, ClassC as C};use function somenamespace{fn_a, fn_b, fn_c};use const somenamespace{ConstA, ConstB, ConstC};
RFC: Объявления группового использования
Эта функция основана на функциональности генератора, представленной в PHP 5.5. Он позволяет использовать оператор return
внутри генератора для возврата окончательного выражения (возврат по ссылке не допускается). Это значение можно получить с помощью нового метода Generator::getReturn()
, который можно использовать только после того, как генератор завершит выдачу значений.
// Синтаксис IIFE теперь возможен — см. подраздел «Унифицированный синтаксис переменных» в разделе «Изменения» $gen = (function() { yield 1; yield 2; return 3; })();foreach ($gen as $val) { echo $val, PHP_EOL; }echo $gen->getReturn(), PHP_EOL;// вывод:// 1// 2// 3
Возможность явным образом возвращать конечное значение из генератора — это удобная возможность. Это связано с тем, что он позволяет генератору возвращать окончательное значение (возможно, из какой-либо формы вычислений сопрограммы), которое может быть специально обработано клиентским кодом, выполняющим генератор. Это гораздо проще, чем заставлять клиентский код сначала проверять, было ли получено окончательное значение, а затем, если да, специально обрабатывать это значение.
RFC: выражения возврата генератора
Делегирование генераторов основано на возможности возвращать выражения из генераторов. Это делается с помощью нового синтаксиса yield from <expr>
, где может быть любой Traversable
объект или массив. Это будет продвигаться до тех пор, пока не перестанет быть действительным, а затем выполнение продолжится в вызывающем генераторе. Эта функция позволяет разбивать операторы yield
на более мелкие операции, тем самым обеспечивая более чистый код с большей возможностью повторного использования.
функция ген() { выход 1; выход 2; вернуть доход от gen2(); } функция gen2() {выход 3; возврат 4; }$gen = gen();foreach ($gen как $val) { эхо $val, PHP_EOL; }echo $gen->getReturn();// вывод// 1// 2// 3// 4
RFC: делегирование генератора
intdiv()
Функция intdiv()
была введена для обработки деления, когда должно быть возвращено целое число.
var_dump(intdiv(10, 3)); // целое(3)
Британская Колумбия Брейки
Функции в глобальном пространстве имен не должны называться intdiv
.
RFC: intdiv()
session_start()
Эта функция дает возможность передавать массив параметров в функцию session_start()
. Это используется для установки параметров php.ini на основе сеанса:
session_start(['cache_limiter' => 'private']); // устанавливаем для параметра session.cache_limiter значение Private
Эта функция также представляет новый параметр php.ini ( session.lazy_write
), который по умолчанию имеет значение true и означает, что данные сеанса перезаписываются только в случае их изменения.
RFC: введение параметров session_start()
preg_replace_callback_array()
Эта новая функция позволяет писать код более чисто при использовании функции preg_replace_callback()
. До PHP 7 обратные вызовы, которые необходимо было выполнить для каждого регулярного выражения, требовали, чтобы функция обратного вызова (второй параметр preg_replace_callback()
) была загрязнена большим количеством ветвей (в лучшем случае хакерский метод).
Теперь обратные вызовы можно зарегистрировать для каждого регулярного выражения с помощью ассоциативного массива, где ключом является регулярное выражение, а значением — обратный вызов.
Подпись функции:
string preg_replace_callback_array(array $regexesAndCallbacks, string $input);
$tokenStream = []; // [tokenName, лексема] пары$input = <<<'end'$a = 3; // завершение инициализации переменной;// До PHP 7 codepreg_replace_callback( [ '~$[a-z_][azd_]*~i', '~=~', '~[d]+~', '~;~', '~//.*~' ], function ($match) use (&$tokenStream) { if (strpos($match[0], '$') === 0) { $tokenStream[] = ['T_VARIABLE', $match[0]] ; } elseif (strpos($match[0], '=') === 0) { $tokenStream[] = ['T_ASSIGN', $match[0]]; } elseif (ctype_digit($match[0])) {$tokenStream[] = ['T_NUM', $match[0]]; } elseif (strpos($match[0], ';') === 0) { $tokenStream[] = ['T_TERMINATE_STMT', $match[0]]; } elseif (strpos($match[0], '//') === 0) { $tokenStream[] = ['T_COMMENT', $match[0]]; } }, $input);// PHP 7+ codepreg_replace_callback_array( [ '~$[a-z_][azd_]*~i' => function ($match) use (&$tokenStream) { $tokenStream[] = ['T_VARIABLE', $match[0]]; }, '~=~' => function ($match) use (&$tokenStream) { $tokenStream[] = ['T_ASSIGN', $match[0]]; }, '~[d]+~' => function ($match) use (&$tokenStream) { $tokenStream[] = ['T_NUM', $match[0]]; }, '~;~' => функция ($match) use (&$tokenStream) { $tokenStream[] = ['T_TERMINATE_STMT', $match[0]]; }, '~//.*~' => function ($match) use (&$tokenStream) { $tokenStream[] = ['T_COMMENT', $match[0]]; } ], $вход);
Британская Колумбия Брейки
Функции в глобальном пространстве имен не должны называться preg_replace_callback_array
.
RFC: добавить функцию preg_replace_callback_array
Эта функция представляет две новые функции для генерации криптографически безопасных целых чисел и строк. Они предоставляют простые API и не зависят от платформы.
Сигнатуры функций:
string random_bytes(int length); int random_int(int min, int max);
Обе функции выдадут исключение Error
, если не удастся найти источник достаточной случайности.
Британская Колумбия Брейки
Функции в глобальном пространстве имен не должны называться random_int
или random_bytes
.
RFC: простой CSPRNG для пользователя
define()
Возможность определять константы массива появилась в PHP 5.6 с помощью ключевого слова const
. Эта возможность теперь применена и к функции define()
:
define('ALLOWED_IMAGE_EXTENSIONS', ['jpg', 'jpeg', 'gif', 'png']);
RFC: RFC отсутствует.
В PHP 7 были представлены два новых класса отражения. Первый — ReflectionGenerator
, который используется для самоанализа генераторов:
класс ReflectionGenerator { public __construct(Generator $gen) public array getTrace($options = DEBUG_BACKTRACE_PROVIDE_OBJECT) public int getExecutingLine (void) общедоступная строка getExecutingFile (void) public ReflectionFunctionAbstract getFunction (void) общедоступный объект getThis (void) общедоступный генератор getExecutingGenerator (void) }
Второй — ReflectionType
для лучшей поддержки функций объявления скалярного и возвращаемого типа:
класс ReflectionType { public boolallowNull(void) public bool isBuiltin(void) public string __toString(void) }
Также в ReflectionParameter
добавлены два новых метода:
класс ReflectionParameter { // ... public bool hasType(void) public ReflectionType getType(void) }
А также два новых метода в ReflectionFunctionAbstract
:
класс ReflectionFunctionAbstract { // ... public bool hasReturnType(void) public ReflectionType getReturnType(void) }
Британская Колумбия Брейки
Классы в глобальном пространстве имен не должны называться ReflectionGenerator
или ReflectionType
.
RFC: RFC отсутствует.
Теперь разрешены глобально зарезервированные слова в качестве имен свойств, констант и методов внутри классов, интерфейсов и свойств. Это уменьшает вероятность разрывов BC при введении новых ключевых слов и позволяет избежать ограничений на имена API.
Это особенно полезно при создании внутренних DSL с гибкими интерфейсами:
// 'new', 'private' и 'for' ранее были непригодны для использованияProject::new('Project Name')->private()->for('цель здесь')->with('имя пользователя здесь');
Единственное ограничение заключается в том, что ключевое слово class
по-прежнему нельзя использовать в качестве имени константы, иначе оно будет конфликтовать с синтаксисом разрешения имени класса ( ClassName::class
).
RFC: контекстно-зависимый лексер
Это изменение обеспечивает гораздо большую ортогональность операторам переменных в PHP. Он позволяет использовать ряд новых комбинаций операторов, которые ранее были запрещены, и, таким образом, открывает новые способы выполнения старых операций в сокращенном коде.
// вложение ::$foo::$bar::$baz // доступ к свойству $baz свойства $foo::$bar // вложение ()foo()() // вызов возврата foo() // операторы над выражениями, заключенными в ()(function () {})() // синтаксис IIFE из JS
Возможность произвольно комбинировать операторы переменных появилась благодаря изменению семантики вычислений косвенных ссылок на переменные, свойства и методы. Новое поведение более интуитивно понятно и всегда следует порядку вычислений слева направо:
// старое значение // новое значение$$foo['bar']['baz'] ${$foo['bar']['baz']} ($$foo)['bar']['baz' ]$foo->$bar['baz'] $foo->{$bar['baz']} ($foo->$bar)['baz']$foo->$bar['baz']( ) $foo->{$bar['baz']}() ($foo->$bar)['baz']() Foo::$bar['baz']() Foo::{$bar['baz']}() (Foo::$bar)['baz']()
Британская Колумбия Брейки
Код, который полагался на старый порядок вычислений, необходимо переписать, чтобы явно использовать этот порядок вычислений с фигурными скобками (см. средний столбец выше). Это сделает код совместимым как с PHP 7.x, так и с PHP 5.x.
RFC: унифицированный синтаксис переменных
Исключения в движке преобразуют многие фатальные и исправимые фатальные ошибки в исключения. Это позволяет плавно ухудшать работу приложений с помощью пользовательских процедур обработки ошибок. Это также означает, что теперь будут выполняться функции, управляемые очисткой, такие как finally
и деструкторы объектов. Кроме того, при использовании исключений для ошибок приложения будут создаваться трассировки стека для получения дополнительной отладочной информации.
функция sum(float ...$numbers): float { return array_sum($numbers); } попробуйте {$total = sum(3, 4, null); } catch (TypeError $typeErr) { // здесь обрабатываем ошибку типа}
Новая иерархия исключений выглядит следующим образом:
interface Throwable |- Exception implements Throwable |- ... |- Error implements Throwable |- TypeError extends Error |- ParseError extends Error |- AssertionError extends Error |- ArithmeticError extends Error |- DivisionByZeroError extends ArithmeticError
Дополнительную информацию об этой новой иерархии исключений см. в подразделе Throwable Interface в разделе «Изменения».
Британская Колумбия Брейки
Пользовательские обработчики ошибок, используемые для обработки (и обычно игнорирования) восстанавливаемых фатальных ошибок, больше не будут работать, поскольку теперь будут выдаваться исключения.
Ошибки синтаксического анализа, возникающие в коде eval()
теперь станут исключениями, требующими их заключения в блок try...catch
.
RFC: исключения в движке
Это изменение влияет на иерархию исключений PHP из-за введения исключений в движок. Вместо того, чтобы помещать фатальные и исправимые фатальные ошибки в уже существующую иерархию классов Exception
, было решено реализовать новую иерархию исключений, чтобы код PHP 5.x не перехватывал эти новые исключения с помощью функции catch-all ( catch (Exception $e)
) статьи.
Новая иерархия исключений выглядит следующим образом:
interface Throwable |- Exception implements Throwable |- ... |- Error implements Throwable |- TypeError extends Error |- ParseError extends Error |- AssertionError extends Error |- ArithmeticError extends Error |- DivisionByZeroError extends ArithmeticError
Интерфейс Throwable
реализуется иерархиями базовых классов Exception
и Error
и определяет следующий контракт:
interface Throwable { final public string getMessage ( void ) final public mixed getCode ( void ) final public string getFile ( void ) final public int getLine ( void ) final public array getTrace ( void ) final public string getTraceAsString ( void ) public string __toString ( void ) }
Throwable
не может быть реализован с помощью определяемых пользователем классов — вместо этого собственный класс исключений должен расширять один из уже существующих классов исключений в PHP.
RFC: переносной интерфейс
Семантика некоторых целочисленных поведений была изменена, чтобы сделать их более интуитивно понятными и независимыми от платформы. Вот список этих изменений:
Приведение NAN
и INF
к целому числу всегда приводит к 0.
Побитовый сдвиг на отрицательное число битов теперь запрещен (вызывает возврат bool(false) и выдает E_WARNING)
Побитовый сдвиг влево на количество бит, превышающее разрядность целого числа, всегда будет приводить к 0.
Побитовый сдвиг вправо на число битов, превышающее разрядность целого числа, всегда будет приводить к 0 или -1 (зависит от знака).
Британская Колумбия Брейки
Любая опора на старую семантику вышеперечисленного больше не будет работать.
RFC: целочисленная семантика
Лицензирование старого расширения JSON считалось платным, что вызывало проблемы для многих дистрибутивов на базе Linux. С тех пор расширение было заменено на JSOND и имеет некоторый прирост производительности и недостатки обратной совместимости.
Британская Колумбия Брейки
Число не должно заканчиваться десятичной точкой (т. е. 34.
необходимо изменить на 34.0
или просто на 34
).
Показатель e
не должен следовать сразу за десятичной запятой (т. е. 3.e3
необходимо изменить либо на 3.0e3
, либо просто 3e3
).
RFC: заменить текущее расширение json на jsond
Приведение чисел с плавающей точкой к целым числам может произойти, когда число с плавающей запятой передается внутренней функции, ожидающей целое число. Если число с плавающей точкой слишком велико для представления в виде целого числа, значение будет автоматически усечено (что может привести к потере величины и знака). Это может привести к труднообнаружимым ошибкам. Таким образом, это изменение направлено на то, чтобы уведомить разработчика, когда неявное преобразование из числа с плавающей запятой в целое число произошло и завершилось неудачно, возвращая null
и выдавая E_WARNING.
Британская Колумбия Брейки
Код, который когда-то работал молча, теперь будет выдавать E_WARNING и может дать сбой, если результат вызова функции будет напрямую передан другой функции (поскольку теперь будет передано null
).
RFC: Сбой ZPP при переполнении
foreach()
В PHP-цикле foreach()
было несколько странных крайних случаев. Все они были обусловлены реализацией и вызывали множество неопределенных и непоследовательных действий при переборе между копиями и ссылками массива, при использовании манипуляторов итераторов, таких как current()
и reset()
, при изменении массива, который в данный момент итерируется, и т. д.
Это изменение устраняет неопределенное поведение этих крайних случаев и делает семантику более предсказуемой и интуитивно понятной.
foreach()
по значению в массивах
$array = [1,2,3];$array2 = &$array;foreach($array as $val) { не установлено ($ массив [1]); // модифицируем массив, который повторяется по echo "{$val} - ", current($array), PHP_EOL; }// До PHP 7 result1 - 33 -// PHP 7+ result1 - 12 - 13 - 1
При использовании семантики по значению итерируемый массив теперь не изменяется на месте. current()
также теперь имеет определенное поведение, где оно всегда начинается с начала массива.
foreach()
по ссылке на массивы и объекты и по значению на объектах
$array = [1,2,3];foreach($array as &$val) { echo "{$val} - ", current($array), PHP_EOL; }//Результат до PHP 71 - 22 - 33 -//Результат PHP 7+1 - 12 - 13 - 1
На функцию current()
больше не влияет итерация foreach()
в массиве. Кроме того, вложенные методы foreach()
, использующие семантику по ссылке, теперь работают независимо друг от друга:
$array = [1,2,3];foreach($array as &$val) { echo $val, PHP_EOL; Еогеасп ($массив как &$val2) { не установлено ($ массив [1]); эхо $val, PHP_EOL; } }// До PHP 7 result111// PHP 7+ result111333
Британская Колумбия Брейки
Любая опора на старую (причудливую и недокументированную) семантику больше не будет работать.
RFC: исправлено поведение «foreach».
list()
Функция list()
была задокументирована как не поддерживающая строки, однако в некоторых случаях строки можно было использовать:
// разыменование массива$str[0] = 'ab';list($a, $b) = $str[0];echo $a; // эхо $b; // b// разыменование объекта$obj = new StdClass();$obj->prop = 'ab';list($a, $b) = $obj->prop;echo $a; // эхо $b; // b// функция returnfunction func() { вернуть 'ab'; }list($a, $b) = func();var_dump($a, $b);echo $a; // эхо $b; // б
Теперь это было изменено: использование строк с помощью list()
запрещено во всех случаях.
Кроме того, пустые list()
теперь являются фатальной ошибкой, а порядок назначения переменных изменен на слева направо:
$a = [1, 2];list($a, $b) = $a;// СТАРЫЙ: $a = 1, $b = 2// НОВЫЙ: $a = 1, $b = null + "Не определено index 1"$b = [1, 2];list($a, $b) = $b;// СТАРЫЙ: $a = null + "Неопределенный индекс 0", $b = 2// НОВЫЙ: $a = 1, $б = 2
Британская Колумбия Брейки
Сделать list()
равным любому непрямому строковому значению больше невозможно. null
теперь будет значением переменных $a
и $b
в приведенных выше примерах.
Вызов list()
без каких-либо переменных приведет к фатальной ошибке.
Использование старого порядка назначения справа налево больше не будет работать.
RFC: исправлено несогласованность поведения list().
RFC: Абстрактное синтаксическое дерево.
До PHP 7, когда делитель был равен 0 для операторов деления (/) или модуля (%), выдавалось E_WARNING и возвращалось false
. В некоторых случаях было бессмысленно возвращать логическое значение арифметической операцией, поэтому в PHP 7 такое поведение было исправлено.
Новое поведение заставляет оператор деления возвращать число с плавающей запятой в виде +INF, -INF или NAN. Оператор модуля E_WARNING был удален и (наряду с новой функцией intdiv()
) будет вызывать исключение DivisionByZeroError
. Кроме того, функция intdiv()
также может выдать ArithmeticError
, если предоставлены допустимые целочисленные аргументы, которые приводят к неправильному результату (из-за целочисленного переполнения).
var_dump (3/0); // float(INF) + E_WARNINGvar_dump(0/0); // float(NAN) + E_WARNINGvar_dump(0%0); // DivisionByZeroErrorintdiv(PHP_INT_MIN, -1); // Арифметическая ошибка
Британская Колумбия Брейки
Оператор деления больше не будет возвращать false
(которое можно было незаметно привести к 0 в арифметической операции).
Оператор модуля теперь выдает исключение с делителем 0 вместо возврата false
RFC: RFC отсутствует.
При реализации пользовательских обработчиков сеансов функции-предикаты из SessionHandlerInterface
, которые ожидают возвращаемого значения true
или false
вели себя не так, как ожидалось. Из-за ошибки в предыдущей реализации только возвращаемое значение -1
считалось ложным — это означает, что даже если логическое значение false
использовалось для обозначения сбоя, оно считалось успехом:
<?phpclass FileSessionHandler реализует SessionHandlerInterface {частный $savePath; функция open($savePath, $sessionName) { вернуть ложь; // всегда терпит неудачу } функция close(){вернуть true;} функция read($id){} функция write($id, $data){} функция уничтожить($id){} функция gc($maxlifetime){} }session_set_save_handler (новый FileSessionHandler());session_start(); // не вызывает ошибки в коде до версии PHP 7
Теперь вышеописанное завершится с фатальной ошибкой. Возвращаемое значение -1
также будет продолжать давать сбой, тогда как 0
и true
будут по-прежнему означать успех. Любое другое возвращаемое значение теперь вызовет сбой и выдаст E_WARNING.
Британская Колумбия Брейки
Если возвращается логическое значение false
, сейчас это фактически завершится неудачно.
Если возвращается что-либо иное, чем логическое значение, 0
или -1
, произойдет сбой и будет выдано предупреждение.
RFC: исправлена обработка возвращаемых значений пользовательского обработчика сеанса.
Конструкторы PHP 4 были сохранены в PHP 5 вместе с новым __construct()
. Теперь конструкторы в стиле PHP 4 устарели в пользу использования только одного метода ( __construct()
), вызываемого при создании объекта. Это связано с тем, что условия вызова конструктора в стиле PHP 4 вызывали у разработчиков дополнительные когнитивные нагрузки, которые также могли сбить с толку неопытных пользователей.
Например, если класс определяется в пространстве имен или если существовал метод __construct()
, то конструктор PHP 4 был распознан как простой метод. Если бы он был определен выше метода __construct()
, то E_STRICT уведомление было бы издано, но все же распознано как простой метод.
Теперь в PHP 7, если класс не находится в пространстве имен, и не присутствует метод __construct()
, конструктор PHP 4 будет использоваться в качестве конструктора, но будет испускаться e_deprecated. В PHP 8 конструктор в стиле PHP всегда будет распознаваться как простой метод, а уведомление E_DEPRECTED исчезнет.
BC Breaks
Пользовательские обработчики ошибок могут повлиять на повышение предупреждений e_deprecated. Чтобы исправить это, просто обновите имя конструктора класса до __construct
.
RFC: удалить конструкторы PHP 4
Когда были вызваны любые функции, основанные на дате или времени, и время по умолчанию не было установлено, было издано предупреждение. Исправлено было просто установить настройку date.timezone
INI на действительный часовой кухню, но это заставило пользователи иметь файл php.ini и настраивать его заранее. Поскольку это была единственная настройка, в которой к нему было приложено предупреждение, и в любом случае оно не выполнило дефолт на UTC, предупреждение теперь удалено.
RFC: Удалите дату. ПРЕДУПРЕЖДЕНИЕ
Альтернативные теги PHP <%
(и <%=
), %>
, <script language="php">
и </script>
теперь были удалены.
BC Breaks
Код, который полагался на эти альтернативные теги, должен быть обновлен как на обычное, так и короткое открытие и закрытие тегов. Это может быть сделано вручную или автоматизировано с помощью этого сценария порта.
RFC: удалить альтернативные теги PHP
Ранее можно было указать несколько операторов блока default
в операторе коммутатора (где был выполнен последний блок default
). Эта (бесполезная) способность теперь удалена и вызывает фатальную ошибку.
BC Breaks
Любой написанный код (или более вероятный), который создал операторы коммутатора с несколькими блоками default
теперь станет фатальной ошибкой.
RFC: Определение нескольких случаев по умолчанию в переключате
Ранее можно было указать параметры с дублирующими именами в определении функции. Эта способность теперь была удалена и вызывает фатальную ошибку.
Функция Foo ($ версия, $ версия) {return $ версия; } echo foo (5, 7); // pre php 7 result7 // php 7+ Результат.
BC Breaks
Параметры функции с дубликатом имени теперь станут фатальной ошибкой.
Следующие SAPI были удалены из ядра (большинство из которых были перемещены в PECL):
SAPI/AOLSERVER
SAPI/APACHE
sapi/apache_hooks
SAPI/APACHE2FILTER
Sapi/Caudium
SAPI/непрерывность
SAPI/ISAPI
SAPI/MILTER
SAPI/NSAPI
SAPI/PHTTPD
SAPI/PI3WEB
SAPI/ROXEN
SAPI/THTTPD
SAPI/смокинг
SAPI/WEBJAMES
ext/mssql
ext/mysql
ext/sybase_ct
ext/ereg
RFC: Удаление мертвых или еще нет PHP7 PHP7 PROMED SAPI и расширения
Строслое шестнадцатеричное число больше не признается численным.
var_dump (is_numeric ('0x123')); var_dump ('0x123' == '291'); echo '0x123' + '0x123'; // pre php 7 resultbool (true) bool (true) 582 // php 7+ РЕЗУЛЬТАЦИЯ РЕЗУЛЬТАЦИИ (false) bool (false) 0
Причина этого изменения состоит в том, чтобы способствовать лучшей последовательности между обработкой струнных шестигранных чисел по всему языку. Например, явные кастрюли не распознают струнные шестигранные номера:
var_dump ((int) '0x123'); // int (0)
Вместо этого строгие шестигранные номера должны быть проверены и преобразованы с использованием функции filter_var()
:
var_dump (filter_var ('0x123', filter_validate_int, filter_flag_ally_hex)); // int (291)
BC Breaks
Это изменение влияет на функцию is_numeric()
и различные операторы, включая ==
, +
, -
, *
, /
, %
, **
, ++
и --
RFC: Удалить поддержку шестнадцатеричной поддержки в числовых струнах
Вся устаревшая функциональность была удалена, особенно:
Оригинальное расширение MySQL (ext/mysql)
Расширение EREG (EXT/EREG)
Назначение new
по ссылке
Объемные звонки нестатических методов из несовместимых $this
контекст (например, Foo::bar()
извне класса, где bar()
не является статическим методом)
BC Breaks
Любой код, который работал с предупреждениями об ископке в PHP 5, больше не будет работать (вас предупредили!)
RFC: Удалить устаревшую функциональность в PHP 7
E_STRICT Уведомления всегда были чем -то вроде серой области по их значению. Это изменяет устранение этой категории ошибок и либо: удаляет уведомление E_STRICT, изменяет ее на e_deprected, если функциональность будет удалена в будущем, изменяет его на e_notice или продвигает его на e_warning.
BC Breaks
Поскольку E_STRICT находится в категории с самой низкой степенью серьезности, любые рекламные акции E_WARNING могут нарушить пользовательские обработчики ошибок
RFC: переклассифицировать уведомления E_STRICT
password_hash()
С введением нового API Hashing API пароля в PHP 5.5, многие начали его реализовать и генерировать свои собственные соли. К сожалению, многие из этих солей были получены из криптографически небезопасных функций, таких как mt_rand (), что делает соль намного слабее, чем то, что было бы сгенерировано по умолчанию. (Да, соль всегда используется, когда хэшируют пароли с этим новым API!) Таким образом, опция создания солей была устарела для предотвращения создания небезопасных солей.
RFC: нет RFC
Неверные восьмиугольные литералы теперь вызовут ошибку разбора, а не усекнуты и молча игнорируются.
Эхо 0678; // Ошибка разбора: неверная цифровая буквальная литература в ...
BC Breaks
Любые неверные восьмиугольные литералы в коде теперь вызовут ошибки анализа
RFC: нет RFC
substr()
изменение возврата значения substr()
теперь вернет пустую строку вместо false
, когда начальное положение усечения равна длине строки:
var_dump (substr ('a', 1)); // pre php 7 resultbool (false) // php 7+ resultString (0) "" "
substr()
может все еще возвращать false
в других случаях, однако.
BC Breaks
Код, который строго проверяется на возвратное значение bool(false)
теперь может быть семантически недействительным
RFC: нет RFC
PHP 6 была основной версией PHP, которая никогда не выявлялась. Предполагалось, что он будет иметь полную поддержку Unicode в ядре, но эти усилия были слишком амбициозными при возникновении слишком большого количества осложнений. Преобладающие причины, по которым версия 6 была пропущена для этой новой крупной версии, заключаются в следующем:
Чтобы предотвратить путаницу . Многие ресурсы были написаны о PHP 6, и большая часть сообщества знала, что было в нем. PHP 7 - это совершенно другой зверь с совершенно разными фокусами (особенно на производительности) и совершенно разными наборами функций. Таким образом, была пропущена версия, чтобы предотвратить путаницу или заблуждения, связанные с тем, что такое PHP 7.
Чтобы спящие собаки лгать . PHP 6 рассматривался как сбой, и большое количество кода PHP 6 все еще остается в репозитории PHP. Поэтому было воспринято как лучше всего перейти к версии 6 и заново заново на следующей крупной версии, версии
RFC: имя следующего выпуска PHP