PHP 8:前后

2020-10-23 14:17:01

现在距离PHP8发布只有几个月的时间了,老实说,PHP8有这么多好功能。在这篇文章中,我想分享PHP8将对我自己的代码产生的实际影响。

我将尽量不滥用属性,但我认为配置事件侦听器是我将广泛使用的注释的一个示例。

你可能知道,我最近一直在研究事件源系统,我可以告诉你:有很多事件配置要做。以这台简单的投影仪为例:

//在类实现{Use;Protected Array$handlesEvent=[CartStartedEvent::class=>;&39;,CartItemAddedEvent::class=>;';,onCartItemAdded';,CartItemRemovedEvent::class=>;';,onCartItemRemoved';,CartExpiredEvent::class=>;';,CartCheckedOutEvent::class=&>;CaronCheckedOut';,CoupondedToCartItemEvent::class=>;';,CartCheckedOutEvent::class=>;';,CoupondedToCartItemEvent::class=>;';,CartCheckedOutEvent::class=>;';,CoupondedToCartItemEvent::class=>;';,CartCheckedOutEvent::class=>;';,CoupondedToCartItemEvent。OnCouponAddedToCartItem';,];公共函数(CartStartedEvent$Event):{/*…。*/}公共函数(CartItemAddedEvent$Event):{/*…。*/}公共函数(CartItemRemovedEvent$Event):{/*…。*/}公共函数(CartCheckedOutEvent$Event):{/*…。*/}公共函数(CartExpiredEvent$Event):{/*…。*/}公共函数(CouponAddedToCartItemEvent$Event):{/*…。*/}}。

事件侦听器配置和处理程序放在一起,我不需要滚动到文件顶部就可以知道侦听器是否配置正确。

我不必再费心将方法名作为字符串来编写和管理:您的IDE不能自动完成它们,没有对打字错误的静态分析,方法重命名也不起作用。

类实现{Use;#[SubscribesTo(CartStartedEvent::Class)]公共函数(CartStartedEvent$Event):{/*…。*/}#[SubscribesTo(CartItemAddedEvent::Class)]公共函数(CartItemAddedEvent$Event):{/*…。*/}#[SubscribesTo(CartItemRemovedEvent::Class)]公共函数(CartItemRemovedEvent$Event):{/*…。*/}#[SubscribesTo(CartCheckedOutEvent::Class)]公共函数(CartCheckedOutEvent$Event):{/*…。*/}#[SubscribesTo(CartExpiredEvent::Class)]公共函数(CartExpiredEvent$Event):{/*…。*/}#[SubscribesTo(CouponAddedToCartItemEvent::Class)]公共函数(CouponAddedToCartItemEvent$Event):{/*…。*/}}。

一个小一点的,但这一次会有日复一日的影响。我经常发现自己仍然需要文档块,因为有两件事:静态返回类型和泛型。后一个问题还不能解决,但幸运的是,第一个问题会在PHP8中解决!

我正在写一本名为“PHP前线”的新书。它大体上是关于PHP8和现代PHP开发的。我计划在12月份发布它,你可以订阅邮件列表来保持最新状态!

如果你读过我的博客,你会知道我写了很多关于PHP类型系统与数据传输对象结合使用的文章。当然,我在自己的代码中使用了很多DTO,所以您可以想象我有多高兴,能够重写以下代码:

类扩展{public string$name;public string$email;public int$age;public static function(CustomerRequest$Request):{return new self([';name';=>;$request->;get(';name';),';email';=>;$request->;get(';email';),';age';=>;$request->;Get(';age';),]);}}$data=CustomerData::fromRequest($customerRequest);

Class{public function(public string$name,public string$email,public int$age,){}}$data=new CustomerData(...$customerRequest->;validation());

请注意构造函数属性提升以及命名参数的使用。是的,它们可以使用命名数组和扩散运算符进行传递!

您有时会发现自己使用的枚举带有一些方法,这会根据枚举值产生不同的结果吗?

/*静态Self Pending()*静态Self Payed()*/类扩展{Private Const Pending=';Pending&39;;Private Const Payed=';Payed';public function():{return[Self::Pending=>;&39;,Self::Payed=>;&39;Green';,][$this-&>;value]?';灰色;;}}。

我认为,对于更复杂的条件,最好使用状态模式,但在某些情况下,枚举确实足够了。这个奇怪的数组语法已经是更冗长条件的简写:

/*静态Self Pending()*静态Self Payed()*/类扩展{Private Const Pending=';Pending&39;;Private Const Payed=';Payed';public function():{if($this->;value=self::ending){return';range&39;;}if($this-&>;value=self::payed){return';green';}返回';灰色';;}}。

/*静态Self Pending()*静态Self Payed()*/类扩展{Private Const Pending=';Pending&39;;Private Const Payed=';Payed';public function():{return Match($this->;value){Self::Pending=>;&39;橙色&39;,Self::Payed=&>;&39;;green';,default=>;';灰色';,};}}。

当我前面提到静态返回类型时,我忘记了需要docblock类型提示的另一个用例:联合类型。至少,它们以前是必需的,因为PHP8本身就支持它们!

在PHP8之前,您不能在表达式中使用掷出,这意味着您必须进行显式检查,如下所示:

公共函数(array$input):{if(!Isset($Input[';BAR';]){抛出条形未命中::New();}$BAR=$Input[';BAR';];//…。}。

在PHP8中,Throw已经成为一个表达式,这意味着您可以这样使用它:

如果您熟悉null合并操作符,那么您已经熟悉了它的缺点:它不能处理方法调用。相反,您需要中间检查,或者依赖某些框架提供的可选助手:

通过添加nullsafe操作符,我们现在可以在方法上具有类似于空合并的行为!

我正在写一本名为“PHP前线”的新书。它大体上是关于PHP8和现代PHP开发的。我计划在12月份发布它,你可以订阅邮件列表来保持最新状态!