新特性

使用表达式定义常量

在之前的 PHP 版本中, 必须使用静态值来定义常量,声明属性以及指定函数参数默认值。 现在你可以使用包括数值、字符串字面量以及其他常量在内的数值表达式来 定义常量、声明属性以及设置函数参数默认值。

<?php
const ONE = 1;
const
TWO = ONE * 2;

class
C {
const
THREE = TWO + 1;
const
ONE_THIRD = ONE / self::THREE;
const
SENTENCE = 'The value of THREE is '.self::THREE;

public function
f($a = ONE + self::THREE) {
return
$a;
}
}

echo (new
C)->f()."\n";
echo
C::SENTENCE;
?>

以上示例会输出:

4
The value of THREE is 3

现在可以通过 const 关键字来定义类型为 array 的常量。

<?php
const ARR = ['a', 'b'];

echo
ARR[0];
?>

以上示例会输出:

a

使用 ... 运算符定义变长参数函数

现在可以不依赖 func_get_args(), 使用 ... 运算符 来实现 变长参数函数

<?php
function f($req, $opt = null, ...$params) {
// $params 是一个包含了剩余参数的数组
printf('$req: %d; $opt: %d; number of params: %d'."\n",
$req, $opt, count($params));
}

f(1);
f(1, 2);
f(1, 2, 3);
f(1, 2, 3, 4);
f(1, 2, 3, 4, 5);
?>

以上示例会输出:

$req: 1; $opt: 0; number of params: 0
$req: 1; $opt: 2; number of params: 0
$req: 1; $opt: 2; number of params: 1
$req: 1; $opt: 2; number of params: 2
$req: 1; $opt: 2; number of params: 3

使用 ... 运算符进行参数展开

在调用函数的时候,使用 ... 运算符, 将 数组可遍历 对象展开为函数参数。 在其他编程语言,比如 Ruby中,这被称为连接运算符,。

<?php
function add($a, $b, $c) {
return
$a + $b + $c;
}

$operators = [2, 3];
echo
add(1, ...$operators);
?>

以上示例会输出:

6

使用 ** 进行幂运算

加入右连接运算符 ** 来进行幂运算。 同时还支持简写的 **= 运算符,表示进行幂运算并赋值。

<?php
printf
("2 ** 3 == %d\n", 2 ** 3);
printf("2 ** 3 ** 2 == %d\n", 2 ** 3 ** 2);

$a = 2;
$a **= 3;
printf("a == %d\n", $a);
?>

以上示例会输出:

2 ** 3 ==      8
2 ** 3 ** 2 == 512
a ==           8

use function 以及 use const

use 运算符 被进行了扩展以支持在类中导入外部的函数和常量。 对应的结构为 use functionuse const

<?php
namespace Name\Space {
const
FOO = 42;
function
f() { echo __FUNCTION__."\n"; }
}

namespace {
use const
Name\Space\FOO;
use function
Name\Space\f;

echo
FOO."\n";
f();
}
?>

以上示例会输出:

42
Name\Space\f

phpdbg

PHP 的 SAPI 模块中实现了一个 交互式调试器,叫做 phpdbg。更多信息,请访问 phpdbg documentation

默认字符编码

对于一些字符编码相关的函数,例如 htmlentities()html_entity_decode() 以及 htmlspecialchars() 使用 default_charset 作为默认字符集。请注意,对于 iconv(现已废弃) 和 mbstring 相关的函数, 如果分别设置了他们的编码, 那么这些对应设置的优先级高于 default_charset。

default_charset 的默认值是 UTF-8

php://input 是可重用的了

只要你需要,你可以多次打开并读取 php://input。 同时,这个特性使得在处理 POST 的数据的时候, 可以明显降低对于内存的需求量。

大文件上传

现在可以支持大于 2GB 的文件上传。

GMP 支持运算符重载

GMP 支持运算符重载, 并且造型成数值类型。 这使得使用 GMP 的代码更加直观。

<?php
$a
= gmp_init(42);
$b = gmp_init(17);

if (
version_compare(PHP_VERSION, '5.6', '<')) {
echo
gmp_intval(gmp_add($a, $b)), PHP_EOL;
echo
gmp_intval(gmp_add($a, 17)), PHP_EOL;
echo
gmp_intval(gmp_add(42, $b)), PHP_EOL;
} else {
echo
$a + $b, PHP_EOL;
echo
$a + 17, PHP_EOL;
echo
42 + $b, PHP_EOL;
}
?>

以上示例会输出:

59
59
59

使用 hash_equals() 比较字符串避免时序攻击

加入 hash_equals() 函数, 以恒定的时间消耗来进行字符串比较, 以避免时序攻击。 比如当比较 crypt() 密码散列值的时候,就可以使用此函数。 (假定你不能使用 password_hash()password_verify(), 这两个函数也可以抵抗时序攻击)

<?php
$expected
= crypt('12345', '$2a$07$usesomesillystringforsalt$');
$correct = crypt('12345', '$2a$07$usesomesillystringforsalt$');
$incorrect = crypt('1234', '$2a$07$usesomesillystringforsalt$');

var_dump(hash_equals($expected, $correct));
var_dump(hash_equals($expected, $incorrect));
?>

以上示例会输出:

bool(true)
bool(false)

__debugInfo()

加入 __debugInfo(), 当使用 var_dump() 输出对象的时候, 可以用来控制要输出的属性和值。

<?php
class C {
private
$prop;

public function
__construct($val) {
$this->prop = $val;
}

public function
__debugInfo() {
return [
'propSquared' => $this->prop ** 2,
];
}
}

var_dump(new C(42));
?>

以上示例会输出:

object(C)#1 (1) {
  ["propSquared"]=>
  int(1764)
}

gost-crypto 散列算法

加入 gost-crypto 散列算法。 它使用 » RFC 4357, 11.2 小节 定义的 CryptoPro S-box 表实现了 GOST 散列函数。

SSL/TLS 提升

在 PHP 5.6 中对 SSL/TLS 的支持进行了大幅度的提升。 这其中包括 默认启用端点验证 选项来支持证书指纹比对, 以避免 TLS 重新协商攻击。 还增加了很多 SSL 上下文选项, 以便在使用加密流的时候, 能够更好的控制协议和验证的相关设置。

这些变动在 PHP 5.6.x 中的 OpenSSL 变更 中有详细描述。

pgsql 异步支持

pgsql 扩展现在支持 异步方式连接数据库及执行查询, 也即可以使用非阻塞的方式和 PostgreSQL 数据库进行交互。 使用 PGSQL_CONNECT_ASYNC 常量可以 建立异步连接,pg_connect_poll()pg_socket()pg_consume_input()pg_flush() 函数 可以用来处理异步连接和查询。

add a note add a note

User Contributed Notes 7 notes

up
164
tr0y
10 years ago
It is also possible ( in 5.6.0alpha ) to typehint the ...-operator

function foo (stdclass ... $inbound) {
   var_dump($inbound);
}

// ok:
foo( (object)['foo' => 'bar'], (object)['bar' => 'foo'] );

// fails:
foo( 1, 2, 3, 4 );
up
36
Anonymous
10 years ago
Remember, that

    ($a ** $b) ** $c === $a ** ($b * $c)

Thats why exponent operator** is RIGHT associative.
up
40
ashnazg at php dot net
10 years ago
Note the order of operations in that exponentiation operator, as it was opposite of what my first expectation was:

<?php
// what I had expected,
// evaluating left to right,
// since no parens were used to guide the order of operations
2 ** 3 ** 2 == 64; // (2 ** 3) ** 2 = 8 ** 2 = 64

// the given example,
// which appears to evaluate right to left
2 ** 3 ** 2 == 512; // 2 ** (3 ** 2) = 2 ** 9 = 512
?>
up
7
ciachn
10 years ago
Having 2 ** 3 ** 2 = 512 is actually that is the exact correct behavior for a right-associative operator just as specified in the "**" documentation.
up
12
gmblar+php at gmail dot com
10 years ago
<?php

function array_zip(...$arrays) {
    return
array_merge(...array_map(NULL, ...$arrays));
}

$a = array(1, 4, 7);
$b = array(2, 5, 8);
$c = array(3, 6, 9);

var_dump(implode(', ', array_zip($a, $b, $c)));

// Output
string(25) "1, 2, 3, 4, 5, 6, 7, 8, 9"
up
-1
stocki dot r at gmail dot com
3 years ago
You can create a self-documented, named argument workaround in PHP 5.6-7 with ... operator:

<?php
htmlspecialchars
($string, ...array_values([
   
'flags'         => ENT_COMPAT | ENT_HTML401,
   
'encoding'      => 'UTF-8',
   
'double_encode' => false,
]))
?>
up
-7
BernieV
5 years ago
The splat operator (...) is documented everywhere with no space after it.
But it seems to work just as well with whitespace between ... and what follows.
My IDE line-wrapped, introducing white-space, immediately after the ...
To Top