Некомпатибилни промени
Почист и полокален преглед на PHP референцата, со задржана структура од PHP.net и подобра читливост за примери, секции и белешки.
Некомпатибилни промени
Референца за `migration70.incompatible.php` со подобрена типографија и навигација.
Некомпатибилни промени
Промени во ракувањето со грешки и исклучоци
Многу фатални и отстранливи фатални грешки беа претворени во исклучоци во PHP 7. Овие исклучоци од грешки наследуваат од Грешка класа, која сама по себе го имплементира Проверува тврдење интерфејс (новиот основен интерфејс од кој наследуваат сите исклучоци).
Ова значи дека прилагодените ракувачи на грешки можеби повеќе нема да бидат активирани бидејќи наместо тоа може да се фрлаат исклучоци (предизвикувајќи нови фатални грешки за нефатени Грешка исклучоци).
Поцелосен опис за тоа како функционираат грешките во PHP 7 може да се најде на страницата за грешки на PHP 7. Овој водич за миграција само ќе ги наброи промените што влијаат на компатибилноста наназад.
set_exception_handler() веќе не е загарантирано да прими Исклучок objects
Кодот што имплементира ракувач со исклучоци регистриран со set_exception_handler() користејќи декларација за тип на Исклучок ќе предизвика фатална грешка кога Грешка објект ќе биде фрлен.
Ако ракувачот треба да работи и на PHP 5 и на PHP 7, треба да ја отстраните декларацијата за тип од ракувачот, додека кодот што се мигрира за работа исклучиво на PHP 7 може едноставно да ја замени Исклучок декларацијата за тип со Проверува тврдење instead.
<?php
// PHP 5 era code that will break.
function handler(Exception $e) { /* ... */ }
set_exception_handler('handler');
// PHP 5 and 7 compatible.
function handler($e) { /* ... */ }
// PHP 7 only.
function handler(Throwable $e) { /* ... */ }
?>Внатрешните конструктори секогаш фрлаат исклучоци при неуспех
Претходно, некои внатрешни класи би враќале null или неупотреблив објект кога конструкторот не успеал. Сите внатрешни класи сега ќе фрлаат
Исклучок во овој случај на ист начин како што веќе мораа да прават корисничките класи.
Грешките при парсирање фрлаат ParseError
Грешките при парсирање сега фрлаат ParseError објект. Ракувањето со грешки за eval() сега треба да вклучува catch блок што може да ја обработи оваа грешка.
Промени во сериозноста на известувањата E_STRICT
Сите E_STRICT известувања се прекласифицирани на други нивоа. E_STRICT константата е задржана, така што повиците како
error_reporting(E_ALL|E_STRICT) нема да предизвикаат грешка.
| Ситуација | Ново ниво/однесување |
|---|---|
| Индексирање по ресурс | E_NOTICE |
| Апстрактни статични методи | Известувањето е отстрането, не предизвикува грешка |
| "Предефинирање" на конструктор | Известувањето е отстрането, не предизвикува грешка |
| Несоодветност на потпис при наследување | E_WARNING |
| Иста (компатибилна) својство во два користени трејта | Известувањето е отстрането, не предизвикува грешка |
| Пристап до статично својство нестативно | E_NOTICE |
| Само променливите треба да се доделуваат по референца | E_NOTICE |
| Само променливите треба да се проследуваат по референца | E_NOTICE |
| Повикување на нестатични методи статички | E_DEPRECATED |
Промени во ракувањето со променливи
PHP 7 сега користи апстрактно дрво на синтакса при парсирање на изворни датотеки. Ова овозможи многу подобрувања на јазикот кои претходно беа невозможни поради ограничувањата во парсерот што се користеше во претходните верзии на PHP, но резултираше со отстранување на неколку посебни случаи од причини за конзистентност, што доведе до прекини во компатибилноста наназад. Овие случаи се детално опишани во овој дел.
Промени во ракувањето со индиректни променливи, својства и методи
Индиректниот пристап до променливи, својства и методи сега ќе се оценува строго по редослед од лево кон десно, за разлика од претходната мешавина од посебни случаи. Табелата подолу покажува како се променил редоследот на оценување.
| Израз | Интерпретација на PHP 5 | Интерпретација на PHP 7 |
|---|---|---|
$$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.
Ова исто така влијае на global клучниот збор. Синтаксата со кадрави загради може да се користи за емулирање на претходното однесување ако е потребно:
<?php
function f() {
// Valid in PHP 5 only.
global $$foo->bar;
// Valid in PHP 5 and 7.
global ${$foo->bar};
}
?>, секвенците U+2028 и U+2029 сега се избегнуваат. list() handling
list() повеќе не доделува променливи по обратен редослед
list() сега ќе доделува вредности на променливите по редоследот по кој се дефинирани, наместо по обратен редослед. Генерално, ова влијае само на случајот кога list() се користи во комбинација со низата [] оператор, како што е прикажано подолу:
<?php
list($a[], $a[], $a[]) = [1, 2, 3];
var_dump($a);
?>Излез од горниот пример во PHP 5:
array(3) {
[0]=>
int(3)
[1]=>
int(2)
[2]=>
int(1)
}
Излез од горниот пример во PHP 7:
array(3) {
[0]=>
int(1)
[1]=>
int(2)
[2]=>
int(3)
}
Генерално, се препорачува да не се потпирате на редоследот по кој list() се случуваат доделувањата, бидејќи ова е детали за имплементација што може повторно да се промени во иднина.
Празно list() се отстранети задачите
list() конструкциите повеќе не можат да бидат празни. Следново веќе не е дозволено:
<?php
list() = $a;
list(,,) = $a;
list($x, list(), $y) = $a;
?>list() не може да се распакува strings
list() повеќе не може да се распакува string variables. str_split() треба да се користи наместо тоа.
Редоследот на елементите во низата се промени кога тие елементи биле автоматски креирани со реферирање во доделување по референца. На пример:
Редоследот на елементите во низата се промени кога тие елементи биле автоматски креирани со реферирање во доделување по референца. На пример:
<?php
$array = [];
$array["a"] =& $array["b"];
$array["b"] = 1;
var_dump($array);
?>Излез од горниот пример во PHP 5:
array(2) {
["b"]=>
&int(1)
["a"]=>
&int(1)
}
Излез од горниот пример во PHP 7:
array(2) {
["a"]=>
&int(1)
["b"]=>
&int(1)
}
Заградите околу аргументите на функциите повеќе не влијаат на однесувањето
Во PHP 5, користењето на излишни загради околу аргумент на функција можеше да ги пригуши предупредувањата за строги стандарди кога аргументот на функцијата се проследуваше со референца. Предупредувањето сега секогаш ќе биде издадено.
<?php
function getArray() {
return [1, 2, 3];
}
function squareArray(array &$a) {
foreach ($a as &$v) {
$v **= 2;
}
}
// Generates a warning in PHP 7.
squareArray((getArray()));
?>Пример #1 Пример што покажува затворачка ознака што го опфаќа последниот нов ред
Notice: Only variables should be passed by reference in /tmp/test.php on line 13
, секвенците U+2028 и U+2029 сега се избегнуваат. foreach
Направени се мали промени во однесувањето на foreach контролната структура, главно околу ракувањето со внатрешниот покажувач на низата и модификацијата на низата што се итерира.
foreach повеќе не го менува внатрешниот покажувач на низата
Пред PHP 7, внатрешниот покажувач на низата се менуваше додека низата се итерираше со користење на foreach. Ова веќе не е случај, како што е прикажано во следниот пример:
<?php
$array = [0, 1, 2];
foreach ($array as &$val) {
var_dump(current($array));
}
?>Излез од горниот пример во PHP 5:
int(1) int(2) bool(false)
Излез од горниот пример во PHP 7:
int(0) int(0) int(0)
foreach со вредност работи на копија од низата
Кога се користи во стандардниот режим со вредност, foreach сега ќе работи на копија од низата што се итерира наместо на самата низа. Ова значи дека промените во низата направени за време на итерацијата нема да влијаат на вредностите што се итерираат.
foreach со референца има подобрено однесување при итерација
Кога се итерира со референца, foreach сега ќе прави подобра работа при следење на промените во низата направени за време на итерацијата. На пример, додавањето на низа додека се итерира сега ќе резултира со тоа што додадените вредности ќе се итерираат исто така:
<?php
$array = [0];
foreach ($array as &$val) {
var_dump($val);
$array[1] = 1;
}
?>Излез од горниот пример во PHP 5:
int(0)
Излез од горниот пример во PHP 7:
int(0) int(1)
Итерација на не-Траверзабилно objects
Итерирање преку не-Траверзабилно објектот сега ќе има исто однесување како итерирање преку низи по референца. Ова резултира со подобрено однесување при менување на низа за време на итерација исто така се применува кога својствата се додаваат или отстрануваат од објектот.
, секвенците U+2028 и U+2029 сега се избегнуваат. int handling
Невалидни октални литерали
Претходно, окталните литерали кои содржеа невалидни броеви беа тивко скратени (0128 беше земено како 012). Сега, невалиден октален литерал ќе предизвика грешка при парсирање.
Негативни битни поместувања
Битните поместувања со негативни броеви сега ќе фрлат ArithmeticError:
<?php
var_dump(1 >> -1);
?>Излез од горниот пример во PHP 5:
int(0)
Излез од горниот пример во PHP 7:
Fatal error: Uncaught ArithmeticError: Bit shift by negative number in /tmp/test.php:2
Stack trace:
#0 {main}
thrown in /tmp/test.php on line 2
Битни поместувања надвор од опсег
Битни поместувања (во која било насока) надвор од битната ширина на int секогаш ќе резултираат со 0. Претходно, однесувањето на таквите поместувања зависеше од архитектурата.
Промени во делењето со нула
Претходно, кога 0 се користеше како делител за операторите за делење (/) или модул (%), се емитуваше E_WARNING и
false ќе се вратеше. Сега, операторот за делење враќа float како +INF, -INF или NAN, како што е наведено од IEEE 754. E_WARNING за операторот за модул е отстранет и ќе фрли DivisionByZeroError
exception.
<?php
var_dump(3/0);
var_dump(0/0);
var_dump(0%0);
?>Излез од горниот пример во PHP 5:
Warning: Division by zero in %s on line %d bool(false) Warning: Division by zero in %s on line %d bool(false) Warning: Division by zero in %s on line %d bool(false)
Излез од горниот пример во PHP 7:
Warning: Division by zero in %s on line %d float(INF) Warning: Division by zero in %s on line %d float(NAN) PHP Fatal error: Uncaught DivisionByZeroError: Modulo by zero in %s line %d
, секвенците U+2028 и U+2029 сега се избегнуваат. string handling
Хексадецималните низи повеќе не се сметаат за нумерички
Низите што содржат хексадецимални броеви повеќе не се сметаат за нумерички. На пример:
<?php
var_dump("0x123" == "291");
var_dump(is_numeric("0x123"));
var_dump("0xe" + "0x1");
var_dump(substr("foo", "0x1"));
?>Излез од горниот пример во PHP 5:
bool(true) bool(true) int(15) string(2) "oo"
Излез од горниот пример во PHP 7:
bool(false) bool(false) int(0) Notice: A non well formed numeric value encountered in /tmp/test.php on line 5 string(3) "foo"
filter_var() може да се користи за да се провери дали string содржи хексадецимален број, а исто така и за да се претвори низа од тој тип во int:
<?php
$str = "0xffff";
$int = filter_var($str, FILTER_VALIDATE_INT, FILTER_FLAG_ALLOW_HEX);
if (false === $int) {
throw new Exception("Invalid integer!");
}
var_dump($int); // int(65535)
?>\u{ може да предизвика грешки
Поради додавањето на новиот
Синтакса за бегство од Unicode кодно точка, низите што содржат буквална \u{ следена од неважечка секвенца ќе предизвика фатална грешка. За да го избегнете ова, водечката коса црта треба да се избегне.
Отстранети функции
call_user_method() and call_user_method_array()
Овие функции беа застарени во PHP 4.1.0 во корист на
call_user_func() and
call_user_func_array(). Можеби ќе сакате да разгледате и користење
Бидејќи ова е конструкција на јазикот, а не функција, не може да се повика користејќи
и/или
...
operator.
Сите ereg* функции
Сите ereg беа отстранети.
PCRE е препорачана алтернатива.
mcrypt aliases
Отповиканата mcrypt_generic_end() функцијата е отстранета во корист на mcrypt_generic_deinit().
Дополнително, застарените mcrypt_ecb(),
mcrypt_cbc(), mcrypt_cfb() and
mcrypt_ofb() функции беа отстранети во корист на користење mcrypt_decrypt() со соодветниот
MCRYPT_MODE_* constant.
Сите ext/mysql функции
Сите ext/mysql беа отстранети. За детали за избор на различно MySQL API, видете Избор на MySQL API.
intl aliases
Отповиканата datefmt_set_timezone_id() and IntlDateFormatter::setTimeZoneID() новите имиња беа отстранети во корист на datefmt_set_timezone() and IntlDateFormatter::setTimeZone(), соодветно.
set_magic_quotes_runtime()
set_magic_quotes_runtime(), заедно со неговиот алијас magic_quotes_runtime(), се отстранети. Тие беа отфрлени во PHP 5.3.0, и станаа ефективно нефункционални со отстранувањето на магичните лајнчиња во PHP 5.4.0.
set_socket_blocking()
Отповиканата set_socket_blocking() алијасот е отстранет во корист на stream_set_blocking().
dl() во PHP-FPM
dl() веќе не може да се користи во PHP-FPM. Останато е функционално во CLI и вградени SAPIs.
GD Type1 функции
Поддршката за PostScript Type1 фонтови е отстранета од GD екстензијата, што резултираше со отстранување на следниве функции:
- imagepsbbox()
- imagepsencodefont()
- imagepsextendfont()
- imagepsfreefont()
- imagepsloadfont()
- imagepsslantfont()
- imagepstext()
Се препорачува наместо тоа да се користат TrueType фонтови и нивните поврзани функции.
Отстранети INI директиви
Отстранети карактеристики
Следниве INI директиви се отстранети бидејќи нивните поврзани карактеристики се исто така отстранети:
-
always_populate_raw_post_data -
asp_tags
xsl.security_prefs
На xsl.security_prefs директивата е отстранета. Наместо тоа, XsltProcessor::setSecurityPrefs()
метод треба да се повика за да се контролираат безбедносните преференции на база на процесор.
Други промени некомпатибилни со претходните верзии
Нови објекти не може да се доделат по референца
Резултатот од new изјавата веќе не може да се додели на променлива по референца:
<?php
class C {}
$c =& new C;
?>Излез од горниот пример во PHP 5:
Deprecated: Assigning the return value of new by reference is deprecated in /tmp/test.php on line 3
Излез од горниот пример во PHP 7:
Parse error: syntax error, unexpected 'new' (T_NEW) in /tmp/test.php on line 3
Невалидни имиња на класи, интерфејси и трајти
Следниве имиња не можат да се користат за именување класи, интерфејси или трајти:
Следниве имиња не можат да се користат за именување класи, интерфејси или трајти:
Понатаму, следниве имиња не треба да се користат. Иако нема да генерираат грешка во PHP 7.0, тие се резервирани за идна употреба и треба да се сметаат за застарени.
Отстранети ASP и script PHP тагови
| Отстранети ASP и script тагови | Отворачки таг |
|---|---|
<% |
%> |
<%= |
%> |
<script language="php"> |
</script> |
Затворачки таг
Отстранети повици од некомпатибилен контекстПретходно застарено во PHP 5.6
$this , статички повици направени на нестатички метод со некомпатибилен контекст сега ќе резултираат со недефинирана променлива во повиканиот метод и издавање предупредување за застареност.
<?php
class A {
public function test() { var_dump($this); }
}
// Note: Does NOT extend A
class B {
public function callNonStaticMethodOfA() { A::test(); }
}
(new B)->callNonStaticMethodOfA();
?>Излез од горниот пример во PHP 5.6:
Deprecated: Non-static method A::test() should not be called statically, assuming $this from incompatible context in /tmp/test.php on line 8
object(B)#1 (0) {
}
Излез од горниот пример во PHP 7:
Deprecated: Non-static method A::test() should not be called statically in /tmp/test.php on line 8 Notice: Undefined variable: this in /tmp/test.php on line 3 NULL
yield е сега десен асоцијативен оператор
На yield конструкторот повеќе не бара загради и е променет во десен асоцијативен оператор со приоритет помеѓу
print and =>. Ова може да резултира со променето однесување:
<?php
echo yield -1;
// Was previously interpreted as
echo (yield) - 1;
// And is now interpreted as
echo yield (-1);
yield $foo or die;
// Was previously interpreted as
yield ($foo or die);
// And is now interpreted as
(yield $foo) or die;
?>Заградите можат да се користат за да се разјаснат тие случаи.
Функциите не можат да имаат повеќе параметри со исто име
Веќе не е можно да се дефинираат два или повеќе параметри на функција со исто име. На пример, следната функција ќе активира
E_COMPILE_ERROR:
<?php
function foo($a, $b, $unused, $unused) {
//
}
?>Функциите што инспектираат аргументи пријавуваат current вредност на параметарот
func_get_arg(), func_get_args(), debug_backtrace() и трагите од извршување на исклучоци повеќе нема да го пријавуваат оригиналната вредност што била предадена на параметар, туку наместо тоа ќе ја обезбедат тековната вредност (која можеби била изменета).
<?php
function foo($x) {
$x++;
var_dump(func_get_arg(0));
}
foo(1);?>Излез од горниот пример во PHP 5:
1
Излез од горниот пример во PHP 7:
2
Изјавите switch не можат да имаат повеќе блокови default
Веќе не е можно да се дефинираат два или повеќе блокови default во изјава switch. На пример, следната изјава switch ќе предизвика
E_COMPILE_ERROR:
<?php
switch (1) {
default:
break;
default:
break;
}
?>$HTTP_RAW_POST_DATA removed
$HTTP_RAW_POST_DATA веќе не е достапна. Функцијата
php://input
треба да се користи наместо тоа.
# коментари во INI датотеките отстранети
Поддршката за додавање коментари со # во INI датотеките е отстранета. ; треба да се користи наместо тоа. Оваа промена се однесува на php.ini, како и датотеките обработени од
parse_ini_file() and parse_ini_string().
JSON екстензијата заменета со JSOND
JSON екстензијата е заменета со JSOND, предизвикувајќи три мали BC прекини. Прво, бројот не смее да завршува со децимална точка (т.е.
34. мора да се промени во или 34.0 or
34). Второ, при користење на научна нотација,
e експонентот не смее веднаш да следи по децимална точка (т.е. 3.e3 мора да се промени во или
3.0e3 or 3e3). Конечно, празен стринг повеќе не се смета за валиден JSON.
Внатрешна грешка на функција при прелевање
Претходно, внатрешните функции би пресекувале броеви произведени од претворање на float во integer без известување кога float бил преголем за да се претстави како integer. Сега, ќе се емитува E_WARNING и null ќе биде вратено.
Поправки на вредностите за враќање на прилагодени ракувачи на сесии
Било кои предикатни функции имплементирани од прилагодени ракувачи на сесии кои враќаат или false or -1 ќе бидат фатални грешки. Ако било која вредност од овие функции освен boolean, -1, или
0 се враќа, тогаш ќе пропадне и ќе се емитува E_WARNING.
Редослед на сортирање на еднакви елементи
Внатрешниот алгоритам за сортирање е подобрен, што може да резултира со различен редослед на сортирање на елементи кои се споредуваат како еднакви, од претходно.
Забелешка:
Не се потпирајте на редоследот на елементи кои се споредуваат како еднакви; може да се промени во секое време.
Погрешно поставени изјави за break и continue
break and continue изјави надвор од циклус или switch контролна структура сега се откриваат во време на компилација наместо во време на извршување како порано, и предизвикуваат
E_COMPILE_ERROR.
Константата не е дозволена како аргумент за break и continue
break and continue изјавите повеќе не дозволуваат нивниот аргумент да биде константа и предизвикуваат
E_COMPILE_ERROR.
Mhash веќе не е екстензија
Mhash екстензијата е целосно интегрирана во Хеш екстензијата. Затоа, веќе не е можно да се открие поддршката за Mhash со extension_loaded(); користете function_exists() наместо тоа. Понатаму, Mhash веќе не се пријавува од get_loaded_extensions() и поврзани функции.
declare(ticks)
На declare(ticks) директивата повеќе не протекува во различни единици за компилација.