企业🤖AI Agent构建引擎,智能编排和调试,一键部署,支持私有化部署方案 广告
#### php7新特性 1.运算符(NULL 合并运算符): 在第一操作数存在时可被直接返回,否则返回第二操作数 $a = $_GET['a'] ?? 1; 它相当于: <php $a = isset($_GET['a']) ? $_GET['a'] : 1; 2.函数返回值类型声明: 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 ) 这个特性可以帮助我们避免一些 PHP 的隐式类型转换带来的问题。 PHP 7 增加了一个 declare 指令: declare(strict_types=1); ,既使用严格模式 例: declare(strict_types=1); function foo($a) : int {  return $a; } 如果 foo(1.2),就会触发致命错误。 3.标量类型声明: PHP 7 中的函数的 形参类型 声明可以是标量了,现在可以使用 string、int、float和 bool 了。 实例: function sumOfInts(int $ints) { return array_sum($ints); } var_dump(sumOfInts(2,'3',4.1)); 输出:int(9) 4.use 批量声明: php7 中 use 可以在一句话中声明多个类或函数或 const 要写出每个类或函数或 const 的名称。 例: use some/namespace/{ClassA, ClassB, ClassC as C}; use function some/namespace/{fn_a, fn_b, fn_c}; use const some/namespace/{ConstA, ConstB, ConstC}; 5.<=>操作符: <=>操作符将==、<、>三个比较操作符打包在了一起,具体使用规则如下: 操作符两边相等时返回 0, 操作符左边小于右边时返回 -1, 操作符左边大于右边时返回 1, 例: echo 1 <=> 1; // 0 echo 1 <=> 2; // -1 echo 2 <=> 1; // 1 6.通过 define() 定义常量数组: define('ANIMALS', [ 'dog', 'cat', 'bird' ]); 7.session_start函数中的选项数组; 在PHP7之前,使用session的时候都必须先调用session_start()函数,且这个函数并没有参数需要传递,所有session相关的配置都在php.ini文件中,从PHP7开始,可以在调用这个函数时传递参数选项数组,这些设置信息将覆盖php.ini中的session配置。 session_start([ 'cookie_lifetime' => 3600, 'read_and_close' => true ]); 8.unserialize函数引入过滤器: unserialize()可以反序列化任何类型的对象,没有任何过滤项,不安全,PHP7在unserialize()中引入了过滤器,且默认允许反序列化所有类型的对象。 9.list: PHP5.4 之前只能通过 array() 来定义数组,5.4之后添加了 [] 的简化写法。 <?php // 5.4 之前 $array = array(1, 2, 3); $array = array("a" => 1, "b" => 2, "c" => 3); // 5.4 及之后 $array = [1, 2, 3]; $array = ["a" => 1, "b" => 2, "c" => 3]; 那么,如果要把数组的值赋值给不同的变量,可以通过 list 来实现: <?php list($a, $b, $c) = $array; 是否也可以通过 [] 的简写来实现呢? <?php [$a, $b, $c] = $array; 以及下一个特性中会提到的 list 指定 key: <?php ["a" => $a, "b" => $b, "c" => $c] = $array; PHP7.1 实现了这个特性,但:出现在左侧的 [] 并不是数组的简写,而是 list() 的简写。 现在新的 list() 的实现并不仅仅可以出现在左值中,也能在 foreach 循环中使用: <?php foreach ($points as ["x" => $x, "y" => $y]) { var_dump($x, $y); } 不过因为实现的问题,list() 和 [] 不能相互嵌套使用: <?php // 不合法 list([$a, $b], [$c, $d]) = [[1, 2], [3, 4]]; // 不合法 [list($a, $b), list($c, $d)] = [[1, 2], [3, 4]]; // 合法 [[$a, $b], [$c, $d]] = [[1, 2], [3, 4]]; 另外,在新的 list() 的实现中可以指定key: <?php $array = ["a" => 1, "b" => 2, "c" => 3]; ["a" => $a, "b" => $b, "c" => $c] = $array; 相当于: <?php $a = $array['a']; $b = $array['b']; $c = $array['c']; 和以往的区别在于以往的 list() 的实现相当于 key 只能是 0, 1, 2, 3 的数字形式并且不能调整顺序。执行语句: <?php list($a, $b) = [1 => '1', 2 => '2']; 会得到 PHP error: Undefined offset: 0... 的错误。 新的实现则可以通过以下方式来调整赋值: <?php list(1 => $a, 2 => $b) = [1 => '1', 2 => '2']; 不同于数组的是,list 并不支持混合形式的 key,以下写法会触发解析错误: <?php // Parse error: syntax error, ... list($unkeyed, "key" => $keyed) = $array; 更复杂的情况,list 也支持复合形式的解析: <?php $points = [ ["x" => 1, "y" => 2], ["x" => 2, "y" => 1] ]; list(list("x" => $x1, "y" => $y1), list("x" => $x2, "y" => $y2)) = $points; $points = [ "first" => [1, 2], "second" => [2, 1] ]; list("first" => list($x1, $y1), "second" => list($x2, $y2)) = $points; 以及循环中使用: <?php $points = [ ["x" => 1, "y" => 2], ["x" => 2, "y" => 1] ]; foreach ($points as list("x" => $x, "y" => $y)) { echo "Point at ($x, $y)", PHP_EOL; } 10.匿名类 有时我们不想为一个参数专门去声明一个类来适配它,而使用内部类可以直接想使用匿名函数一样方便,直接使用,如果参数类型是接口类型,我们只需要让匿名类实现指定的接口即可 interface IFoo { function doSomething(); } class Bar { public function execute(IFoo $foo) { $foo->doSomething(); } } $bar = new Bar(); $bar->execute(new class () implements IFoo { function doSomething() { echo 'execute!'; } }); //输出execute! 11.生成器返回表达式 生成器是一个偏的内容,不太被使用的特性,不过这在PHP5.5版本就已经开始有了。以下是官方对生成器的解释: 生成器提供了一种更容易的方法来实现简单的对象迭代,相比较定义类实现 Iterator 接口的方式,性能开销和复杂性大大降低。 生成器允许你在 foreach 代码块中写代码来迭代一组数据而不需要在内存中创建一个数组, 那会使你的内存达到上限,或者会占据可观的处理时间。相反,你可以写一个生成器函数,就像一个普通的自定义函数一样, 和普通函数只返回一次不同的是, 生成器可以根据需要 yield 多次,以便生成需要迭代的值。 其实平时我们在遍历内容比较大的数据时,很消耗内存,但是使用生成器就不一样,它只有在迭代的时候才会取值,不会把遍历的数据全部放入内存中。 生成器Generator实现了迭代器接口Iterator,可以对其进行遍历操作,在PHP7中生成器添加了getReturn接口,可以获取return返回值,而在PHP7之前,在生成器中声明带值的返回会引发Fatal error: Generators cannot return values using "return" in %s on line %d错误。 function generateSerialNo(int $limit) { $i = 0; for (; $i < $limit; $i++) { yield $i; } return $i; } $gen = generateSerialNo(10); foreach ($gen as $value) { echo $value, ' '; } echo $gen->getReturn(); //输出 //0 1 2 3 4 5 6 7 8 9 10 以上时生成一个0到$limt-1的序列数字,可以看到最后输出10,其实这个10时返回值,当生成器遍历完之后$i的值已经时10了,跳出了循环。 生成器委托 生成器实现了Iterator接口,说明其可以进行遍历操作,在PHP7中,可以用yield from来把生成器委托到其它生成器。 //生成1到5的数字 function generateOneToFive() { yield from generateOneToThree(); yield from generateSixFourToFive(); } //生成1到3的数字 function generateOneToThree() { yield 1; yield 2; yield 3; } //生成4到5的数字 function generateSixFourToFive() { yield 4; yield 5; } foreach (generateOneToFive() as $num) { echo $num . ' '; } //输出 //1 2 3 4 5 上边的代码需要生成器生成1-5的数字,主生成器中并没有生成数字的逻辑,而是委托其它生成器完成。 12.更多的Error变为可捕获的Exception 从PHP7开始,程序中的fatal错误都可以被截获,PHP7提供了throwable接口,异常与错误都继承于这个接口。 Error 现在大多数的fatal错误情况会抛出一个error实例,类似于截获异常,error实例可以被try/catch截获。 try { ... } catch(Error $e) { echo $e->getMessage(); } 13.switch中的default默认值 在PHP7之前,switch语句中允许多个default默认值,从PHP7开始,只能有一个default默认值,否则会产生fatal级别错误。 // php7之前 switch (true) { case 'value': # code... break; default: # code... break; default: # code... break; } // php7 switch (true) { case 'value': # code... break; default: # code... break; } 14.闭包的绑定 Closure::call() 之前声明一个闭包之后需要为为闭包绑定执行上下文,需要复制闭包然后绑定$this,现在使用call()省去复制步骤,更加方便,性能更好。 PHP7之前 class App { public function execute() { echo 'App execute'; } } $closure = function() { echo $this->execute(); }; $newClosure = Closure::bind($closure, new App()); //或者$newClosure = $closure->bindTo(new App()); $newClosure(); //输出App execute PHP7 class App { public function execute() { echo 'App execute Call'; } } $closure = function() { echo $this->execute(); }; $closure->call(new App()); //输出App execute Call 15.整除函数intdiv 这应该很好了解,整除,返回的是整数部分的模。 echo intdiv(100, 3) , '<br>'; echo intdiv(8, 7) , '<br>'; echo intdiv(10.4, 2.5) , '<br>'; //结果 //33 1 5 16.函数preg_replace_callback_array() 这个新函数能够以数组的形式来传递正则和回掉函数处理匹配工作,比使用preg_replace_callback()精简了不少,特别适合批量匹配正则。 17.Expectations 预期 在PHP7中assert不再是一个函数,而是一个语言结构就像echo一样。 预期增强了之前的assert方法,我们可以在开发或者生产环境中使用断言,其提供了可配置选项,我们可以针对不同的环境来使用不同的策略。 PHP7的断言配置: zend.assertions 1-生成和执行代码(开发坏境) 0-生成代码但跳过运行时环境 -1-不生成代码(生产环境) assert.exception 1-断言失败时,抛出异常,没有指定异常则默认抛出AssertException 0-生成一个Throwable抛出警告,而不是抛出错误(兼容PHP5的行为)。 ini_set('zend.assertions', 1); $dest = true; assert(false, $dest); //抛出AssertException //---------------------------- ini_set('assert.exception', 0); ini_set('zend.assertions', 0); $dest = true; assert(false, $dest); //无错误和警告