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 相关文章推荐
一个用mysql_odbc和php写的serach数据库程序
Oct 09 PHP
解析阿里云ubuntu12.04环境下配置Apache+PHP+PHPmyadmin+MYsql
Jun 26 PHP
php中curl和file_get_content的区别
May 10 PHP
Destoon实现多表查询示例
Aug 21 PHP
PHP ajax 异步执行不等待执行结果的处理方法
May 27 PHP
用PHP代码在网页上生成图片
Jul 01 PHP
PHP通过加锁实现并发情况下抢码功能
Aug 10 PHP
浅谈php中urlencode与rawurlencode的区别
Sep 05 PHP
CI框架使用composer安装的依赖包步骤与方法分析
Nov 21 PHP
php+Ajax无刷新验证用户名操作实例详解
Mar 04 PHP
Yii2框架配置文件(Application属性)与调试技巧实例分析
May 27 PHP
基于PHP+Mysql简单实现了图书购物车系统的实例详解
Aug 06 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
如何使用Strace调试工具
2013/06/03 PHP
easyui的tabs update正确用法分享
2014/03/21 PHP
php使用FFmpeg接口获取视频的播放时长、码率、缩略图以及创建时间
2016/11/07 PHP
ExtJS Window 最小化的一种方法
2009/11/18 Javascript
Ext.get() 和 Ext.query()组合使用实现最灵活的取元素方式
2011/09/26 Javascript
字符串的replace方法应用浅析
2011/12/06 Javascript
情人节之礼 js项链效果
2012/02/13 Javascript
JavaScript NaN和Infinity特殊值 [译]
2012/09/20 Javascript
Ext中下拉列表ComboBox组件store数据格式用法介绍
2013/07/15 Javascript
jQuery简单实现input文本框内灰色提示文本效果的方法
2015/12/02 Javascript
AngularJS 避繁就简的路由
2016/07/01 Javascript
js控制li的隐藏和显示实例代码
2016/10/15 Javascript
微信小程序 tabs选项卡效果的实现
2017/01/05 Javascript
js中获取键盘按下键值event.keyCode、event.charCode和event.which的兼容性详解
2017/03/15 Javascript
解决ionic和angular上拉加载的问题
2017/08/03 Javascript
jQuery实现判断上传图片类型和大小的方法示例
2018/04/11 jQuery
微信小程序canvas.drawImage完全显示图片问题的解决
2018/11/30 Javascript
记录vue项目中遇到的一点小问题
2019/05/14 Javascript
vue实现在线翻译功能
2019/09/27 Javascript
Vue 中 filter 与 computed 的区别与用法解析
2019/11/21 Javascript
详细分析Node.js 多进程
2020/06/22 Javascript
JavaScript 几种循环方式以及模块化的总结
2020/09/03 Javascript
[01:30]DOTA2上海特锦赛现场采访 Loda倾情献唱
2016/03/25 DOTA
跟老齐学Python之折腾一下目录
2014/10/24 Python
Python使用正则表达式抓取网页图片的方法示例
2017/04/21 Python
Pycharm设置utf-8自动显示方法
2019/01/17 Python
python代理工具mitmproxy使用指南
2019/07/04 Python
python argparser的具体使用
2019/11/10 Python
全球最大的网上自行车商店:Chain Reaction Cycles
2016/12/02 全球购物
信息技术专业个人自我评价
2013/12/11 职场文书
大学生自我鉴定范文
2013/12/28 职场文书
2014中考励志标语
2014/06/05 职场文书
房展策划方案
2014/06/07 职场文书
个人批评与自我批评
2014/10/15 职场文书
新农村建设指导员工作总结
2015/08/13 职场文书
生命的关键成分来自太空?陨石说是的
2022/04/29 数码科技