本篇文章主要是介绍php7相对于php5.6的一些新的特性。

增加箭头函数的支持

  • 主要是为了提高代码的可读性和简洁性
  • 语法:fn($n) => $n * $n * $n

如下所示:


$a = [1, 2, 3, 4, 5];

$b = array_map(fn($n) => $n * $n * $n, $a);

print_r($b);


预加载

  • 主要目的是提升 PHP 7.4 的性能
  • 预加载是在OPcache中加载文件、框架和库的过程,绝对是新版本的最佳补充

弱引用

  • php7.4中增加的
  • 弱引用也是一种引用形式,如果我们销毁了原来的对象,那么弱引用对象也会被销毁
  • 有利于垃圾回收
  • 语法:WeakReference::create($obj)

原来的赋值方式的对象引用,在unset原来的对象之后,内存中的实际对象没有被释放,只是切断了关联:

$obj = new stdClass;
$weakRef = $obj;

var_dump($weakRef);
// object(stdClass)#1 (0) {
// }

unset($obj);
var_dump($weakRef);
// object(stdClass)#1 (0) {
// }

通过弱引用的方式,在unset原始对象之后,内存中的实际对象也会被释放:

$obj = new stdClass;
$weakRef = WeakReference::create($obj);

var_dump($weakRef->get());
// object(stdClass)#2 (0) {
// }

unset($obj);
var_dump($weakRef->get());
// NULL

直接使用 new 来创建对象,这种形式是不行的,会一直返回 NULL 。因为弱引用是通过变量来创建的,它指向的是原始对象的符号表,而变量和对象之间的符号表连接才是弱引用关心的内容,它会根据符号表的状态来判断当前的状态:

$weakRef = WeakReference::create(new stdClass);
var_dump($weakRef->get());
// NULL

空合并操作符

  • 可以减少书写代码的逻辑
  • 语法:??
$name = $name ?? "NoName";  // 如果$name有值就取其值,否则设$name成"NoName"

数组表达式中的展开运算符

  • 展开运算符被认为是一种语言结构,而 array_merge 是一个函数
  • 针对常量数组的编译时长优化,性能将会提升
  • 语法:[...$parts]
$parts = ['apple', 'pear'];
$fruits = ['banana', 'orange', ...$parts, 'watermelon'];
print_r($fruits);
// Array ( [0] => banana [1] => orange [2] => apple [3] => pear [4] => watermelon )

新增类型提示

  • php5.0增加的函数参数对象类型提示:function printPerson(Person $personObject){}
  • php5.1增加的函数参数的数组类型提示:function printSkill(array $arr) {}
  • php7增加的标量类型提示:function printRecord(string $name, int $id, float $salary, bool $sex){}

函数和方法返回的类型提示

  • 规定返回值必须是指定的类型:function getRecord(string $name) : string {}
  • PHP 7.1 引入了 Void 返回类型

代码示例:

function first(): void {
    // ...
}

function second(): void {
    // ...
    return;
}

严格类型约束

  • 文件的第一条语句的位置放上文件级别指令declare(strict_types=1)来声明的这个文件

如果没有规定严格类型限制的话,那么对于标量类型的参数类型提示和返回值类型提示将不影响程序的运行:

// 1、声明函数
function getPrice(int $price) : int {
    return $price;
}

// 2、执行函数,程序会将10.2转为整型,直接舍弃小数点,这可能会导致问题
getPrice(10.2);

但是,需要注意的是,对象及数组类型还是具备约束力。

生成器特性

  • 新增的生成器委托
  • 生成器委托的形式为:yield from <expr><expr>的结果得是可遍历对象或数组。

代码示例:

$generator = function () {
	// 会先迭代这个部分内容
	yield from range(1, 3);
	
	// 然后再执行这部分内容
	foreach (range(4, 6) as $i) {
		yield $i;
	}
};

// 将输出1、2、3、4、5、6
foreach ($generator() as $value) {
	echo "$value";
}
  • 生成器返回表达式

代码示例:

$traverser = (function () {
  yield "foo";
  yield "bar";
  return "value";
})();

// 这里将不会输出,因为没有迭代的话,将不会执行
$traverser->getReturn();

foreach ($traverser as $value) {
    echo "{$value}", PHP_EOL;
}

$traverser->getReturn();  // "value"

飞船操作符

  • 形式:(expr) <=> (expr)
  • 左边运算对象小,则返回-1;左、右两边运算对象相等,则返回0;左边运算对象大,则返回1

代码示例:

$name = ["Simen", "Suzy", "Cook", "Stella"];
usort($name, function ($left, $right) {
    return $left <=> $right;
});
print_r($name);

常量数组

  • PHP 7 之前只允许类/接口中使用常量数组,现在 PHP 7 也支持非类/接口的普通常量数组了

代码示例:

define("USER", [
  "name"  => "Simen",
  "sex"   => "Male",
  "age"   => "38",
  "skill" => ["PHP", "MySQL", "C"]
]);
// USER["skill"][2] = "C/C++";  // PHP Fatal error:  Cannot use temporary expression in write context in...

统一了变量语法

  • 统一了由左向右结合的规则
$goo = [
    "bar" => [
        "baz" => 100,
        "cug" => 900
    ]
];

$foo = "goo";

// 实际为:($$foo)['bar']['baz']; PHP 5 中为:${$foo['bar']['baz']};
// PHP 7 中一个笼统的判定规则是,由左向右结合。
$$foo["bar"]["baz"];
                      

新增的Throwable 接口

  • \Exception\Error 类都实现了 Throwable,所以这个可以捕获这些异常
  • 好像内存超出的异常不能被捕获到
try {
    $name = $name->method();
} catch (\Throwable $e) {
    echo  $e->getMessage();
}

补充:好像实际开发过程中,类似内存超时这种错误,仍旧无法捕获到!

新增use 组合声明

  • use 组合声明可以减少 use 的输入冗余

代码示例:

use PHPGoodTaste\Utils\{
    Util,
    Form,
    Form\Validation,
    Form\Binding
};

一次捕捉多种类型的异常、错误

  • PHP 7.1 新添加了捕获多种异常/错误类型的语法——通过竖杠|来实现。

代码示例:

try {
      throw new LengthException("LengthException");
    //   throw new DivisionByZeroError("DivisionByZeroError");
    //   throw new Exception("Exception");
} catch (\DivisionByZeroError | \LengthException $e) {
    echo "出错消息 --- ", $e->getMessage(), PHP_EOL;
} catch (\Exception $e) {
    echo "出错消息 --- ", $e->getMessage(), PHP_EOL;
} finally {
    // ...
}

常量可见性修饰符

  • PHP 7.1类常量可以可见性修饰符的

代码示例:

class YourClass 
{
    const THE_OLD_STYLE_CONST = "One";

    public const THE_PUBLIC_CONST = "Two";
    private const THE_PRIVATE_CONST = "Three";
    protected const THE_PROTECTED_CONST = "Four";
}

iterable 伪类型

  • PHP 7.1 引入了 iterable 伪类型
  • iterable 类型适用于数组、生成器以及实现了 Traversable 的对象,它是 PHP 中保留类名。

代码示例:

$fn = function (iterable $it) : iterable {
    $result = [];
    foreach ($it as $value) {
        $result[] = $value + 1000;
    }
    return $result;
};

$fn([1, 2, 3, 4, 5, 6, 7, 8, 9, 10]);

可空类型

  • PHP 7.1 引入了可空类型。
  • 对于同一类型的强制要求,可以设置其是否可空。

代码示例:

$fn = function (?int $in) {
    return $in ?? "NULL";
};

$fn(null);
$fn(5);
$fn();  // TypeError: Too few arguments to function {closure}(), 0 passed in ...
 posted on 2021-06-21 14:40  silverwq  阅读(170)  评论(0)    收藏  举报