PHP 5.6.x#
1. 新特性#
1.1. 使用表达式定义常量#
在之前的 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
1.2. 使用 ...
运算符定义变长参数函数#
现在可以不依赖 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
1.3. 使用 ...
运算符进行参数展开#
在调用函数的时候,使用 ...
运算符, 将 数组 和 可遍历 对象展开为函数参数。 在其他编程语言,比如 Ruby 中,这被称为连接运算符。
<?php
function add($a, $b, $c) {
return $a + $b + $c;
}
$operators = [2, 3];
echo add(1, ...$operators);
?>
以上例程会输出:
6
1.4. 使用 **
进行幂运算#
加入右连接运算符 **
来进行幂运算。 同时还支持简写的 **=
运算符,表示进行幂运算并赋值。
<?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
1.5. use function
以及 use const
#
use
运算符 被进行了扩展以支持在类中导入外部的函数和常量。 对应的结构为 use function
和 use 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
1.6. php://input 是可重用的了#
只要你需要,你可以多次打开并读取 php://input。 同时,这个特性使得在处理 POST 的数据的时候, 可以明显降低对于内存的需求量。
1.7. 大文件上传#
现在可以支持大于 2GB 的文件上传。
1.8. 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
1.9. 使用 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)
1.10. __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)
}
原文