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类
Oct 09 PHP
echo, print, printf 和 sprintf 区别
Dec 06 PHP
php daddslashes()和 saddslashes()有哪些区别分析
Oct 26 PHP
thinkphp3.0 模板中函数的使用
Nov 13 PHP
做了CDN获取用户真实IP的函数代码(PHP与Asp设置方式)
Apr 13 PHP
php获取淘宝分类id示例
Jan 16 PHP
yii实现级联下拉菜单的方法
Jul 31 PHP
thinkphp文件引用与分支结构用法实例
Nov 26 PHP
php查看当前Session的ID实例
Mar 16 PHP
PHP实现向关联数组指定的Key之前插入元素的方法
Jun 06 PHP
PHP生成指定范围内的N个不重复的随机数
Mar 18 PHP
PHP设计模式(六)桥连模式Bridge实例详解【结构型】
May 02 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
了解Joomla 这款来自国外的php网站管理系统
2010/03/11 PHP
PHP面向对象之后期静态绑定功能介绍
2015/05/18 PHP
PHP中常见的密码处理方式和建议总结
2018/10/14 PHP
用javascript实现读取txt文档的脚本
2007/07/20 Javascript
DWR Ext 加载数据
2009/03/22 Javascript
判断客户端浏览器是否安装了Flash插件的多种方法
2010/08/11 Javascript
javascript中使用正则计算中文长度的例子
2014/04/29 Javascript
学习JavaScript设计模式(代理模式)
2015/12/03 Javascript
浅谈Vue路由快照实现思路及其问题
2018/06/07 Javascript
vue+springmvc导出excel数据的实现代码
2018/06/27 Javascript
原生JavaScript实现的无缝滚动功能详解
2020/01/17 Javascript
解决三元运算符 报错“SyntaxError: can''t assign to conditional expression”
2020/02/12 Javascript
[00:17]DOTA2荣耀之路5:It’s a disastah!
2018/05/28 DOTA
打开电脑上的QQ的python代码
2013/02/10 Python
Python计算一个文件里字数的方法
2015/06/15 Python
python实现爬虫下载美女图片
2015/07/14 Python
Python实现数据库并行读取和写入实例
2017/06/09 Python
Python数据结构与算法之图的广度优先与深度优先搜索算法示例
2017/12/14 Python
python3.X 抓取火车票信息【修正版】
2018/06/19 Python
Flask模拟实现CSRF攻击的方法
2018/07/24 Python
python Pexpect 实现输密码 scp 拷贝的方法
2019/01/03 Python
python实现连连看辅助之图像识别延伸
2019/07/17 Python
Python3.6 + TensorFlow 安装配置图文教程(Windows 64 bit)
2020/02/24 Python
Python3标准库glob文件名模式匹配的问题
2020/03/13 Python
HTML5 Canvas自定义圆角矩形与虚线示例代码
2013/08/02 HTML / CSS
澳大利亚手袋、珠宝和在线时尚精品店:The Way
2019/12/21 全球购物
教师个人鉴定材料
2014/02/08 职场文书
交警个人先进事迹材料
2014/05/11 职场文书
物流管理专业推荐信
2014/09/06 职场文书
合伙经营协议书范本
2014/09/13 职场文书
高校自主招生自荐信2015
2015/03/04 职场文书
2015年爱牙日活动总结
2015/03/23 职场文书
2015年度服装销售工作总结
2015/03/31 职场文书
民间借贷纠纷答辩状
2015/08/03 职场文书
2016年小学六一儿童节活动总结
2016/04/06 职场文书
详解Redis瘦身指南
2021/05/26 Redis