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作为Shell脚本语言使用
Oct 09 PHP
图象函数中的中文显示
Oct 09 PHP
PHP中冒号、endif、endwhile、endfor使用介绍
Apr 28 PHP
PHP简洁函数(PHP简单明了函数语法)
Jun 10 PHP
php添加文章时生成静态HTML文章的实现代码
Feb 17 PHP
php根据年月获取季度的方法
Mar 31 PHP
php rsa加密解密使用详解
Jan 14 PHP
PHP新建类问题分析及解决思路
Nov 19 PHP
PHP使用Redis替代文件存储Session的方法
Feb 15 PHP
php写一个函数,实现扫描并打印出自定目录下(含子目录)所有jpg文件名
May 26 PHP
PHP+jQuery实现即点即改功能示例
Feb 21 PHP
如何用RabbitMQ和Swoole实现一个异步任务系统
May 29 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中var_dump方法的使用详解
2013/06/24 PHP
Codeigniter出现错误提示Error with CACHE directory的解决方案
2014/06/12 PHP
php实现比较两个字符串日期大小的方法
2015/05/12 PHP
php使用APC实现实时上传进度条功能
2015/10/26 PHP
Yii清理缓存的方法
2016/01/06 PHP
PHP Curl模拟登录微信公众平台、新浪微博实例代码
2016/01/28 PHP
OfflineSave离线保存代码再次发布使用说明
2007/05/23 Javascript
Javascript string 扩展库代码
2010/04/09 Javascript
基于javascipt-dom编程 table对象的使用
2013/04/22 Javascript
JavaScript 实现类的多种方法实例
2013/05/01 Javascript
jquery中animate动画积累的解决方法
2013/10/05 Javascript
js简单实现让文本框内容逐个字的显示出来
2013/10/22 Javascript
基于jquery扩展漂亮的下拉框可以二次修改
2013/11/19 Javascript
jQuery回到顶部的代码
2016/07/09 Javascript
js图片上传前预览功能(兼容所有浏览器)
2016/08/24 Javascript
JS生成和下载二维码的代码
2016/12/07 Javascript
vue 返回上一页,页面样式错乱的解决
2019/11/14 Javascript
微信h5静默和非静默授权获取用户openId的方法和步骤
2020/06/08 Javascript
Vue $attrs & inheritAttr实现button禁用效果案例
2020/12/07 Vue.js
python使用新浪微博api上传图片到微博示例
2014/01/10 Python
Python函数式编程指南(四):生成器详解
2015/06/24 Python
python面试题之列表声明实例分析
2019/07/08 Python
使用OpenCV circle函数图像上画圆的示例代码
2019/12/27 Python
python编写softmax函数、交叉熵函数实例
2020/06/11 Python
pytorch实现查看当前学习率
2020/06/24 Python
OpenCV利用python来实现图像的直方图均衡化
2020/10/21 Python
世界最大的海报和艺术印刷商店:AllPosters.com
2017/02/01 全球购物
澳大利亚最超值的自行车之家:Reid Cycles
2019/03/24 全球购物
J2SDK1.5与J2SDK5.0有什么区别
2012/09/19 面试题
linux面试题参考答案(9)
2015/01/07 面试题
服务员自我评价
2014/01/25 职场文书
党员领导干部廉洁从政承诺书
2014/03/27 职场文书
开展党的群众路线教育实践活动总结报告
2014/10/31 职场文书
学习心理学的体会
2014/11/07 职场文书
硕士毕业论文导师评语
2014/12/31 职场文书
《暗黑破坏神2:重制版》本周进行第一轮A测 目前可官网进行申请报名
2021/04/07 其他游戏