一篇文章了解php7和php8新特性

news2025/2/24 23:23:45

PHP7新特性


?? 运算符

php7以前用三目判断变量是否存在或是否为空

$a = isset($_GET['a']) ? $_GET['a'] : 1;

php7新增null 合并运算符??快捷判断

$a = $_GET['a'] ?? 1;

函数返回值类型声明

:+返回值类型的形式定义函数的返回值类型

<?php
    
declare(strict_types=1);
function foo($a) : int
{
    return $a;
}

不过这里也有一个特点需要注意。PHP 7 增加了一个 declare 指令:strict_types,既使用严格模式。

使用返回值类型声明时,如果没有声明为严格模式,如果返回值不是预期的类型,PHP 还是会对其进行强制类型转换。但是如果是严格模式, 则会出发一个 TypeError 的 Fatal error,跟 js 的 strict mode有点类似

标量类型声明

新增了 stringintfloatbool等类型的的形式参数类型声明,在 PHP 5 中只能是类名、接口、array 或者 callable,例如下面的函数中定义int类型的参数$a

function foo(int $a) : int
{
    return $a;
}

不过还是要在开启严格模式下才会触发错误,否则php还是会对不符合预期的参数进行强制类型转换,严格模式下则触发 TypeError 的致命错误

use 批量声明

PHP 7 中 use 可以在一句话中声明多个类、函数或 const 了

<?php 
    
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};

太空船运算符

也被称为组合比较运算符或三向比较运算符。这个运算符的符号是 <=>

太空船运算符用于比较两个表达式。它会返回一个整数,表示这两个表达式的相对顺序:

  • 如果左边的值小于右边的值,返回 -1
  • 如果左边的值等于右边的值,返回 0
  • 如果左边的值大于右边的值,返回 1

这使得在需要对两个值进行比较并得到一个明确的排序结果时非常有用,特别是在排序算法中。

示例:

$a = 5;
$b = 10;

$result = $a <=> $b;

if ($result === -1) {
    echo "$a is less than $b";
} elseif ($result === 0) {
    echo "$a is equal to $b";
} else {
    echo "$a is greater than $b";
}

输出:

csharp5 is less than 10

这种运算符在某些情况下可以使代码更加简洁和易读,特别是当需要进行连续的比较和赋值操作时。

常量数组

在 PHP 7 中,您可以直接在定义常量时定义常量数组。这是通过使用 define() 函数来完成的,其中第一个参数是常量的名称,第二个参数是要分配给该常量的值。对于数组常量,您需要将数组值作为第二个参数传递,并使用 true 作为第三个参数,以指示该常量是一个数组常量。

以下是如何在 PHP 7 中定义和使用常量数组的示例

// 定义常量数组
define('MY_CONSTANT_ARRAY', [1, 2, 3, 4, 5], true);

// 检查常量是否已定义
if (defined('MY_CONSTANT_ARRAY')) {
    // 使用常量数组
    $array = MY_CONSTANT_ARRAY;
    print_r($array);
} else {
    echo "常量 MY_CONSTANT_ARRAY 未定义。";
}

一旦常量被定义,它的值就不能被改变。尝试更改常量的值将收到一个错误,类似于 “Cannot redefine constant MY_CONSTANT_ARRAY”,这意味着可以定义一个不可改变的数组,从而提高代码的可读性和安全性。

匿名类

匿名类允许你创建没有显式类名的临时类,它们通常用于需要一个简单的一次性对象,而不需要定义完整的类。匿名类特别适用于需要实现某个接口或扩展某个类的简单场景,而不必编写额外的类定义。示例:

// 使用匿名类扩展现有类
class BaseClass {
    public function showMessage() {
        echo "Hello from BaseClass!";
    }
}

$extendedObj = new BaseClass();
$extendedObj->showMessage(); // 输出 "Hello from BaseClass!"

// 使用匿名类扩展 BaseClass
$extendedObj = new class($extendedObj) extends BaseClass {
    public function showMessage() {
        parent::showMessage(); // 调用父类的 showMessage 方法
        echo " and also from the anonymous child class!";
    }
};

$extendedObj->showMessage(); // 输出 "Hello from BaseClass! and also from the anonymous child class!"

匿名类可以包含属性、方法,以及实现接口或扩展类的要求。由于它们是匿名的,你不能在其他地方引用它们,只能在创建它们的上下文中使用它们。这使得它们非常适合于一次性任务,如临时替换某个类的行为,或者在不需要持久化类定义的情况下进行测试。

异常处理改进

在 PHP 7 中,异常处理得到了几个重要的改进,使得处理异常更加简洁、高效和灵活。以下是 PHP 7 中关于异常处理的一些主要改进:

  1. 类型化异常:在 PHP 7 之前,异常通常只是普通的对象,而在 PHP 7 中,你可以使用类名来指定一个异常的类型。这允许你更加精确地捕获特定类型的异常,而不是使用通用的 Exception 类。例如:

    try {
        // 可能抛出特定类型的异常
    } catch (MyCustomException $e) {
        // 只处理 MyCustomException 类型的异常
    }
    
  2. 异常链:在 PHP 7 之前,一个异常不能包含另一个异常。在 PHP 7 中,引入了异常链的概念,允许一个异常封装另一个异常,类似于其他语言中的嵌套异常。这有助于保留原始异常的上下文,并允许更详细的错误调试。

    try {
        // 尝试执行可能出错的代码
    } catch (Exception $e) {
        throw new MyCustomException("Something went wrong", 0, $e);
    }
    

    在这个例子中,MyCustomException 可以访问原始异常 $e 的所有信息。

  3. finally 块:在 PHP 7 之前,try-catch 结构没有 finally 块,这意味着无论是否发生异常,一些清理代码可能需要在 trycatch 块中重复。在 PHP 7 中,finally 块被引入,它包含了无论是否捕获到异常都需要执行的代码。

    try {
        // 尝试执行代码
    } catch (Exception $e) {
        // 处理异常
    } finally {
        // 无论是否发生异常,都会执行这里的代码
    }
    
  4. 异常接口的变化Exception 接口在 PHP 7 中发生了变化,引入了更多的方法,如 getStringRepresentation(),该方法返回异常的字符串表示形式。同时,Throwable 接口被引入,它是一个所有可被抛出的异常的基类,包括 ExceptionError

  5. 错误和异常的统一处理:PHP 7 引入了 Throwable 接口,它允许你统一处理错误(Error)和异常(Exception)。这意味着你可以在一个 catch 块中同时捕获错误和异常,尽管在实践中通常建议分开处理它们。

这些改进使得 PHP 的异常处理更加成熟和灵活,帮助开发者编写更加健壮和易于维护的代码。

性能优化

性能优化。PHP7 引入了全新的引擎:Zend Engine 3.0,大幅提高了解释和执行 PHP 代码的速度。相比于 PHP 5.x,PHP7 的性能提升了 2-3 倍。

PHP8新特性


JIT编译器

PHP 8 引入了 JIT (Just-In-Time)编译器(即时编译引擎),可以显著提高代码执行速度。JIT编译器已经集成在了Opcache插件中,只有启动Opcache插件才有效;

开启方法:

1.在php.ini文件中添加opcache配置,根据需要调整参数值

[opcache]
opcache.enable=1
opcache.enable_cli=1
opcache.jit_buffer_size=128M
opcache.jit=1255

2.将php.ini这行的注释取消

;zend_extension=opcache  #删除前面的;号

3.重启php,在phpinfo()中查看

或者打印变量,查看on的值是否为true

<?php
var_dump(opcache_get_status()['jit']);

注意事项:如果开启了opcache并且修改了代码,那么你需要重启php服务你修改的代码才会生效!!!

命名参数

命名参数允许你在函数调用时明确指定参数的值,而不需要按照函数定义中的参数顺序传递参数。这可以提高代码的可读性和可维护性,特别是在处理具有多个可选参数的函数时。

要使用命名参数,你需要在函数调用时使用参数名称来指定参数的值。参数名称和值之间使用冒号(:)进行分隔。以下是一个示例

<?php
function createUser($name, $age=18, $email, $password = 'password123') {
    echo $name, $age=18, $email, $password = 'password123';
}

// 使用命名参数调用函数,只指定 $name 和 $email
createUser(name: 'John', email: 'john@example.com'); // 使用 $age 的默认值 18 和 $password 的默认值 'password123'

联合类型

联合类型允许一个变量、函数或方法的参数和返回值接受多种不同的类型。这增加了类型系统的灵活性,并有助于在开发过程中提供更准确的类型检查。

联合类型使用竖线(|)分隔多个类型,表示变量、参数或返回值可以是这些类型中的任何一个。以下是一些使用联合类型的示例:

// 变量声明
$variable = 'hello'; // string 类型
$variable = 42; // int 类型
$variable = 4.2; // float 类型
$variable = true; // bool 类型
$variable = null; // null 类型

// 函数参数
function processValue(mixed $value): void {
    // 处理 $value,它可以是任何类型
}

// 方法返回值
class Example {
    public function getValue(): int|float {
        // 返回 int 或 float 类型的值
    }
}

// 类属性
class User {
    public function __construct(private string|int $id) {
        // 构造函数接受 string 或 int 类型的 $id
    }
}

// 类型断言
$value = '42';
if ($value is int|float) {
    echo "The value is an integer or a float.";
}

联合类型不会改变变量的实际类型,它们只是提供了一种方式来描述变量可能持有的多种类型。在运行时,变量的实际类型仍然是确定的,并且可以通过类型断言或其他方式来检查和操作。

属性改进

  1. 属性初始化: 在 PHP 8 之前,类的属性必须在构造函数中进行初始化。然而,在 PHP 8 中,你可以直接在属性声明时为其赋予默认值,这样就不需要再在构造函数中进行初始化。

    class MyClass {
        public $myProperty = 'default value'; // 直接在属性声明时初始化
    }
    
  2. 属性类型声明: PHP 8 引入了更严格的类型系统,允许你在属性声明时指定其类型。这有助于在开发过程中捕获类型错误,并提高代码的可读性和可维护性。

    class MyClass {
        public int $myIntProperty; // 指定属性类型为 int
    }
    
  3. 只读属性
    PHP 8 引入了只读属性(read-only properties)的概念。使用 public readonly 关键字定义的属性只能在对象构造时或在 __construct 方法内部被赋值,之后就不能再修改了。这有助于确保对象的不变性。

    class MyClass {
        private $myProperty;
    
        public function __construct() {
            $this->myProperty = 'secret';
        }
    
        public function revealProperty(): string {
            return $this->myProperty; // 传统的 getter 方法
        }
    }
    
    $obj = new MyClass();
    echo $obj->revealProperty(); // 输出 "secret"
    
    // 在 PHP 8 中,你也可以这样直接读取私有属性的值(不推荐,因为破坏了封装性)
    echo $obj->myProperty; // 输出 "secret"
    

match表达式

match 表达式允许你根据表达式的值来匹配不同的情况,并执行相应的代码块。它使用了一种类似于数组解构的语法,使得代码更加简洁和直观。

下面是一个使用 match 表达式的示例:

$number = 5;

$result = match ($number) {
    1, 2, 3 => 'Low',
    4, 5, 6 => 'Medium',
    7, 8, 9 => 'High',
    default => 'Unknown',
};

echo $result; // 输出 "Medium"

match 表达式的语法比传统的 switch 语句更加简洁,并且支持多个值匹配同一个结果,这使得代码更加易读和易于维护。

需要注意的是,match 表达式在 PHP 8 中是作为一种表达式存在的,它会返回一个值,而不是像 switch 语句那样仅仅执行代码块。因此,你可以将 match 表达式的结果赋值给一个变量,或者在更大的表达式中使用它。

Nullsafe 运算符

在 PHP 8 中,引入了一个新的运算符叫做 Nullsafe 运算符(?->)。这个运算符提供了一种安全的方式来访问对象的属性或调用对象的方法,而不需要担心对象本身是否为 null。在 PHP8以前的版本 中,如果你尝试访问一个 null 对象的属性或方法,将会引发一个错误。为了避免这种情况,开发者通常需要在使用对象之前进行空值检查。然而,这会导致代码变得冗长且难以阅读。

Nullsafe 运算符的引入解决了这个问题。它允许你在不进行显式空值检查的情况下安全地访问对象的属性或方法。如果对象本身是 null,Nullsafe 运算符将返回 null,而不会引发错误。

class User {
    public $name;

    public function getName() {
        return $this->name;
    }
}

$user = null;

// 使用传统的方式访问属性或方法会引发错误
// echo $user->name; // Error: Trying to get property 'name' of non-object
// echo $user->getName(); // Error: Calling a member function getName() on null

// 使用 Nullsafe 运算符安全地访问属性或方法
echo $user?->name; // 输出 null,而不是引发错误
echo $user?->getName(); // 输出 null,而不是引发错误

字符串与数字的比较

PHP 8 比较数字字符串(numeric string)时,会按数字进行比较。 不是数字字符串时,将数字转化为字符串,按字符串比较。

0 == 'foobar' // php7执行结果为:true
0 == 'foobar' // php8执行结果为:false

构造器属性提升

这个新的语法糖来用来创建值对象或数据传输对象。不用为类属性和构造函数指定它们,PHP 现在可以将它们合并为一个。

php7定义类属性和构造方法赋值:

class Money 
{
    public Currency $currency;
 
    public int $amount;
 
    public function __construct(
        Currency $currency,
        int $amount,
    ) {
        $this->currency = $currency;
        $this->amount = $amount;
    }
}

php8合并定义类属性和构造方法赋值:

class Money 
{
    public function __construct(
        public Currency $currency,
        public int $amount,
    ) {}
}

其他调整

更多细节调整参考官方文档

PHP: PHP 8.0.0 Release Announcement

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1585858.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

git配置多SSH

目的&#xff1a; 一台电脑可以让github、gitee等账号同时存在&#xff0c;让不同账号配置不同的密钥 第一步&#xff1a;创建不同平台的SSH公钥 执行命令&#xff1a; ssh-keygen -t rsa -C "对应仓库邮箱地址" -f ~/.ssh/id_rsa.github 如果执行上面的命令&…

Windows部署ChatGLM3步骤

一、环境要求 硬件 内存&#xff1a;> 16GB 显存: > 13GB&#xff08;4080 16GB&#xff09; 软件 python 版本推荐3.10 - 3.11 transformers 库版本推荐为 4.36.2 torch 推荐使用 2.0 及以上的版本&#xff0c;以获得最佳的推理性能 二、部署步骤 1、新建pytho…

Web服务器架构设计(学习笔记)

软件架构风格 质量属性与架构评估 Web架构综合考察 什么叫做架构风格&#xff1f;又有哪些架构风格&#xff1f;不同的架构风格的优劣如何? 有哪些层次的负载均衡实现&#xff1f;优劣如何&#xff1f; 有哪些层面的集群切片实现&#xff1f; 什么叫做小前端&#xff0c…

【收藏】工业物联网常用协议及使用场景

物联网通信协议 物联网通信协议在工业中至关重要。它们实现设备之间的实时数据传输与相互交互&#xff0c;提高了生产效率、降低成本、增强安全性。这些协议帮助监控设备运行状况、优化生产流程、预测维护需求&#xff0c;同时改善生产环境智能化。通过整合智能传感器与设备&am…

哪些工作不会被AI替代:人类能力地形图

这一轮AI&#xff0c;到底对人有多强的替代性&#xff1f;这一轮AI的可靠性&#xff0c;是之前任何一代所谓的人工智能都不能比的。 在国内&#xff0c;AI开始被用来筛选简历&#xff0c;而在国外&#xff0c;亚马逊正在用算法跟踪仓库工人的生产率&#xff0c;顺道还会给生产率…

【Vector-Map-路径规划(0)】卷首语

因为城市NOA 的开发过程中&#xff0c;十字路口这类场景非常不好处理&#xff0c;个人对路径规划没有什么基础&#xff0c;只知道深度优先&#xff0c;广度优先&#xff0c;A*&#xff0c;Dijkstra等算法&#xff0c;不知道在矢量地图中如何使用&#xff1f;因此花几天时间读几…

【Python】控制台进度条

在Python开发中&#xff0c;有时需要向用户展示一个任务的进度&#xff0c;以提供更好的交互体验。下面我将展示如何使用Python来创建一个简单的控制台进度条。 效果&#xff1a; 代码&#xff1a; import time import sys def print_progress_bar(completed, total, length…

如何使用Jellyfin+cpolar低成本部署私人影音平台并实现无公网IP远程访问

文章目录 1. 前言2. Jellyfin服务网站搭建2.1. Jellyfin下载和安装2.2. Jellyfin网页测试 3.本地网页发布3.1 cpolar的安装和注册3.2 Cpolar云端设置3.3 Cpolar本地设置 4.公网访问测试5. 结语 1. 前言 随着移动智能设备的普及&#xff0c;各种各样的使用需求也被开发出来&…

Redis从入门到精通(十二)Redis实战(九)GEO查询附近商户、BitMap用户签到和统计、HLL的UV统计

↑↑↑请在文章开头处下载测试项目源代码↑↑↑ 文章目录 前言4.10 附近商户4.10.1 GEO介绍4.10.2 附近商户需求分析4.10.3 实现新增商户功能4.10.4 实现查询附近商户功能 4.11 用户签到4.11.1 用户签到需求分析4.11.2 BitMap介绍4.11.3 实现用户签到4.11.4 实现用户签到统计4.…

Vuforia AR篇(二)— 扫描指定图片播放视频

目录 一、 使用Vuforia SDK创建Vuforia账号下载Vuforia SDK包导入SDK到unity中 二、使用Vuforia扫描指定图片播放视频创建ARCamera创建 License创建ImageTarget生成识别数据库播放视频 三、 效果 一、 使用Vuforia SDK 创建Vuforia账号 Vuforia官网 登录官网创建一个账号&am…

【fiddler】弱网测试

目录 一、测试目的 二、步骤 2.1打开弱网模式 ​ 2.2设置网络参数 &#xff08;1&#xff09;打开Rules→Customize Rules&#xff1b; &#xff08;2&#xff09;找到下面框出的代码&#xff0c;在这里设置弱网参数值&#xff1b; &#xff08;3&#xff09;设置完成后&a…

【每日刷题】Day10

【每日刷题】Day10 &#x1f955;个人主页&#xff1a;开敲&#x1f349; &#x1f525;所属专栏&#xff1a;每日刷题&#x1f345; 目录 1. 环形链表的约瑟夫问题_牛客题霸_牛客网 (nowcoder.com) 2. 21. 合并两个有序链表 - 力扣&#xff08;LeetCode&#xff09; 3. 152…

【MATLAB源码-第9期】基于matlab的DQPSK的误码率BER和误符号率SER仿真。

1、算法描述 DQPSK信号的解调与2DPSK信号的解调类似&#xff0c;也有两种方法&#xff0c;分别是极性比较法和相位比较法 极性比较法。其原理方框图如下图所示。由于DQPSK信号可以看做是两路2DPSK信号的合成&#xff0c;解 调时也可以分别按两路2DPSK信号解调&#xff0c;因此…

Docker部署SpringBoo+Vue前后端分离项目

文章目录 1. 安装Docker1. 1 卸载旧版Docker1.2 配置yum仓库1.3 安装Docker1.4 添加自启动配置1.5 配置阿里云镜像加速1.6 测试 2. 安装Nginx2.1 拉取镜像2.2 安装Nginx2.3 测试 3. 安装MySQL3.1 拉取镜像3.2 安装MySQL3.3 连接MySQL 4. 部署SpringBoot项目4.1 Maven打包4.2 编…

java数组.day16(冒泡排序,稀疏数组)

冒泡排序 冒泡排序无疑是最为出名的排序算法之一&#xff0c;总共有八大排序! 冒泡的代码还是相当简单的&#xff0c;两层循环&#xff0c;外层冒泡轮数&#xff0c;里层依次比较&#xff0c;江湖中人人尽皆知。 我们看到嵌套循环&#xff0c;应该立马就可以得出这个算法的时…

VBA信息获取与处理第四节:获取唯一非重复随机值的返回数组

《VBA信息获取与处理》教程(版权10178984)是我推出第六套教程&#xff0c;目前已经是第一版修订了。这套教程定位于最高级&#xff0c;是学完初级&#xff0c;中级后的教程。这部教程给大家讲解的内容有&#xff1a;跨应用程序信息获得、随机信息的利用、电子邮件的发送、VBA互…

001-NodeJs全局对象

概念 node是一个运行js的平台&#xff0c;在node中&#xff0c;用global对象取代了Window这个对象。 node中的repl环境可以执行js,通过命令node进入到repl环境。repl环境类似于Chrome的开发人员工具。 全局对象global 可以参考一下它的文档global全局对象 node版本介绍&am…

C++ stl容器vector的底层模拟实现

目录 前言&#xff1a; 1.成员变量&#xff0c;容量与大小 2.构造函数 无参构造&#xff1a; 带参的使用值进行构造&#xff1a; 使用迭代器区间进行构造&#xff1a; 3.交换 4.拷贝构造 5.赋值重载 6.迭代器 7.扩容 reserve&#xff1a; resize&#xff1a; 8.…

深入OceanBase内部机制:系统架构与组件精讲

码到三十五 &#xff1a; 个人主页 心中有诗画&#xff0c;指尖舞代码&#xff0c;目光览世界&#xff0c;步履越千山&#xff0c;人间尽值得 ! 目录 1️⃣OceanBase 整体架构1.1 分区1.2 分片1.3 日志流1.4 对等节点1.5 多租户 2️⃣OceanBase 架构与组件详解2.1 存储层2.2 …

公司电脑如何对文件进行加密?

在现代企业中&#xff0c;文件加密是确保敏感数据安全的关键。使用华企盾DSC数据安全防泄密系统&#xff0c;公司电脑可以轻松地对文件进行加密&#xff0c;以防止未授权的访问和数据泄露。以下是对文件进行加密的步骤和方法&#xff1a; 智能半透明加密&#xff1a;这种模式允…