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与javascript对多项选择的处理
Oct 09 PHP
截获网站title标签之家内容的例子
Oct 09 PHP
不用mod_rewrite直接用php实现伪静态化页面代码
Oct 04 PHP
php更改目录及子目录下所有的文件后缀扩展名的代码
Oct 12 PHP
php代码运行时间查看类代码分享
Aug 06 PHP
php递归json类实例
Dec 02 PHP
常见php数据文件缓存类汇总
Dec 05 PHP
学习php设计模式 php实现备忘录模式(Memento)
Dec 09 PHP
微信接口生成带参数的二维码
Jul 31 PHP
PHP调用API接口实现天气查询功能的示例
Sep 21 PHP
ThinkPHP框架使用redirect实现页面重定向的方法实例分析
Apr 12 PHP
Laravel ORM 数据model操作教程
Oct 21 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 current函数获取未知字符键名数组第一个元素的值
2013/06/24 PHP
php天翼开放平台短信发送接口实现方法
2014/12/22 PHP
PHP解析url并得到url参数方法总结
2018/10/11 PHP
php设计模式之策略模式应用案例详解
2019/06/17 PHP
客户端静态页面玩分页
2006/06/26 Javascript
使两个iframe的高度与内容自适应,且相等
2006/11/20 Javascript
起点页面传值js,有空研究学习下
2010/01/25 Javascript
js png图片(有含有透明)在IE6中为什么不透明了
2010/02/07 Javascript
toString()一个会自动调用的方法
2010/02/08 Javascript
js里的prototype使用示例
2010/11/19 Javascript
解析DHTML,JavaScript,DOM,BOM以及WEB标准的描述
2013/06/19 Javascript
Javascript基础教程之JavaScript语法
2015/01/18 Javascript
贴近用户体验的Jquery日期、时间选择插件
2015/08/19 Javascript
jQuery获取访问者IP地址的方法(基于新浪API与QQ查询接口)
2016/05/25 Javascript
Angular和百度地图的结合实例代码
2016/10/19 Javascript
js中string和number类型互转换技巧(分享)
2016/11/28 Javascript
利用jQuery实现滑动开关按钮效果(附demo源码下载)
2017/02/07 Javascript
关于axios如何全局注册浅析
2018/01/14 Javascript
详解vue2.0监听属性的使用心得及搭配计算属性的使用
2018/07/18 Javascript
JS实现鼠标拖拽盒子移动及右键点击盒子消失效果示例
2019/01/29 Javascript
vue如何获取自定义元素属性参数值的方法
2019/05/14 Javascript
node.js使用stream模块实现自定义流示例
2020/02/13 Javascript
[02:17]DOTA2亚洲邀请赛 RAVE战队出场宣传片
2015/02/07 DOTA
[01:12:27]EG vs Secret 2018国际邀请赛淘汰赛BO3 第二场 8.22
2018/08/23 DOTA
python统计文本字符串里单词出现频率的方法
2015/05/26 Python
使用Python下载歌词并嵌入歌曲文件中的实现代码
2015/11/13 Python
Python使用logging结合decorator模式实现优化日志输出的方法
2016/04/16 Python
Python实现图片转字符画的示例代码
2017/08/21 Python
Python json模块dumps、loads操作示例
2018/09/06 Python
使用TensorFlow实现二分类的方法示例
2019/02/05 Python
Python PyQt5整理介绍
2020/04/01 Python
详解Python3 定义一个跨越多行的字符串的多种方法
2020/09/06 Python
SQL Server里面什么样的视图才能创建索引
2015/04/17 面试题
秘书行业自我鉴定范文
2013/12/30 职场文书
自我鉴定四大框架
2014/01/17 职场文书
高校自主招生校长推荐信
2015/03/23 职场文书