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提取视频网站页面中的FLASH地址的代码
Apr 17 PHP
php 面向对象的一个例子
Apr 12 PHP
php实现MD5加密16位(不要默认的32位)
Aug 12 PHP
php实现图片添加水印功能
Feb 13 PHP
php连接与操作PostgreSQL数据库的方法
Dec 25 PHP
PHP的数组中提高元素查找与元素去重的效率的技巧解析
Mar 03 PHP
php编程中echo用逗号和用点号连接的区别
Mar 26 PHP
thinkPHP自动验证机制详解
Dec 05 PHP
php安装dblib扩展,连接mssql的具体步骤
Mar 02 PHP
Thinkphp实现站点静态化的方法详解
Mar 21 PHP
利用PHP_XLSXWriter代替PHPExcel的方法示例
Jul 16 PHP
Laravel框架实现redis集群的方法分析
Sep 14 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&&mysql)五
2006/10/09 PHP
IIS+PHP+MySQL+Zend配置 (视频教程)
2006/12/13 PHP
PHP 柱状图实现代码
2009/12/04 PHP
Linux下CoreSeek及PHP扩展模块的安装
2012/09/23 PHP
ThinkPHP模板判断输出Empty标签用法详解
2014/06/30 PHP
初识通用数据库操作类――前端easyui-datagrid,form(php)
2015/07/31 PHP
php使用fullcalendar日历插件详解
2019/03/06 PHP
jQuery 插件 将this下的div轮番显示
2009/04/09 Javascript
用AJAX返回HTML片段中的JavaScript脚本
2010/01/04 Javascript
JavaScript 联动的无限级封装类,数据采用非Ajax方式,随意添加联动
2010/06/29 Javascript
javascript客户端解决方案 缓存提供程序
2010/07/14 Javascript
jquery eval解析JSON中的注意点介绍
2013/08/23 Javascript
如何学习Javascript入门指导
2013/11/01 Javascript
探讨JQUERY JSON的反序列化类 using问题的解决方法
2013/12/19 Javascript
JS延迟加载加快页面打开速度示例代码
2013/12/30 Javascript
自定义刻度jQuery进度条及插件
2015/09/02 Javascript
JS实现仿PS的调色板效果完整实例
2016/12/21 Javascript
JSONP跨域请求
2017/03/02 Javascript
angular $watch 一个变量的变化(实例讲解)
2017/08/02 Javascript
react native带索引的城市列表组件的实例代码
2017/08/08 Javascript
React Native 通告消息竖向轮播组件的封装
2020/08/25 Javascript
Angular 4根据组件名称动态创建出组件的方法教程
2017/11/01 Javascript
node学习笔记之读写文件与开启第一个web服务器操作示例
2019/05/29 Javascript
[58:54]EG vs RNG 2019国际邀请赛小组赛 BO2 第一场 8.16
2019/08/18 DOTA
pyqt5使用按钮进行界面的跳转方法
2019/06/19 Python
pyqt5 使用cv2 显示图片,摄像头的实例
2019/06/27 Python
序列化Python对象的方法
2020/08/01 Python
体育教师求职信
2014/06/30 职场文书
家具公司总经理岗位职责
2014/07/08 职场文书
竞选班长演讲稿500字
2014/08/22 职场文书
教师民族团结演讲稿
2014/08/27 职场文书
党的群众路线教育实践活动个人批评与自我批评
2014/10/16 职场文书
2015年挂职干部工作总结
2015/05/14 职场文书
财务管理制度范本
2015/08/04 职场文书
聊聊pytorch测试的时候为何要加上model.eval()
2021/05/23 Python
openstack云计算keystone组件工作介绍
2022/04/20 Servers