PHP 7 新特性

article/2025/9/15 7:15:43

转载自:

https://zhuanlan.zhihu.com/p/27694633

https://zhuanlan.zhihu.com/p/27847880

https://zhuanlan.zhihu.com/p/29478077

https://goghcrow.gitbooks.io/php7/content/xin-te-xing.html

PHP 7 之前的类型提示

PHP 5.0 首次提出函数参数(只针对对象类型)的类型提示(Type Hint),之后 PHP 5.1 进一步扩展到可针对数组类型。举例如下:

<?php
class Person
{public $name;public $id;function __construct($name, $id) {$this->name = $name;$this->id = $id;}
}$person = new Person("Tom", 101);function printPerson(Person $person) {echo "Name: ", $person->name, ", ID: ", $person->id, ".";
}printPerson($person);$skills = ["PHP 7", "C++", "Java", "Golang", "Python"];  // PHP 5.4 起可以使用数组定义短语法function printSkills(array $skills) {foreach ($skills as $skill) {echo $skill, "\n";}
}printSkills($skills);

运行结果如下图所示:

而时光到了 PHP 7,类型提示的增强则更进了一步。

PHP 7 的标量参数类型提示

PHP 7 增加了对标量参数类型的支持:

  • int
  • float
  • string
  • bool

举例如下:

// Scalar Type Hints
function printRecord(string $name, int $id, float $salary, bool $sex) {
    echo $sex ? "$name, $id, $salary, male." : "$name, $id, $salary, female.";
}printRecord("Tom", 101, 5650.00, TRUE);
printRecord("Suzy", 101, 5650.00, FALSE);

运行结果如下图所示:

PHP 7 的函数/方法返回值类型提示

PHP 7还支持了函数/方法返回值类型提示。举例如下:

function getRecord(string $name, int $id, float $salary, bool $sex) : string {
    return $sex ? "$name, $id, $salary, male." : "$name, $id, $salary, female.";
}getRecord("Tom", 101, 5650.00, TRUE);

结果如下图所示:

return的返回类型提示,跟 PHPDoc 的 @return 注解是完全不同的两个方面,@return 只是“好言规劝”或向IDE“友好反馈”返回类型应该是什么,而对于实际的返回类型不具约束力。return的返回类型提示则具有对返回类型的运行时强制约束力——具体有待后续进一步阐述,稍安勿躁。

类型提示特性中其他一些问题点

如果函数参数或返回值是对象咋办呢?进一步来说,类型提示涉及父类继承或接口实现时,又是怎样一种表现呢?让我们继续前进的脚步吧。

interface iFoo {}
class Foo implements iFoo {}
class Bar extends Foo {}function coo(iFoo $foo) : iFoo {
    return $foo;
}coo(new Foo());
coo(new Bar());function gaa(Foo $foo) : iFoo {
    return $foo;
}gaa(new Foo());
gaa(new Bar());function zii(Bar $bar) : Foo {
    return $bar;
}zii(new Foo());  // TypeError: Argument 1 passed to zii() must be an instance of Bar, instance of Foo given on line 1
zii(new Bar());

综上,上代码看得最清楚,不太想多花笔墨了。

严格类型约束

还有一个很重要的特性——严格类型约束——declare(strict_types=1);

不妨来看看:

function xii(array $a, string $s) : int {
    print_r($a);
    echo $s, "\n";
    return "101";
}xii([1, 2, 3, 4, 5, 6, 7, 8], 101);
xii(101, 102);  // TypeError: Argument 1 passed to xii() must be of the type array, integer given on line 1

对于标量类型提示,我们的参数也罢、返回值也罢,其类型跟类型提示不一致也不影响程序运行(注:对象及数组类型具备约束力,注意区别)。这可能不是我们想要的。解决办法就是在 PHP 脚本文件的第一条语句的位置放上:declare(strict_types=1);。这是个文件级别的指令,同时不影响其他包含文件——主要是考虑向后兼容及不影响各类扩展、内建代码。

按要求加上 declare(strict_types=1); 指令之后,运行下图代码就会报错:

小结

可见 PHP 的类型提示是个非常棒的功能!在不失弱类型语言方便、灵活特点的前提下,提供了一种运行时保护措施,有助于团队协作,无疑在灵活性与规范化之间取得了巧妙平衡。这是一种浓浓的好味道,那些黑 PHP 的人,大概是不会懂的。让 PHP 走自己的路,春风十里,都不如 PHP!

顺带说说,PHP 的类型提示,可比截至当前 Python 3.6 中的类型提示强太多了,Python 3.6 中的类型提示充其量只是“好言规劝”或向IDE“友好反馈”类型应该是什么。

生成器委托(Generator Delegation)

生成器委托(Generator Delegation)是 PHP 7 添加的特性,官方文档描述是:

“In PHP 7, generator delegation allows you to yield values from another generator, Traversable object, or array by using the yield from keyword. The outer generator will then yield all values from the inner generator, object, or array until that is no longer valid, after which execution will continue in the outer generator.”。

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

<?php
declare(strict_types=1);$seh_seh_liām = function () {$generator = function () {yield from range(1, 3);foreach (range(4, 6) as $i) {yield $i;}};foreach ($generator() as $value) {echo "每天念 PHP 是最好的编程语言 6 遍...第 $value 遍...", PHP_EOL;}
};$seh_seh_liām();

生成器返回表达式(Generator Return Expression)

生成器返回表达式(Generator Return Expression)为生成器函数提供了增强内力,在 PHP 7 之前是无法在生成器函数内返回值的。

举例如下:

<?php
$traverser = (function () {yield "foo";yield "bar";return "value";
})();$traverser->getReturn();foreach ($traverser as $value) {echo "{$value}", PHP_EOL;
}$traverser->getReturn();  // "value"

生成器与Coroutine

来个直接点的例子。

<?php
declare(strict_types=1);class Coroutine
{public static function create(callable $callback) : Generator{return (function () use ($callback) {try {yield $callback;} catch (Exception $e) {echo "OH.. an error, but don't care and continue...", PHP_EOL;}})();}public static function run(array $cos){$cnt = count($cos);while ($cnt > 0) {$loc = random_int(0, $cnt-1);  // 用 random 模拟调度策略。$cos[$loc]->current()();array_splice($cos, $loc, 1);$cnt--;}}
}$co = new Coroutine();$cos = [];
for ($i = 1; $i <= 10; $i++) {$cos[] = $co::create(function () use ($i) { echo "Co.{$i}.", PHP_EOL; });
}
$co::run($cos);$cos = [];
for ($i = 1; $i <= 20; $i++) {$cos[] = $co::create(function () use ($i) { echo "Co.{$i}.", PHP_EOL; });
}
$co::run($cos);

空合并操作符(Null Coalesce Operator)

直接上例子:

$name = $name ?? "NoName";  // 如果$name有值就取其值,否则设$name成"NoName"

飞船操作符(Spaceship Operator)

形式:(expr) <=> (expr)

左边运算对象小,则返回-1;左、右两边运算对象相等,则返回0;左边运算对象大,则返回1。

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

常量数组(Constant Array)

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

Throwable 接口

这是 PHP 7 引进的一个值得期待的新特性,将极大增强 PHP 错误处理能力。PHP 5 的 try ... catch ... finally 无法处理传统错误,如果需要,你通常会考虑用 set_error_handler() 来 Hack 一下。但是仍有很多错误类型是 set_error_handler() 捕捉不到的。PHP 7引入 Throwable 接口,错误及异常都实现了 Throwable,无法直接实现 Throwable,但可以扩展 \Exception 和 \Error 类。可以用 Throwable 捕捉异常跟错误。\Exception 是所有PHP及用户异常的基类;\Error 是所有内部PHP错误的基类。

$name = "Tony";
try {$name = $name->method();
} catch (\Error $e) {echo "出错消息 --- ", $e->getMessage(), PHP_EOL;
}try {$name = $name->method();
} catch (\Throwable $e) {echo "出错消息 --- ", $e->getMessage(), PHP_EOL;
}try {intdiv(5, 0);
} catch (\DivisionByZeroError $e) {echo "出错消息 --- ", $e->getMessage(), PHP_EOL;
}

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 之前的类常量是不允许添加可见性修饰符的,此时类常量可见性相当于 public。PHP 7.1 为类常量添加了可见性修饰符支持特性。总的来说,可见性修饰符使用范围如下所示:

  • 函数/方法:public、private、protected、abstract、final
  • 类:abstract、final
  • 属性/变量:public、private、protected
  • 类常量:public、private、protected
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]);

可空类型(Nullable Type)

PHP 7.1 引入了可空类型。看看新兴的 Kotlin 编程语言的一个噱头特性就是可空类型。PHP 越来越像“强类型语言了”。对于同一类型的强制要求,可以设置其是否可空。

$fn = function (?int $in) {return $in ?? "NULL";
};$fn(null);
$fn(5);
$fn();  // TypeError: Too few arguments to function {closure}(), 0 passed in ...

Void 返回类型

PHP 7.1 引入了 Void 返回类型。

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


http://chatgpt.dhexx.cn/article/RWAh3uJ1.shtml

相关文章

php7 新特性整理

PHP7 已经出来1年了&#xff0c;PHP7.1也即将和大家见面&#xff0c;这么多好的特性&#xff0c;好的方法&#xff0c;为什么不使用呢&#xff0c;也希望PHP越来越好。 在这里整理 PHP 5.1 &#xff0c;PHP5.2,PHP5.3,PHP5.4,PHP5.5,PHP5.6 ,PHP7,PHP7.1 所有新特性&#xff0…

PHP 7 新特性 - 收集

前言 最好的语言发布了新的版本&#xff0c;一个划时代的大版本&#xff1a;PHP7。 PHP7修复了大量BUG&#xff0c;新增了功能和语法糖。这些改动涉及到了核心包、GD库、PDO、ZIP、ZLIB等熟悉和不熟悉的核心功能与扩展包。 PHP7移除了已经被废弃的函数&#xff0c;如mysql_系…

PHP7新特性总结

前言 本文是一篇讲座听后&#xff0b;后续研究的总结。 话说当年追时髦&#xff0c;php7一出就给电脑立马装上了&#xff0c;php5和php7共存&#xff0c;也是立马写了个超级耗时间的循环脚本测了一番&#xff0c;确实php7给力很多&#xff0c;然后也是注意了一些新增的特性与一…

搭建图片加密平台,扫码支付后简单获取密码

搭建图片加密平台&#xff0c;扫码支付后简单获取密码 很多人问我&#xff0c;互联网上到底做什么项目是可以赚到钱的&#xff1f;没有基础&#xff0c;不懂技术&#xff0c;不会推广&#xff0c;所以有没有简单一点的&#xff0c;一操作就能上手就能赚钱的&#xff1f;我可以…

java中Base64图片加密解密保存

工具类中的图片解密的代码 /*** base64字符串转图片* param imgStr 图片的base64* param path 将要生成的地址* return*/ public static String generateImage(String imgStr, String path) {//如果图像数据为空 if (imgStr null) {return null;}BASE64Decoder decoder new…

PC微信机器人之实战分析微信图片加密解密

今天主要讨论下微信图片的加密和解密&#xff0c;我们都知道微信接收的图片是加密形式的需要解密&#xff0c;但是这个加密大家都知道是异或。但是怎么异或&#xff0c;跟谁异或呢&#xff1f;这次就是围绕这个来讲的&#xff0c;我们手动计算异或的值&#xff0c;才能彻底明白…

混沌加密算法python_基于混沌Logistic加密算法的图片加密与还原

摘要 一种基于混沌Logistic加密算法的图片加密与还原的方法,并利用Lena图和Baboon图来验证这种加密算法的加密效果。为了能够体现该算法在图片信息加密的效果,本文还采用了普通行列置乱加密算法和像素点的RGB的值的缩放算法这两种算法对相同的图片的图片进行处理,利用matlab…

关于身份证图片加密安全技术

前言 现在的图片都是上传到c d n或者其它第三方服务器上&#xff0c;通过一个url进行访问&#xff0c;非常的方便&#xff0c;方便的同时也带来了另外一个问题&#xff0c;隐私安全问题&#xff0c;比如&#xff1a;好莱坞隐私照片泄漏。 如何保证图片安全 如果发生客户隐私…

blob图片路径加密

目录 一、代码二、效果演示 一、代码 <!DOCTYPE html> <html lang"en"><head><meta charset"UTF-8"><meta name"viewport" content"widthdevice-width, initial-scale1.0"><title>blob图片路径加…

Cocos图片加密与解密

如果cocos项目没有对资源进行加密处理,发布出来的APK一旦被人解包&#xff0c;则所有图片资源都会暴露出来,为了避免图片资源被人恶意使用&#xff0c;所以我准备给自己项目中使用到的图片进行简单加密&#xff0c;这样可以防住一部分解包伸手党。 我们这里采用最常见的异或加…

(在线)实时图片加密

目录 1 功能介绍 2 操作说明 2.1 图片加密 2.1 图片解密 1 功能介绍 图片加密http://eastsun.xyz/sudoku/html/encryptPic.html 该网站主要用于对图片进行在线实时加密,解密 用户可以自定义加密后生成的"文字图片"内容,同时这些文字图片也可以是图片解密的提示信…

python简单的图片加密

欢迎加入我们卧虎藏龙的python讨论qq群&#xff1a;729683466 ●导 语 ● 总有些东西是你不希望别人看到的 比如 你暗恋的女神的照片 要是被别人发现了 那可就尴尬了 所以 来学一学用python加密图片吧&#xff01; 代码及相关资源获取 1&#xff1a;关注“python趣味爱好者”公…

java 图片加密

首先&#xff0c;了解下异或操作 ^ &#xff0c;对一个数进行两次异或操作得到原数值。 public class IOTest {public static void main(String[] args) {int i 3;System.out.println(i^123);//120System.out.println(i^123^123);//3}} 将一张图片进行拷贝&#xff0c;对其进…

用JS实现:图片压缩、图片加密

本文将用JavaScript实现两个颇有技术含量的功能&#xff1a;图片压缩、图片加密。 最终效果&#xff1a;可实现将任意图片加密、压缩&#xff0c;并保存到一个独立的html页面中&#xff0c;输入正确的密码&#xff0c;才能看到原图。 第一步、压缩图片 技术原理 将图片读入c…

python图片水印加密的几种处理方式

常见的图片加密方法包括加密算法、水印、隐藏、压缩等。下面简要介绍一些常见的图片加密方法&#xff1a; 加密算法 加密算法是一种基于数学运算的加密方式&#xff0c;可对图片进行加密处理&#xff0c;使得未经过解密操作的情况下难以被直接读取或显示。常见的加密算法包括对…

去除水印-Teorex Inpaint 序列号

Teorex Inpaint 正版序列号 效果很好&#xff01; 如图所示 序列号在下面&#xff1b; 上面就是 正版的效果&#xff1b; 所以 大家好评 我心领了 记得关注&#xff01; 好福利一堆呢&#xff01; 回复“水印” 知识星球也要加入哦&#xff01; 加粗样式 加入的好朋友…

Inpaint 5.2安装说明

##一&#xff0e;软件简介&#xff1a; Inpaint 是一款可以从图片上去除不必要的物体&#xff0c;让您轻松摆脱照片上的水印、划痕、污渍、标志等瑕疵的实用型软件&#xff1b;简单说来&#xff0c;Inpaint 就是一款强大实用的图片去水印软件&#xff0c;您的图片中不想要的部分…

图片去水印工具:Inpaint 7.2中文专业破解版下载及使用方法

下载地址&#xff1a; 点我 Inpaint 是一款可以从图片上去除不必要的物体&#xff0c;让您轻松摆脱照片上的水印、划痕、污渍、标志等瑕疵的实用型软件&#xff1b;简单说来&#xff0c;Inpaint 就是一款强大实用的图片去水印软件&#xff0c;您的图片中不想要的部分&#xff0…

snipaste使用教程介绍

snipaste是一个简单但强大的截图工具&#xff0c;但是很多用户下载之后都不知道怎么用&#xff1f;今天小编带来的内容就是snipaste使用方法教程。 Win10纯净版_Win10 64位纯净版_Win10纯净精简版系统下载-系统部落 1、打开Snipaste首选&#xff0c;切换到常规&#xff0c;勾…

截图工具Snipaste

提示&#xff1a;今天介绍一个好用的截图工具 Snipaste介绍 软件名/版本&#xff1a; Snipaste-2.7.3-Beta-x64 Snipaste介绍&#xff1a;这里只谈一下我的使用感受吧&#xff0c;Snipaste有我们常用的截图样式&#xff0c;它有个好用的粘贴方式就是随意粘贴不影响你其它的操…