PHP 8 新特性之枚举

PHP 8 新特性之枚举 枚举概览 枚举,或称 “Enum”,能够让开发者自定义类型为一系列可能的离散值中的一个。 在定义领域模型中很有用,它能够“隔离无效状态”(making invalid states unrepresentable)。 枚举以各种不同功能的形式出现在诸多语言中。 在 PHP 中, 枚举是一种特殊类型的对象。Enum 本身是一个类(Class), 它的各种条目(case)是这个类的单例对象,意味着也是个有效对象 —— 包括类型的检测,能用对象的地方,也可以用它。 最常见的枚举例子是内置的 boolean 类型, 该枚举类型有两个有效值 true 和 false。 Enum 使开发者能够任意定义出用户自己的、足够健壮的枚举。 Enum 类似 class,它和 class、interface、trait 共享同样的命名空间。 也能用同样的方式自动加载。 一个 Enum 定义了一种新的类型,它有固定、数量有限、可能的合法值。 示例 #1 用注解实现接口的可选方法 <?php // 通过传入参数:待搜索的注解类名,可返回指定的注解类, 而不需要再到反射类中迭代循环获取所有注解。 示例 <?php <?php // 声明新的枚举类型 Suit,仅有四个有效的值: Suit::Hearts、Suit::Diamonds、 Suit::Clubs、Suit::Spades。 enum Suit { case Hearts; case Diamonds; case Clubs; case Spades; } // 变量可以赋值为以上有效值里的其中一个。 函数可以检测枚举类型,这种情况下只能传入类型的值。 function pick_a_card(Suit $suit) { /* ....

June 11, 2023 · 1 min · Leanku

PHP 8 新特性之注解

PHP 8 新特性之注解功能 注解概览 注解功能提供了代码中的声明部分都可以添加结构化、机器可读的元数据的能力, 注解的目标可以是类、方法、函数、参数、属性、类常量。 通过 反射 API 可在运行时获取注解所定义的元数据。 因此注解可以成为直接嵌入代码的配置式语言。 通过注解的使用,在应用中实现功能、使用功能可以相互解耦。 某种程度上讲,它可以和接口(interface)与其实现(implementation)相比较。 但接口与实现是代码相关的,注解则与声明额外信息和配置相关。 接口可以通过类来实现,而注解也可以声明到方法、函数、参数、属性、类常量中。 因此它们比接口更灵活。 注解使用的一个简单例子:将接口(interface)的可选方法改用注解实现。 我们假设接口 ActionHandler 代表了应用的一个操作: 部分 action handler 的实现需要 setup,部分不需要。 我们可以使用注解,而不用要求所有类必须实现 ActionHandler 接口并实现 setUp() 方法。 因此带来一个好处——可以多次使用注解。 示例 #1 用注解实现接口的可选方法 <?php interface ActionHandler { public function execute(); } #[Attribute] class SetUp {} class CopyFile implements ActionHandler { public string $fileName; public string $targetDirectory; #[SetUp] public function fileExists() { if (!file_exists($this->fileName)) { throw new RuntimeException("File does not exist"); } } #[SetUp] public function targetDirectoryExists() { if (!...

June 11, 2023 · 2 min · Leanku

PHP 8 新特性

PHP 8 新特性 命名参数(8.0) 新增命名参数的功能: 在函数或方法调用时,可通过参数名来指定参数的值,而不仅仅依赖参数的位置 从 PHP 8.0.0 开始,函数参数列表可以包含一个尾部的逗号,这个逗号将被忽略。这在参数列表较长或包含较长的变量名的情况下特别有用,这样可以方便地垂直列出参数。 <?php function takes_many_args( $first_arg, $second_arg, $again = 'a default string', // 在 8.0.0 之前,这个尾部的逗号是不允许的。 ){ // ... } z takes_many_args(1, 2); //按照参数顺序传参 takes_many_args(first_arg:1, second_arg:2); //指定参数,不分顺序 // 类也可以使用命名参数,假设Demo类构造函数有$first_arg,$second_arg,两个参数,有takes_many_args方法 $demo = new Demo(first_arg:1, second_arg:2); $demo->takes_many_args(first_arg:1, second_arg:2); // 不能用位置的参数和命名的参数一起 // 可选参数必须在必选参数后面 例如上面的$again ?> 注解(Attributes)(8.0) 新增注解的功能。 此篇单独介绍 构造器属性提升(Constructor Property Promotion)(8.0) 新增构造器属性提升功能 在构造函数中声明类的属性)。 构造器的参数也可以相应提升为类的属性。 构造器的参数赋值给类属性的行为很普遍,否则无法操作。 而构造器提升的功能则为这种场景提供了便利。 <?php class Point { protected int $x; protected int $y; public function __construct(int $x, int $y = 0) { $this->x = $x; $this->y = $y; } } // 两个参数都传入 $p1 = new Point(4, 5); // 仅传入必填的参数。 $y 会默认取值 0。 $p2 = new Point(4); // 使用命名参数(PHP 8....

May 11, 2023 · 4 min · Leanku

PHP8新特性之match表达式

PHP8 alpha2发布了,最近引入了一个新的关键字:match, 这个关键字的作用跟switch有点类似。 虽然我一般对语法糖无感,但这个我觉得还是有点意思,match这个词也挺好看,那么它是干啥的呢? 在以前我们可能会经常使用switch做值转换类的工作,类似: switch ($input) { case "true": $result = 1; break; case "false": $result = 0; break; case "null": $result = NULL; break; } (当然,有的同学会说,谁会这么写,用个数组转换不行么? 拜托,这是举例啊,数组也只能数字键和整数啊,万一key是需要其他表达式呢,万一你要多个key对应一个值呢,对吧?) 那么如果使用match关键字呢,可以变成类似: $result = match($input) { "true" => 1, "false" => 0, "null" => NULL, }; 相比switch, match会直接返回值,可以直接赋值给$result了。 并且,类似switch的多个case一个block一样,match的多个条件也可以写在一起,比如: $result = match($input) { "true", "on" => 1, "false", "off" => 0, "null", "empty", "NaN" => NULL, }; 需要注意的和switch不太一样的是,以前我们用switch可能会经常遇到这种诡异的问题: $input = "2 person"; switch ($input) { case 2: echo "bad"; break; } 你会发现,bad竟然被输出了,这是因为switch使用了宽松比较(==)。match就不会有这个问题了, 它使用的是严格比较(===),就是值和类型都要完全相等。...

March 14, 2023 · 1 min · Leanku