PHP7新特性
标量类型声明
PHP的标量类型:
bool
int
float
string
function addOne(int a) { return a + 1; } function addA(string a) { return a . "A"; }
严格类型声明
<?php declare(strict_types=1);
返回类型声明
<?php class A { private $name; function __construct(string $name) { $this->name = $name; } /** * @return mixed */ public function getName() { return $this->name; } } function getString(): string { return ""; } function getArray(): array { return []; } function getInt(): int { return 1.2; } function getInt2(): int { return '123'; } function getInt3(): int { return '123a'; } function createA(string $name): A { return new A($nam
空合并运算符
空合并运算符用两个问号表示: ??
,用来检查值是否存在并且不为空,然后返回第一个操作数,否则返回第二个操作数。
$username = $_SERVER['username'] ?? 'not define'; echo $username . PHP_EOL; $username = isset($_SERVER['username']) ? $_SERVER['username'] : 'not define'; echo $username . PHP_EOL; $username = $_SERVER['username'] ?? getenv('USER') ?? 'not define'; echo $username . PHP_EOL;
飞船运算符
飞船运算符用<=>
表示,用来比较两个表达式,小于时返回-1
,等于时返回0
,大于时返回1
echo 1 <=> 2 . PHP_EOL; // 1 echo 1 <=> 1 . PHP_EOL; // 0 echo 5 <=> 3 . PHP_EOL; // -1
使用define
定义常量数组
<?php define('NAME', ['A', 'B', 'C', 'D']); // NAME[] = 'E'; print_r(NAME
解构赋值
可以在list
函数中指定key
。
<?php $data = [ ["id" => 1, "name" => 'Tom'], ["id" => 2, "name" => 'Fred'], ]; // list() style list("id" => $id1, "name" => $name1) = $data[0]; // [] style ["id" => $id1, "name" => $name1] = $data[0]; // list() style foreach ($data as list("id" => $id, "name" => $name)) { // logic here with $id and $name echo "$name"; } // [] style foreach ($data as ["id" => $id, "name" => $name]) { echo "$name"; // logic here with $id and $nam
匿名类
当一个类不需要被记录,或者一个在执行中只会使用一次时可以考虑使用匿名类。
interface Writer { public function write(string $message); } function http_response(Writer $writer, $body, $headers=[], $version='HTTP/1.1') { $writer->write("$version 200 OK\r\n"); $writer->write("Content-Type: text/html\r\n"); $writer->write("Content-Length: " . strlen($body) . "\r\n"); foreach ($headers as $header => $val) { $writer->write("$header: $val\r\n"); } $writer->write("\r\n"); $writer->write($body); } http_response(new class implements Writer { public function write(string $message) { echo $message; } }, "something", array( 'Location' => '/' ));
命名空间分组导入
- 导入命名空间内的多个类:
use App\Module\{Foo, Bar, Baz}
- 导入命名空间内的多个函数:
use function App\Tool\{some_function}
- 堕入命名空间内的多个常量:
use const App\Tool\{A};
Heredoc
PHP7Heredoc有了更灵活的语法,提高了可读性。
- 允许结束标记缩近
- 删除结束标记后的新行要求
$templates = array( <<<EOF sdkf skldjfls sdfljkl sdf ksdjfl sdfl sdfjl EOF, <<<EOF xxxx yyyy zzzz EOF );
类常量可见性
class Bar { public const A = 1; protected const B = 2; private const C = 3; }
支持负字符串偏移量
$name = 'name'; echo $name[-1]; // output e
PHP5迁移到PHP7编写代码需要注意的地方
保持接口兼容:子类重写父类/实现接口的方法要注意参数兼容
<?php class P { public function printMessage($msg, $newline=false) { echo $newline ? $msg.PHP_EOL : $msg; } } class S extends P { # 错误的 public function printMessage($msg, $newline) { } } class S extends P { # 正确的 public function printMessage($msg, $newline=false) { } } # output Warning: Declaration of S::printMessage($msg, $newline) should be compatible with P::printMessage($msg, $newline = false) in /root/phpnewfeatures/parent_sub_class_method.php on l
引用传递参数要是一个变量。
<?php function group_by_key(&$arr, $key) {} function new_array() { return []; } $arr = []; group_by_key($arr, 'key'); # 正确的 group_by_key([], 'key'); # 错误的 group_by_key(new_array(), 'key'); # 错误的 # output PHP Fatal error: Only variables can be passed by reference in /root/phpnewfeatures/array_parameter_ref.php on li
switch
结构中的continue
语句会产生一个警告,应该用break
。
<?php for ($i = 0; $i < 3; $i++) { switch ($i) { case 1: continue; case 2: echo 'yes'; break; default: break; } } # output PHP Warning: "continue" targeting switch is equivalent to "break". Did you mean to use "continue 2"? in /root/phpnewfeatures/switch_case_no_continue.php on line
当传递参数过少是将抛出异常,在调用用户定义函数时,如果参数过少,在PHP7之前会产生一个警告,在PHP7会抛出异常。
<?php function addInts($a, $b, $c) { return $a + $b + $c; } addInts(1,2, 3); addInts(1,2); # output php5 PHP Warning: Missing argument 3 for addInts(), called in /root/phpnewfeatures/too_few_args.php on line 9 and defined in /root/phpnewfeatures/too_few_args.php on line 3 # output php7 PHP Fatal error: Uncaught ArgumentCountError: Too few arguments to function addInts(), 2 passed in /root/phpnewfeatures/too_few_args.php on line 9 and exactly 3 expected in /root/phpnewfeatures/too_few_args.p
下面的名称不能作为类、接口和trait的名称
- void
- iterable
- bool
- int
- string
- NULL
- TRUE
- FALSE
- FLOAT
无效字符串数学运算
<?php '1b' + 2; PHP Notice: A non well formed numeric value encountered in /root/phpnewfeatures/non_well_formed_numeric_encountered.php on line
计算非可数类型(non-countable)时会发出警告。对非可数类型调用 count()(或 sizeof())函数,会抛出一个 E_WARNING 错误。
<?php count(''); count(null); count(false); count('hello'); count(1); count(new StdClass); # output Warning: count(): Parameter must be an array or an object that implements Counta
object在之前的版本中被声明为软保留字,现在变为了强制保留字,禁止在任何类和接口中使用该名称。
PHP Fatal error: Cannot use 'object' as class name as it is reserved
不带引号的字符串
- 不带引号的字符串是不存在的全局常量,转化成他们自身的字符串。 在PHP7以前,该行为会产生 E_NOTICE,但现在会产生 E_WARNING。在下一个 PHP 主版本中,将抛出 Error 异常。
<?php $b = hello; echo $b; #output PHP Warning: Use of undefined constant hello - assumed 'hello' (this will throw an Error in a future version of PHP) hello array( a =>
引用返回,一个返回引用的函数,不要返回一个表达式,要返回一个变量。
<?php $config = []; function &getConfig() { $item = 1; return $config[0] =& $item; # line 7 } function &getConfig2() { $item = 1; $config[0] = $item; return $item; } $c1 =& getConfig(); $c2 =& getConfig2(); ?> PHP Notice: Only variable references should be returned by reference in /root/phpnewfeatures/ref_return_value.php on line 7 PHP Stack trace: PHP 1. {main}() /root/phpnewfeatures/ref_return_value.php:0 PHP 2. getConfig() /root/phpnewfeatures/ref_return_value.php:17 Notice: Only variable references should be returned by reference in /root/phpnewfeatures/ref_return_value.php on line 7 Call Stack: 0.0011 391504 1. {main}() /root/phpnewfeatures/ref_return_value.php:0 0.0011 391504 2. getConfig() /root/phpnewfeatures/ref_return_valu
json_decode
解码为对象时,如果json的键是空会创建一个空的属性名称,而不是_empty__
作为属性名称。
<?php var_dump(json_decode('{"": 1}')); #php7 class stdClass#1 (1) { public $ => int(1) } #php5 class stdClass#1 (1) { public $_empty_ => int(1)
json_decode
,如果JSON的字面量true
,false
,null
不是小写格式,会返回null
,并且设置json_last_error
。
<?php var_dump(json_decode('{"checked": False}', true)); var_dump(json_last_error()); # php 7 /root/phpnewfeatures/json_decode_uppercase_true.php:3: NULL /root/phpnewfeatures/json_decode_uppercase_true.php:4: int(4) # php 5 array(1) { 'checked' => bool(false) } int
数字字符串转换遵循科学计数法
- 包括
(int)
强制转换操作和一下函数- intval
- settype
- decbin
- decoct
- dechex
<?php echo (int) '123e3'; # php7 123000 # php5 1
字符串不再支持空索引操作符,在PHP7之前会静默的转换为一个数组。
<?php $str = ''; $str[] = 'x'; # php5 array(1) { [0] => string(1) "x" } # php7 PHP Fatal error: Uncaught Error: [] operator not supported for strings in /root/phpnewfeatures/string_empty_index.php:5 Stack trace: #0 {main} thrown in /root/phpnewfeatures/string_empty_index.php on line 5 Fatal error: Uncaught Error: [] operator not supported for strings in /root/phpnewfeatures/string_empty_index.php on line 5 Error: [] operator not supported for strings in /root/phpnewfeatures/string_empty_index.php on line 5 Call Stack: 0.0007 391296 1. {main}() /root/phpnewfeatures/string_empty_index.ph
MCrypt已过期,mcrypt库在2007年以来未见任何更新,不再建议使用。可以使用OpenSSL或Sodium替代。
list不再能解开string
<?php $str = 'abcdfg'; list($a, $b, $c) = $str; var_dump($a, $b, $c); # php5 string(1) "a" string(1) "b" string(1) "c" # php7 /root/phpnewfeatures/list_string.php:7: NULL /root/phpnewfeatures/list_string.php:7: NULL /root/phpnewfeatures/list_string.php:7:
十六进制字符串不再被认为是数字
<?php var_dump("0x123" == "291"); var_dump(is_numeric("0x123")); var_dump("0xe" + "0x1"); var_dump(substr("foo", "0x1")); ?> #php5 bool(true) bool(true) int(15) string(2) "oo" #php7 /root/phpnewfeatures/hexstring.php:3: bool(false) /root/phpnewfeatures/hexstring.php:4: bool(false) PHP Notice: A non well formed numeric value encountered in /root/phpnewfeatures/hexstring.php on line 5 PHP Stack trace: PHP 1. {main}() /root/phpnewfeatures/hexstring.php:0 Notice: A non well formed numeric value encountered in /root/phpnewfeatures/hexstring.php on line 5 Call Stack: 0.0008 390712 1. {main}() /root/phpnewfeatures/hexstring.php:0 PHP Notice: A non well formed numeric value encountered in /root/phpnewfeatures/hexstring.php on line 5 PHP Stack trace: PHP 1. {main}() /root/phpnewfeatures/hexstring.php:0 Notice: A non well formed numeric value encountered in /root/phpnewfeatures/hexstring.php on line 5 Call Stack: 0.0008 390712 1. {main}() /root/phpnewfeatures/hexstring.php:0 /root/phpnewfeatures/hexstring.php:5: int(0) PHP Notice: A non well formed numeric value encountered in /root/phpnewfeatures/hexstring.php on line 6 PHP Stack trace: PHP 1. {main}() /root/phpnewfeatures/hexstring.php:0 PHP 2. substr() /root/phpnewfeatures/hexstring.php:6 Notice: A non well formed numeric value encountered in /root/phpnewfeatures/hexstring.php on line 6 Call Stack: 0.0008 390712 1. {main}() /root/phpnewfeatures/hexstring.php:0 0.0049 390744 2. substr() /root/phpnewfeatures/hexstring.php:6 /root/phpnewfeatures/hexstring.php:6: stri