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 相关文章推荐
php imagecreatetruecolor 创建高清和透明图片代码小结
May 15 PHP
通过PHP的内置函数,通过DES算法对数据加密和解密
Jun 21 PHP
php中文字符串截取方法实例总结
Sep 30 PHP
PHP跨平台获取服务器IP地址自定义函数分享
Dec 29 PHP
PHP针对JSON操作实例分析
Jan 12 PHP
php数组合并与拆分实例分析
Jun 12 PHP
PHP利用超级全局变量$_GET来接收表单数据的实例
Nov 05 PHP
关于 Laravel Redis 多个进程同时取队列问题详解
Dec 25 PHP
PHP实现动态压缩js与css文件的方法
May 02 PHP
PHP实现的函数重载功能示例
Aug 03 PHP
PHP CURL中传递cookie的方法步骤
May 09 PHP
php7 图形用户界面GUI 开发示例
Feb 22 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
PHP 事件机制(2)
2011/03/23 PHP
PHP __autoload函数(自动载入类文件)的使用方法
2012/02/04 PHP
php动态生成版权所有信息的方法
2015/03/24 PHP
php实现的二分查找算法示例
2017/06/20 PHP
TextArea 控件的最大长度问题(js json)
2009/12/16 Javascript
javascript定时保存表单数据的代码
2011/03/17 Javascript
JS中toFixed()方法引起的问题如何解决
2012/11/20 Javascript
用jquery方法操作radio使其默认选项是否
2013/09/10 Javascript
让JavaScript的Alert弹出框失效的方法禁止弹出警告框
2014/09/03 Javascript
JS实现点击按钮自动增加一个单元格的方法
2015/03/09 Javascript
根据user-agent判断蜘蛛代码黑帽跳转代码(js版与php版本)
2015/09/14 Javascript
js跨域请求数据的3种常用的方法
2015/12/01 Javascript
在javascript中创建对象的各种模式解析
2016/05/16 Javascript
jquery radio的取值_radio的选中_radio的重置方法
2016/09/20 Javascript
Angular 2应用的8个主要构造块有哪些
2016/10/17 Javascript
JS中闭包的经典用法小结(2则示例)
2016/12/28 Javascript
JSON的parse()方法介绍
2019/01/31 Javascript
Python基于有道实现英汉字典功能
2015/07/25 Python
Tensorflow 自带可视化Tensorboard使用方法(附项目代码)
2018/02/10 Python
Python实现简单http服务器
2018/04/12 Python
django.db.utils.ProgrammingError: (1146, u“Table‘’ doesn’t exist”)问题的解决
2018/07/13 Python
解决vscode python print 输出窗口中文乱码的问题
2018/12/03 Python
在OpenCV里使用Camshift算法的实现
2019/11/22 Python
Python求两个字符串最长公共子序列代码实例
2020/03/05 Python
python中threading开启关闭线程操作
2020/05/02 Python
对python中arange()和linspace()的区别说明
2020/05/03 Python
GitHub上值得推荐的8个python 项目
2020/10/30 Python
Django celery异步任务实现代码示例
2020/11/26 Python
python3定位并识别图片验证码实现自动登录功能
2021/01/29 Python
体育教学随笔感言
2014/02/24 职场文书
消防安全责任书
2014/04/14 职场文书
纪检监察建议书
2014/05/19 职场文书
2014国庆节餐厅促销活动策划方案
2014/09/16 职场文书
幼儿学前班评语
2014/12/29 职场文书
新手初学Java List 接口
2021/07/07 Java/Android
python实现学员管理系统(面向对象版)
2022/06/05 Python