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

PHP7新特性


?? 运算符

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

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

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

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

函数返回值类型声明

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

<?phpdeclare(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.mzph.cn/news/815474.shtml

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

相关文章

Unity DOTS1.0(4) Baking 和 Baker

Baking 概念&#xff1a; 把Editor中的GameObject数据转换成entities数据写入到Entity Scens里面,这个过程我们叫做BakingBaking是一种不可逆的操作&#xff0c;把低效代价昂贵的但是灵活的GameObjects转换成性能高效的Entities与Components。 作用&#xff1a; 在传统的模…

MyBatis批量插入的五种方式

MyBatis批量插入的五种方式: 一、准备工作 1、导入pom.xml依赖 <dependencies><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency><!-- MySQL驱动依赖 --…

vue3 依赖-组件tablepage-vue3说明文档,列表页快速开发,使用思路及范例(Ⅱ)搜索及数据获取配置项

github求⭐ vue3 依赖-组件tablepage-vue3说明文档&#xff0c;列表页快速开发&#xff0c;使用思路及范例&#xff08;Ⅰ&#xff09;配置项文档 vue3 依赖-组件tablepage-vue3说明文档&#xff0c;列表页快速开发&#xff0c;使用思路及范例&#xff08;Ⅱ&#xff09;搜索…

什么是享元模式,有哪些具体应用

一、定义 享元模式是一种通过尽可能多地共享数据来最小化内存使用和对象数量&#xff0c;从而提高性能的设计模式。在享元模式中&#xff0c;如果需要相同数据的多个对象&#xff0c;则共享这些对象而不是创建新的对象&#xff0c;从而提高系统的效率。 其实有很多应用场景&am…

数据库(1)

目录 1.什么是事务&#xff1f;事务的基本特性ACID&#xff1f; 2.数据库中并发一致性问题&#xff1f; 3.数据的隔离等级&#xff1f; 4.ACID靠什么保证的呢&#xff1f; 5.SQL优化的实践经验&#xff1f; 1.什么是事务&#xff1f;事务的基本特性ACID&#xff1f; 事务指…

Alibaba --- 如何写好 Prompt ?

如何写好 Prompt 提示工程&#xff08;Prompt Engineering&#xff09;是一项通过优化提示词&#xff08;Prompt&#xff09;和生成策略&#xff0c;从而获得更好的模型返回结果的工程技术。总体而言&#xff0c;其实现逻辑如下&#xff1a; &#xff08;注&#xff1a;示例图…

napi系列学习进阶篇——NAPI异步调用

简介 OpenHarmony Napi 标准系统异步接口实现支持Callback方式和Promise方式。标准系统异步接口实现规范要求&#xff0c;若引擎开启Promise特性支持&#xff0c;则异步方法必须同时支持Callback方式和Promise方式。使用哪种方式由应用开发者决定&#xff0c;通过是否传递Call…

SpringMVC--获取请求参数 / 域对象共享数据

目录 1. SpringMVC 获取请求参数 1.1. 通过ServletAPI获取 1.2. 控制器方法形参获取 1.3. RequestParam 1.4. RequestHeader 1.5. CookieValue 1.6. 通过POJO获取请求参数 1.7. 解决获取请求参数的乱码问题 2. 域对象共享数据 2.1. 三大域对象 2.2. 准备工作 2.3. S…

RedisTemplate对象中方法的使用

系列文章目录 文章目录 系列文章目录前言 前言 前些天发现了一个巨牛的人工智能学习网站&#xff0c;通俗易懂&#xff0c;风趣幽默&#xff0c;忍不住分享一下给大家。点击跳转到网站&#xff0c;这篇文章男女通用&#xff0c;看懂了就去分享给你的码吧。 Redis是一个key-va…

第二届数据安全大赛暨首届“数信杯”数据安全大赛数据安全积分争夺赛-东区预赛wp

附件下载地址&#xff1a; 链接&#xff1a;https://pan.baidu.com/s/1tClZrup28n4fUe5Kpa7mgQ?pwdkbd6 文章目录 数据安全题re_ds001Homooo0 数据分析题数据分析1-1数据分析1-2数据分析1-3数据分析2-1数据分析2-2数据分析2-3数据分析3-1数据分析3-2数据分析3-3数据分析5-1数据…

【AI基本模型】简化生成对抗网络 (GAN)

目录 一、说明 二、GAN的工作 三、如何手动计算生成对抗网络&#xff08;GAN&#xff09;&#xff1f;✍️ 四、GAN的应用 一、说明 生成对抗网络 &#xff08;GAN&#xff09; 是一种机器学习算法&#xff0c;可以生成与现实世界数据几乎无法区分的合成数据。它们的工作原理是…

【计算机毕业设计】基于Java+SSM的实战开发项目150套(附源码+演示视频+LW)

大家好&#xff01;我是程序猿老A&#xff0c;感谢您阅读本文&#xff0c;欢迎一键三连哦。 &#x1f9e1;今天给大家分享150的Java毕业设计&#xff0c;基于ssm框架&#xff0c;这些项目都经过精心挑选&#xff0c;涵盖了不同的实战主题和用例&#xff0c;可做毕业设计和课程…

python画神经网络图

代码1(画神经网络连接图&#xff09; from math import cos, sin, atan import matplotlib.pyplot as plt # 注意这里并没有用到这个networkx这个库&#xff0c;完全是根据matploblib这个库来画的。 class Neuron():def __init__(self, x, y,radius,nameNone):self.x xself.y …

文本检索粗读

一.前情提要 1.本文理论为主&#xff0c;并且仅为个人理解&#xff0c;能力一般&#xff0c;不喜勿喷 2.本文理论知识较为散碎 3.如有需要&#xff0c;以下是原文&#xff0c;更为完备 Neural Corpus Indexer 文档检索【论文精读47】_哔哩哔哩_bilibili 二.正文 &#xf…

CommunityToolkit.Mvvm笔记1---Instruction

CommunityToolkit.Mvvm是一个官方社区套件(Windows Community Toolkit)&#xff0c;延续了MVVMLight的风格&#xff0c;是一个现代、快速和模块化的 MVVM 库。 它是 .NET 社区工具包的一部分。 第一&#xff1a;入门安装 1&#xff0c;用NuGget安装&#xff0c;搜索Community…

【菜狗学前端】ES6+笔记(包含Promise及async、await等)

老样子。复制上来的图片都没了&#xff0c;想看原版可以移步对应资源下载(资源刚上传&#xff0c;还在审核中) &#xff08;免费&#xff09;菜狗学前端之ES6笔记https://download.csdn.net/download/m0_58355897/89135424 一 解构赋值 解构赋值 解构指的是把一个数据…

马上拥有“钞能力”!!24个Python接单平台,赶紧码住!!

学Python能兼职挣米吗&#xff1f;怎么挣&#xff1f; 一、Python兼职种类&#xff1a; 接私活刚学会python那会&#xff0c;就有认识的朋友介绍做一个网站的私活&#xff0c;当时接单赚了4K&#xff0c;后又自己接过开发网站后台接口、做数据处理等事情&#xff0c;都赚了一…

【机器学习300问】66、均方误差与交叉熵误差,两种损失函数的区别?

一、均方误差&#xff08;Mean Squared Error, MSE&#xff09; 假设你是一个教练&#xff0c;在指导学生射箭。每次射箭后&#xff0c;你可以测量子弹的落点距离靶心的差距&#xff08;误差&#xff09;。MSE就像是计算所以射击误差的平方后的平均值。它强调了每一次偏离靶心的…

了解 Vue 工程化开发中的组件通信

目录 1. 组件通信语法 1.1. 什么是组件通信&#xff1f; 1.2. 为什么要使用组件通信&#xff1f; 1.3. 组件之间有哪些关系&#xff08;组件关系分类&#xff09;&#xff1f; 1.4. 组件通信方案有哪几类 &#xff1f; 2. 父子通信流程图 3. 父传子 3.1. 父传子核心流程…

力扣练习题(2024/4/14)

1接雨水 给定 n 个非负整数表示每个宽度为 1 的柱子的高度图&#xff0c;计算按此排列的柱子&#xff0c;下雨之后能接多少雨水。 示例 1&#xff1a; 输入&#xff1a;height [0,1,0,2,1,0,1,3,2,1,2,1] 输出&#xff1a;6 解释&#xff1a;上面是由数组 [0,1,0,2,1,0,1,3,2…