PHP7.1新功能之Nullable Type用法分析


Posted in PHP onSeptember 26, 2016

本文实例分析了PHP7.1新功能之Nullable Type用法。分享给大家供大家参考,具体如下:

在 PHP5 时代,PHP 的参数已经支持 type hint(除了基本类型),想必大家应该很熟悉;后来 PHP7 时代来临,PHP 也可以指定返回值的类型(以及基本类型的 type hint)。但我们可能还有一种需求:除了指定的 type hint,参数或者返回值也能定义可以为 null,举个例子,假如我们有一个 UserRepository 类,有一个方法叫 find($id),此方法可返回一个 User 对象,也可返回 null,在 PHP7.1 里就可以这么定义了:
...

class UserRepository
{
  ...
  public function find($id): ?User
  {
    ...
    return $user;
    // or
    // return null;
  }
}

但这么申明以后,如果返回 null,是否必须显式调用 return null,这就得等 7.1 正式出来之后再验证了。

当然还有参数设定是否 nullable 的例子,直接复制官网里的例子:

function say(?string $msg) {
  if ($msg) {
    echo $msg;
  }
}
say('hello'); // ok -- prints hello
say(null); // ok -- does not print
say(); // error -- 丢失属性
say(new stdclass); //error -- 类型错误

以上便是 nullable type 的大致用法,但其实引入了此种机制以后,有很多细节都是需要注意的,比如在继承的时候,子类允许去掉父类同名方法的返回类型为 nullable 的设置:

interface Fooable
{
  public function foo(): ?Fooable;
}
interface StrictFooable extends Fooable
{
  public function foo(): Fooable; // valid
}

但反过来,子类是不允许添加返回类型可以为 nullable 的。

然后我们再来看看参数类型的情况。跟返回类型相反,子类在复写父类方法时,参数类型是可以在父类参数的基础上添加 nullable 属性的:

interface Fooable
{
  public function foo(Fooable $f);
}
interface LooseFoo extends Fooable
{
  function foo(?Fooable $f);
}

反过来不行。可能刚看到这点,大家都会有疑问为什么返回类型和参数类型会有这样的设定。其实大家想想 Liskov 替换原则就明白了。
最后是关于参数默认值的问题,目前 PHP 是可以这样做的:

function foo_default(Bar $bar = null) {}
foo_default(new Bar); // valid
foo_default(null); // valid
foo_default(); // valid

但如果改成 nullable 的类型申明,即使传入的参数是 null,也不能在调用的时候省略不写:

function foo_nullable(?Bar $bar) {}
foo_nullable(new Bar); // valid
foo_nullable(null); // valid
foo_nullable(); // INVALID!

由此可见 nullable 类型的目的是为了允许某个参数带类型而且可以为 null,而默认值为 null 的参数就真的是想告诉大家某个参数的默认值是 null。以前我们如果允许某些 setter 可以置空,写的代码总是觉得怪怪的:

public function setIssueAt(\DateTime $issueAt = null)

觉得怪最大的原因我想是因为这样的一个 setter 居然可以不传参数!

这下好了,有了 nullable type,我们也就不会写那么别扭的代码了。

当然,nullable type 和 = null 是可以同时用的。这里就不写例子了,效果跟只用 = null 没有区别。

最后,还是继承:如果父类方法参数是 nullable 的,那么子类可以使用 = null

interface Contract
{
  public function method(?Foo $foo): bool;
}
class Implementation implements Contract
{
  public function method(?Foo $foo = null): bool
  {
    return is_null($foo);
  }
}

希望本文所述对大家PHP程序设计有所帮助。

PHP 相关文章推荐
不支持fsockopen但支持culr环境下下ucenter与modoer通讯问题
Aug 12 PHP
如何获知PHP程序占用多少内存(memory_get_usage)
Sep 23 PHP
php顺序查找和二分查找示例
Mar 27 PHP
php解决抢购秒杀抽奖等大流量并发入库导致的库存负数的问题
Jun 19 PHP
php返回json数据函数实例
Oct 09 PHP
PHP中shuffle数组值随便排序函数用法
Nov 21 PHP
PHP使用header()输出图片缓存实例
Dec 09 PHP
php实现可运算的验证码
Nov 10 PHP
基于PHP实现短信验证码接口(容联运通讯)
Sep 06 PHP
PHP简单实现遍历目录下特定文件的方法小结
May 22 PHP
PHP实现的DES加密解密类定义与用法示例
Nov 02 PHP
php的对象传值与引用传值代码实例讲解
Feb 26 PHP
php实现在新浪云中使用imagick生成缩略图并上传的方法
Sep 26 #PHP
php版交通银行网银支付接口开发入门教程
Sep 26 #PHP
php版微信公众平台实现预约提交后发送email的方法
Sep 26 #PHP
php版微信公众平台入门教程之开发者认证的方法
Sep 26 #PHP
php is_executable判断给定文件名是否可执行实例
Sep 26 #PHP
PHP弱类型的安全问题详细总结
Sep 25 #PHP
php中mkdir()函数的权限问题分析
Sep 24 #PHP
You might like
ThinkPHP实现批量删除数据的代码实例
2014/07/02 PHP
PHP中通过fopen()函数访问远程文件示例
2014/11/18 PHP
CI框架中通过hook的方式实现简单的权限控制
2015/01/07 PHP
php自动识别文字编码并转换为目标编码的方法
2015/08/08 PHP
PHP上传图片、删除图片简单实例
2016/11/12 PHP
Yii2中简单的场景使用介绍
2017/06/02 PHP
网站内容禁止复制和粘贴、另存为的js代码
2014/02/26 Javascript
jquery 扑捉回车键事件代码
2014/04/24 Javascript
现代 JavaScript 开发编程风格Idiomatic.js指南中文版
2014/05/28 Javascript
浅谈javascript中call()、apply()、bind()的用法
2015/04/20 Javascript
JavaScript常用字符串与数组扩展函数小结
2016/04/24 Javascript
Bootstrap每天必学之按钮(Button)插件
2016/04/25 Javascript
js中常用的Tab切换效果(推荐)
2016/08/30 Javascript
js判断手机号是否正确并返回的实现代码
2017/01/17 Javascript
Angular实现模版驱动表单的自定义校验功能(密码确认为例)
2018/05/17 Javascript
jQuery实现鼠标移入移出事件切换功能示例
2018/09/06 jQuery
vue 使用鼠标滚动加载数据的例子
2019/10/31 Javascript
vue自动添加浏览器兼容前后缀操作
2020/08/13 Javascript
Python3 入门教程 简单但比较不错
2009/11/29 Python
Python multiprocessing多进程原理与应用示例
2019/02/28 Python
Python利用scapy实现ARP欺骗的方法
2019/07/23 Python
Pytorch基本变量类型FloatTensor与Variable用法
2020/01/08 Python
python 识别登录验证码图片功能的实现代码(完整代码)
2020/07/03 Python
python中round函数保留两位小数的方法
2020/12/04 Python
HTML5 Canvas图像模糊完美解决办法
2018/02/06 HTML / CSS
奥地利时尚、美容、玩具和家居之家:Kastner & Öhler
2020/04/26 全球购物
面试后的感谢信范文
2014/02/01 职场文书
学生安全教育材料
2014/02/14 职场文书
给学校的建议书范文
2014/05/15 职场文书
英语专业求职信
2014/07/08 职场文书
2015年中学校长工作总结
2015/05/19 职场文书
婚宴致辞
2015/07/28 职场文书
会计手工模拟做账心得体会
2016/01/22 职场文书
导游词之铁岭象牙山
2019/12/06 职场文书
解决linux下redis数据库overcommit_memory问题
2022/02/24 Redis
最新动漫情报:2022年7月新番定档超过30部, OVERLORD骨王第四季也在其中噢
2022/05/04 日漫