官方文档: 从PHP 5.6.x 移植到 PHP 7.0.x

PHP官方文档上面说到, PHP7 相对于 PHP5.6 来说,是一个大版本的改变。

现在我们整理一下可能会影响到日常开发的点(注:实际变更涉及到的点不仅限于下述几点)。

【不向后兼容变更】

异常处理和错误的更改

PHP 7中,很多致命错误以及可恢复的致命错误,都被转换为异常来处理了。 这些异常继承自Error类,此类实现了Throwable接口 (所有异常都实现了这个基础接口)。

这也意味着,当发生错误的时候,以前代码中的一些错误处理的代码将无法被触发。 因为在PHP 7版本中,已经使用抛出异常的错误处理机制了。 (如果代码中没有捕获Error异常,那么会引发致命错误)。

关于间接使用变量、属性和方法的变化

对变量、属性和方法的间接调用现在将严格遵循从左到右的顺序来解析

使用了旧的从右到左的解析顺序的代码必须被重写,明确的使用大括号来表明顺序(参见示例 PHP5 的写法)。 这样使得代码既保持了与PHP 7.x的前向兼容性,又保持了与PHP 5.x的后向兼容性。

示例:


$a = 'b';

$b = [
'a'=>[
'aa'=>'a',
],
];

echo $$b['a']['aa']; # echo b in php 5

echo $$b['a']['aa']; # php7 中则会解析成 ($$b)['a']['aa'],如果要想达到php5中的输出结果,则需要加上大括号 ${$b['a']['aa']}

list() 处理方式变动

foreach 变化

(1) foreach 不再改变内部数组指针

$array = [0, 1, 2];
foreach ($array as &$val) {
var_dump(current($array));
}

# in php 5
int(1)
int(2)
bool(false)

# in php 7
int(0)
int(0)
int(0)

(2) 通过值遍历时,操作的值为数组的副本

(3) 通过引用遍历时,有更好的迭代特性

$HTTP_RAW_POST_DATA 被移除

不再提供$HTTP_RAW_POST_DATA变量。 请使用php://input作为替代。

【新特性】

标量类型声明


function sumOfInts(int ...$ints)
{
return array_sum($ints);
}
# 输出 int(9)
var_dump(sumOfInts(2, '3', 4.1));


返回值类型声明

function arraysSum(array ...$arrays): array
{
return array_map(function(array $array): int {
return array_sum($array);
}, $arrays);
}

print_r(arraysSum([1,2,3], [4,5,6], [7,8,9]));

# 输出一个数组
Array
(
[0] => 6
[1] => 15
[2] => 24
)

null合并运算符

由于日常使用中存在大量同时使用三元表达式和 isset()的情况, 我们添加了null合并运算符 (??) 这个语法糖。

如果变量存在且值不为NULL, 它就会返回自身的值,否则返回它的第二个操作数。


$username = $_GET['user'] ?? 'nobody';

# 等同于
$username = isset($_GET['user']) ? $_GET['user'] : 'nobody';

拓展

$a = ''; // or 0 or false

$b = $a ?? 'a'; // $b is '' or 0 or false

$c = $a ?: 'a';// $c is 'a'

太空船操作符(组合比较符) <=>

太空船操作符用于比较两个表达式。当$a小于、等于或大于$b时它分别返回-1、0或1。 比较的原则是沿用 PHP 的常规比较规则进行的。

// 整数
echo 1 <=> 1; // 0
echo 1 <=> 2; // -1
echo 2 <=> 1; // 1

// 浮点数
echo 1.5 <=> 1.5; // 0
echo 1.5 <=> 2.5; // -1
echo 2.5 <=> 1.5; // 1

// 字符串
echo "a" <=> "a"; // 0
echo "a" <=> "b"; // -1
echo "b" <=> "a"; // 1

通过define()定义常量数组

define('ANIMALS', [
'dog',
'cat',
'bird'
]);

echo ANIMALS[1]; // 输出 "cat"

匿名类

现在支持通过new class 来实例化一个匿名类,这可以用来替代一些“用后即焚”的完整类定义。

interface Logger {
public function log(string $msg);
}

class Application {
private $logger;

public function getLogger(): Logger {
return $this->logger;
}

public function setLogger(Logger $logger) {
$this->logger = $logger;
}
}

$app = new Application;
$app->setLogger(new class implements Logger {
public function log(string $msg) {
echo $msg;
}
});

var_dump($app->getLogger());


整数除法函数intdiv()

新加的函数 intdiv() 用来进行 整数的除法运算。

# 输出 int(3)
var_dump(intdiv(10, 3));

【PHP 7.0.x 弃用的功能】

password_hash() 盐值选项

废弃了 password_hash() 函数中的盐值选项,阻止开发者生成自己的盐值(通常更不安全)。

开发者不传该值时,该函数自己会生成密码学安全的盐值。因此再无必要传入自己自定义的盐值。

变更的函数

debug_zval_dump() 现在打印 “int” 替代 “long”, 打印 “float” 替代 “double”

dirname() 增加了可选的第二个参数, depth, 获取当前目录向上 depth 级父目录的名称。

getrusage() 现在支持 Windows.

mktime() and gmmktime() 函数不再接受 is_dst 参数。

preg_replace() 函数不再支持 “\e” (PREG_REPLACE_EVAL). 应当使用 preg_replace_callback() 替代。

setlocale() 函数不再接受 category 传入字符串。 应当使用 LC_* 常量。

exec(), system() and passthru() 函数对 NULL 增加了保护.

shmop_open() 现在返回一个资源而非一个int, 这个资源可以传给shmop_size(), shmop_write(), shmop_read(), shmop_close()shmop_delete().

substr() 现在当 start 的值与 string 的长度相同时将返回一个空字符串。

为了避免内存泄露,xml_set_object() 现在在执行结束时需要手动清除 $parse。