PHP 7 Alpha 1已经在2015.06.11发布了,预计在2015.11.12发布正式的PHP7版本。
官方新闻稿可参见:
以下来自
7.0版本变化
========================================
1. 向后兼容性改变
========================================
语言改变
================
变量处理改变
----------------------------
* 现在按照从左到右方式来解释间接变量,属性和方法引用。下面是一些举例:
$$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']}()
* 全局关键字现在只接受单变量, 不能写作
global $$foo->bar;
现在需要写作:
global ${$foo->bar};
* Parentheses around variables or function calls no longer have any influence
on behavior. For example the following code, where the result of a function
call is passed to a by-reference function
function getArray() { return [1, 2, 3]; }
$last = array_pop(getArray());
// Strict Standards: Only variables should be passed by reference
$last = array_pop((getArray()));
// Strict Standards: Only variables should be passed by reference
will now throw a strict standards error irregardless of whether parentheses
are used. Previously no notice was generated in the second case.
* Array elements or object properties that are automatically created during
by-reference assignments will now result in a different order. For example
$array = [];
$array["a"] =& $array["b"];
$array["b"] = 1;
var_dump($array);
now results in the array ["a" => 1, "b" => 1], while previously the result
was ["b" => 1, "a" => 1];
Relevant RFCs:
* https://wiki.php.net/rfc/uniform_variable_syntax
* https://wiki.php.net/rfc/abstract_syntax_tree
list()改变
-----------------
* list()不再按照倒序来为变量赋值,例如
list($array[], $array[], $array[]) = [1, 2, 3];
var_dump($array);
结果将是$array == [1, 2, 3]而不再是[3, 2, 1]. 注意,只有变量赋值的**顺序**变化,赋值保持不变, 利用,常见的
list($a, $b, $c) = [1, 2, 3];
// $a = 1; $b = 2; $c = 3;
行为将保持不变。
* 不再允许对空list()赋值,下面这些都是非法的:
list() = $a;
list(,,) = $a;
list($x, list(), $y) = $a;
* list()不再支持unpacking strings (而以前在一些些情况下是可以支持的). 代码
$string = "xy";
list($x, $y) = $string;
现在结果将是$x == null, $y == null (without notices)而不再是$x == "x", $y == "y".
而且,list()现在总是需要与实现ArrayAccess的objects工作,例如
list($a, $b) = (object) new ArrayObject([0, 1]);
现在结果将是$a == 0, $b == 1, 而以前版本中$a和$b都是null.
Relevant RFCs:
* https://wiki.php.net/rfc/abstract_syntax_tree#changes_to_list
* https://wiki.php.net/rfc/fix_list_behavior_inconsistency
foreach改变
------------------
* 用foreach()来遍历不再影响内部数组指针, 可通过current()/next()等函数访问这些指针。 例如
$array = [0, 1, 2];
foreach ($array as &$val) {
var_dump(current($array));
}
现在将打印值int(0)三次, 而以前版本输出是int(1), int(2)与bool(false).
* 当按值来遍历数组时,foreach现在总是对数组的一份copy来操作, 因此不再影响遍历行为。例如
$array = [0, 1, 2];
$ref =& $array; // Necessary to trigger the old behavior
foreach ($array as $val) {
var_dump($val);
unset($array[1]);
}
现在将打印出所有三个元素(0 1 2), 而以前版本中第二个元素1被跳过只打印出(0 2).
* 当按引用来遍历数组时,数组修改将继续影响遍历。但PHP7现在在许多情况下会维护正确的位置. 例如在按引用遍历数组时追加元素:
$array = [0];
foreach ($array as &$val) {
var_dump($val);
$array[1] = 1;
}
现在也会遍历追加的元素。因此这个例子的数据现在将是"int(0) int(1)", 而以前版本输出只有"int(0)".
* 按值或按引用遍历plain (non-Traversable) objects的行为类似于按引用遍历数组. 主要是采用了更为准确的定位管理, 这在前面也提到了。
* 遍历Traversable objects保持不变.
Relevant RFC: https://wiki.php.net/rfc/php7_foreach
参数处理改变
-----------------------------
* 不可以再定义两个同名的函数参数了, 例如下面方法将触发一个编译时错误:
public function foo($a, $b, $unused, $unused) {
// ...
}
类似的代码可修改为不同的参数名, 例如:
public function foo($a, $b, $unused1, $unused2) {
// ...
}
* func_get_arg()与func_get_args()函数将不再返回传递给参数的原始值(original value), 相反将返回当前值(current value) (值可能在函数中被修改). 例如
function foo($x) {
$x++;
var_dump(func_get_arg(0));
}
foo(1);
现在将打印出"2"而不是"1". 代码可修改为在调用func_get_arg(s)后才做修改:
function foo($x) {
var_dump(func_get_arg(0)); // !!! 我个人建议采用这种方案
$x++;
}
或者避免修改参数:
function foo($x) {
$newX = $x + 1;
var_dump(func_get_arg(0));
}
* 类似的,exception backtraces将不再显示传递给函数参数的原始值(original value), 而是显示出修改后的值. 例如
function foo($x) {
$x = 42;
throw new Exception;
}
foo("string");
现在的跟踪栈将是:
Stack trace:
#0 file.php(4): foo(42)
#1 {main}
而之前的跟踪栈将是:
Stack trace:
#0 file.php(4): foo('string')
#1 {main}
虽然这不会影响代码运行时的行为,但调试时需要知道这个差异。
同样的限制也适用于debug_backtrace() function以及其他检查函数参数的functions.
Relevant RFC: https://wiki.php.net/phpng
整数处理改变
---------------------------
* 无效的八进制literals (包含大于7的数)现在生成编译时错误. 例如下面代码不再有效:
$i = 0781; // 8 is not a valid octal digit!
以前版本中无效的数(以及后续有效digits)都只是简单被忽略掉, 因此$i的值为7, 因为后面两个digitals被安静丢弃了。
* 按比特位移一个负值现在将抛出一个警告并返回false:
var_dump(1 >> -1); // bool(false)
// Warning: Bit shift by negative number
* 按比特位左移的数超过整数bit宽度结果总是为0:
var_dump(1 << 64); // int(0)
以前版本中该代码行为依赖于使用的CPU架构, 例如在x86 (包括x86-64)上由于位移操作回绕(shift operand was wrapped)结果是int(1).
* 类似地, 按比特位右移的数超过整数bit宽度结果总是为0或-1(依赖于是否是正整数还是负整数):
var_dump(1 >> 64); // int(0)
var_dump(-1 >> 64); // int(-1)
Relevant RFC: https://wiki.php.net/rfc/integer_semantics
串处理改变
--------------------------
* 包含十六进制数字的串不再被视为数, 不再被特殊处理. 下面是新行为的一些例子:
var_dump("0x123" == "291"); // bool(false) (以前版本结果为true)
var_dump(is_numeric("0x123")); // bool(false) (以前版本结果为true)
var_dump("0xe" + "0x1"); // int(0) (以前版本结果为16)
var_dump(substr("foo", "0x1")); // string(3) "foo" (以前版本结果为"oo")
// Notice: A non well formed numeric value encountered
可以用filter_var()检查一个串是否包含了十六进制数字或将这样一个串转为整数:
$str = "0xffff";
$int = filter_var($str, FILTER_VALIDATE_INT, FILTER_FLAG_ALLOW_HEX);
if (false === $int) {
throw new Exception("Invalid integer!");
}
var_dump($num); // int(65535)
* 由于对双引号串与heredocs添加了Unicode Codepoint Escape Syntax, "\u{"后面跟着无效的序列(sequence)将产生错误:
$str = "\u{xyz}"; // Fatal error: Invalid UTF-8 codepoint escape sequence
为了防止出现问题,应当对前面的反斜杠做转义:
$str = "\\u{xyz}"; // Works fine
但是, "\u"后面不跟{则不受影响. 下面代码不会出错, 行为同以前版本:
$str = "\u202e"; // Works fine
Relevant RFCs:
* https://wiki.php.net/rfc/remove_hex_support_in_numeric_strings
* https://wiki.php.net/rfc/unicode_escape
错误处理变化
-------------------------
* 异常的新基类是BaseException, 它从Exception类扩展而来. 异常处理代码中的Typehints可能需要做出调整。
* 一些致命错误与可恢复的致命错误现在抛出一个EngineException. 由于EngineException是扩展自BaseException而不是Exception, 因此这些异常不会被现有的try/catch代码块捕获.
对于已经被转为exception的可恢复的致命错误, error handler不再可能安静忽略该错误, 尤其是不再可能忽略typehint failures.
* 解析错误现在生成一个ParseException (扩展自BaseException). eval()s对潜在无效代码的错误处理应当修改为捕获ParseException, 而以前版本返回值是基于/ error_get_last()来处理.
* 内部类的构造函数现在总是在失败时抛出异常, 而以前版本中一些构造函数返回NULL或一个unusable object.
* 一些E_STRICT notices的错误等级发生了变化.
Relevant RFCs:
* https://wiki.php.net/rfc/engine_exceptions_for_php7
* https://wiki.php.net/rfc/internal_constructor_behaviour
* https://wiki.php.net/rfc/reclassify_e_strict
其他语言变化
----------------------
* 不再支持通过静态调用方式来调用非静态函数(这里$this上下文不一致)。如果这样调用的话,$this未被定义,但允许这种调用方式同时给出一个废弃通告(deprecation notice)。举例:
class A {
public function test() { var_dump($this); }
}
// Note: Does NOT extend A
class B {
public function callNonStaticMethodOfA() { A::test(); }
}
(new B)->callNonStaticMethodOfA();
// Deprecated: Non-static method A::test() should not be called statically
// Notice: Undefined variable $this
NULL
注意:只有当上下文不一致时这样调用才给出废弃通告。如果class B扩展自class A,那么允许这种调用方式,没有任何通告。
* 不可以使用下面类, 接口和trait名称 (case-insensitive):
bool
int
float
string
null
false
true
这适用于class/interface/trait声明, class_alias() 以及use语句.
而且,下面class, interface和trait names现在保留给未来使用, 但使用时还不会抛出错误:
resource
object
mixed
numeric
* 在表达式中yield语言结构不再需要括号. 它现在是一个右关联运算符, 优先级在"print" 和"=>"之间。注意在一些情况下会产生不同的行为, 举例:
echo yield -1;
// 以前版本被解释为echo (yield) - 1;
// 现在被解释为 echo yield (-1);
yield $foo or die;
// 以前版本被解释为 yield ($foo or die);
// 现在被解释为 (yield $foo) or die;
通过添加括号总是可以解决这些前后版本解释不一致问题。
. 删除ASP (<%) 和script (<script language=php>) tags.
(RFC: https://wiki.php.net/rfc/remove_alternative_php_tags)
. 不再支持通过引用来赋值new的结果.
. 不再支持不一致的$this上下文对非静态方法的scoped calls. 详情可参见https://wiki.php.net/rfc/incompat_ctx.
. 在ini文件中不再支持#-风格的注释。而是使用;-风格的注释。
. 不再支持$HTTP_RAW_POST_DATA. 相反请使用php://input stream.
标准库变化
========================
. call_user_method()与call_user_method_array()不再存在.
. ob_start()不再生成E_ERROR, 但在输出buffer handler中创建一个output buffer时会生成一个E_RECOVERABLE_ERROR .
. 提升了zend_qsort(使用混合排序算法)的性能, 将zend_qsort 重命名为 zend_sort.
. 增加了stable排序算法zend_insert_sort.
. 在fpm-fcgi中删除了dl()函数.
. setcookie()中使用空的cookie name将生成一个WARNING, 不再发送一个空的set-cookie header.
其他
=====
- Curl:
. 不再支持CURLOPT_SAFE_UPLOAD选项的disabling. 所有的curl文件uploads都必须使用curl_file / CURLFile APIs.
- Date:
. Removed $is_dst parameter from mktime() and gmmktime().
- DBA
. dba_delete() now returns false if the key was not found for the inifile
handler, too.
- GMP
. 现在需要libgmp版本4.2或更新版本.
. gmp_setbit()与gmp_clrbit()现在对负的indices值返回FALSE, 这样就与其他GMP函数返回值保持一致。
- Intl:
. Removed deprecated aliases datefmt_set_timezone_id() and
IntlDateFormatter::setTimeZoneID(). Use datefmt_set_timezone() and
IntlDateFormatter::setTimeZone() instead.
- libxml:
. Added LIBXML_BIGLINES parser option. It's available starting with libxml 2.9.0
and adds suppport for line numbers >16-bit in the error reporting.
- Mcrypt
. Removed deprecated mcrypt_generic_end() alias in favor of
mcrypt_generic_deinit().
. Removed deprecated mcrypt_ecb(), mcrypt_cbc(), mcrypt_cfb() and mcrypt_ofb()
functions in favor of mcrypt_encrypt() and mcrypt_decrypt() with an
MCRYPT_MODE_* flag.
- Session
. session_start() accepts all INI settings as array. e.g. ['cache_limiter'=>'private']
sets session.cache_limiter=private. It also supports 'read_and_close' which closes
session data immediately after read data.
. Save handler accepts validate_sid(), update_timestamp() which validates session
ID existence, updates timestamp of session data. Compatibility of old user defined
save handler is retained.
. SessionUpdateTimestampHandlerInterface is added. validateSid(), updateTimestamp()
is defined in the interface.
. session.lazy_write(default=On) INI setting enables only write session data when
session data is updated.
- OpenSSL:
. Removed the "rsa_key_size" SSL context option in favor of automatically
setting the appropriate size given the negotiated crypto algorithm.
. Removed "CN_match" and "SNI_server_name" SSL context options. Use automatic
detection or the "peer_name" option instead.
- PCRE:
. Removed support for /e (PREG_REPLACE_EVAL) modifier. Use
preg_reaplace_callback() instead.
- PDO_pgsql:
. Removed PGSQL_ATTR_DISABLE_NATIVE_PREPARED_STATEMENT attribute in favor of
ATTR_EMULATE_PREPARES.
- Standard:
. Removed string category support in setlocale(). Use the LC_* constants
instead.
. Removed set_magic_quotes_runtime() and its alias magic_quotes_runtime().
- JSON:
. Rejected RFC 7159 incompatible number formats in json_decode string -
top level (07, 0xff, .1, -.1) and all levels ([1.], [1.e1])
. Calling json_decode with 1st argument equal to empty PHP string or value that
after casting to string is empty string (NULL, FALSE) results in JSON syntax error.
- Stream:
. Removed set_socket_blocking() in favor of its alias stream_set_blocking().
- XSL:
. Removed xsl.security_prefs ini option. Use XsltProcessor::setSecurityPrefs()
instead.
========================================
2. New Features
========================================
- Core
. Added group use declarations.
(RFC: https://wiki.php.net/rfc/group_use_declarations)
. Added null coalesce operator (??).
(RFC: https://wiki.php.net/rfc/isset_ternary)
. Support for strings with length >= 2^31 bytes in 64 bit builds.
. Closure::call() method added (works only with userland classes).
. Added \u{xxxxxx} Unicode Codepoint Escape Syntax for double-quoted strings
and heredocs.
. define() now supports arrays as constant values, fixing an oversight where define() did not support arrays yet const syntax did.
. Added the comparison operator (<=>), aka the spaceship operator.
(RFC: https://wiki.php.net/rfc/combined-comparison-operator)
. Added the yield from operator for delegating Generators like coroutines.
(RFC: https://wiki.php.net/rfc/generator-delegation)
. Reserved keywords can now be used in various new contexts.
(RFC: https://wiki.php.net/rfc/context_sensitive_lexer)
- OpenSSL
. Added "alpn_protocols" SSL context option allowing encrypted client/server
streams to negotiate alternative protocols using the ALPN TLS extension when
built against OpenSSL 1.0.2 or newer. Negotiated protocol information is
accessible through stream_get_meta_data() output.
- Reflection
. Added a ReflectionGenerator class (yield from Traces, current file/line,
etc.)
. Added a ReflectionType class to better support the new return type and
scalar type declarations features. The new ReflectionParameter::getType()
and ReflectionFunctionAbstract::getReturnType() methods both return an
instance of ReflectionType.
========================================
3. Changes in SAPI modules
========================================
- FPM
. Fixed bug #65933 (Cannot specify config lines longer than 1024 bytes).
. Listen = port now listen on all addresses (IPv6 and IPv4-mapped).
========================================
4. Deprecated Functionality
========================================
- Core
. PHP 4 style constructors, where the constructor name is the same as the
class name, are now deprecated.
. Static calls to non-static methods are now deprecated.
- OpenSSL
. The "capture_session_meta" SSL context option is now deprecated. Meta
data concerning active crypto on a stream resource is now accessible
through the return result from stream_get_meta_data().
========================================
5. Changed Functions
========================================
- parse_ini_file():
- parse_ini_string():
. Added scanner mode INI_SCANNER_TYPED to yield typed .ini values.
- unserialize():
. Added second parameter for unserialize function
(RFC: https://wiki.php.net/rfc/secure_unserialize) allowing to specify
acceptable classes:
unserialize($foo, ["allowed_classes" => ["MyClass", "MyClass2"]);
- proc_open():
The maximum number of pipes used by proc_open() was previously limited by
hardcoded value of 16. This limit is now removed and the number of pipes is
effectively limited by the amount of memory available to PHP.
========================================
6. New Functions
========================================
- GMP
. Added gmp_random_seed().
- PCRE:
. Added preg_replace_callback_array function
(RFC: https://wiki.php.net/rfc/preg_replace_callback_array)
- Standard
. Added intdiv() function for integer division.
. Added error_clear_last() function to reset error state.
- Zlib:
. Added deflate_init(), deflate_add(), inflate_init(), inflate_add()
functions allowing incremental/streaming compression/decompression.
========================================
7. New Classes and Interfaces
========================================
========================================
8. Removed Extensions and SAPIs
========================================
- sapi/aolserver
- sapi/apache
- sapi/apache_hooks
- sapi/apache2filter
- sapi/caudium
- sapi/continuity
- sapi/isapi
- sapi/milter
- sapi/nsapi
- sapi/phttpd
- sapi/pi3web
- sapi/roxen
- sapi/thttpd
- sapi/tux
- sapi/webjames
- ext/mssql
- ext/sybase_ct
For more details see https://wiki.php.net/rfc/removal_of_dead_sapis_and_exts
NOTE NSAPI was not voted in the RFC, however it was removed afterwards. It turned
out, that the corresponding SDK isn't available anymore.
========================================
9. Other Changes to Extensions
========================================
========================================
10. New Global Constants
========================================
- Core
. PHP_INT_MIN added.
- Zlib
. These constants are added to control flush behavior with the new
incremental deflate_add() and inflate_add() functions:
. ZLIB_NO_FLUSH
. ZLIB_PARTIAL_FLUSH
. ZLIB_SYNC_FLUSH
. ZLIB_FULL_FLUSH
. ZLIB_BLOCK
. ZLIB_FINISH
- GD
. T1Lib support removed, thus lifting the optional dependency on T1Lib, the
following is therefore not available anymore:
Functions:
- imagepsbbox()
- imagepsencodefont()
- imagepsextendedfont()
- imagepsfreefont()
- imagepsloadfont()
- imagepsslantfont()
- imagepstext()
Resources:
- 'gd PS font'
- 'gd PS encoding'
========================================
11. Changes to INI File Handling
========================================
- Core
. Removed asp_tags ini directive. Trying to enable it will result in a fatal
error.
. Removed always_populate_raw_post_data ini directive.
========================================
12. Windows Support
========================================
- Core
. Support for native 64 bit integers in 64 bit builds.
. Support for large files in 64 bit builds.
. Support for getrusage()
- ftp
. The ftp extension is always shipped shared
. For SSL support, the dependency on the openssl extension was abolished. Instead
it depends alone on the openssl library. If it's present at the compile time,
ftp_ssl_connect() is enabled automatically.
- odbc
. The odbc extension is always shipped shared
========================================
13. Other Changes
========================================
- Core
. Instead of being undefined and platform-dependent, NaN and Infinity will
always be zero when casted to integer.
. Calling a method on a non-object no longer raises a fatal error; see
also: https://wiki.php.net/rfc/catchable-call-to-member-of-non-object.
. Error messages for zend_parse_parameters, type hints and conversions now
always say "integer" and "float" instead of "long" and "double".
. Output buffering now continues to work for an aborted connection if
ignore_user_abort is set to true.