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实现ping
Oct 09 PHP
php sprintf()函数让你的sql操作更安全
Jul 23 PHP
UTF8编码内的繁简转换的PHP类
Jul 09 PHP
浅析echo(),print(),print_r(),return之间的区别
Nov 27 PHP
利用phpexcel把excel导入数据库和数据库导出excel实现
Jan 09 PHP
PHP中执行cmd命令的方法
Oct 11 PHP
PHP发送AT指令实例代码
May 26 PHP
CodeIgniter集成smarty的方法详解
May 26 PHP
Yii2框架制作RESTful风格的API快速入门教程
Nov 08 PHP
详解PHP函数 strip_tags 处理字符串缺陷bug
Jun 11 PHP
PHP在同一域名下两个不同的项目做独立登录机制详解
Sep 22 PHP
Laravel 5.5 实现禁用用户注册示例
Oct 24 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 变量定义方法
2009/06/14 PHP
Php连接及读取和写入mysql数据库的常用代码
2014/08/11 PHP
Windows下安装PHP单元测试环境PHPUnit图文教程
2014/10/24 PHP
PHP使用xmllint命令处理xml与html的方法
2014/12/15 PHP
PHP列出MySQL中所有数据库的方法
2015/03/12 PHP
JS 用6N±1法求素数 实例教程
2009/10/20 Javascript
javascript阻止浏览器后退事件防止误操作清空表单
2013/11/22 Javascript
jquery Tab效果和动态加载的简单实例
2013/12/11 Javascript
无闪烁更新网页内容JS实现
2013/12/19 Javascript
js/jquery获取文本框输入焦点的方法
2014/03/04 Javascript
javascript基础语法学习笔记
2016/01/04 Javascript
第七章之菜单按钮图标组件
2016/04/25 Javascript
mvc中form表单提交的三种方式(推荐)
2016/08/10 Javascript
Angular2-primeNG文件上传模块FileUpload使用详解
2017/01/14 Javascript
jQuery加载及解析XML文件的方法实例分析
2017/01/22 Javascript
jQuery validate 验证radio实例
2017/03/01 Javascript
angularjs的select使用及默认选中设置
2017/04/08 Javascript
JS仿QQ好友列表展开、收缩功能(第二篇)
2017/07/07 Javascript
promise和co搭配生成器函数方式解决js代码异步流程的比较
2018/05/25 Javascript
小程序封装路由文件和路由方法(5种全解析)
2019/05/26 Javascript
微信小程序Echarts图表组件使用方法详解
2019/06/25 Javascript
Python中字典的基础知识归纳小结
2015/08/19 Python
使用Python绘制图表大全总结
2017/02/11 Python
python3大文件解压和基本操作
2017/12/15 Python
Numpy中矩阵matrix读取一列的方法及数组和矩阵的相互转换实例
2018/07/02 Python
详解python 中in 的 用法
2019/12/12 Python
python argparse模块通过后台传递参数实例
2020/04/20 Python
CSS 说明横向进度条最后显示文字的实现代码
2020/11/10 HTML / CSS
Jack Rogers官网:美国经典的女性鞋靴品牌
2019/09/04 全球购物
写自荐信要注意什么
2013/12/26 职场文书
出国考察邀请函
2014/01/21 职场文书
商业活动邀请函
2014/02/04 职场文书
工作建议书范文
2014/05/13 职场文书
旅游文化节策划方案
2014/06/06 职场文书
三八妇女节标语
2014/10/09 职场文书
教你在 Java 中实现 Dijkstra 最短路算法的方法
2022/04/08 Java/Android