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
PHP 高手之路(二)
Oct 09 PHP
[原创]PHP中通过ADODB库实现调用Access数据库之修正版本
Dec 31 PHP
PHP 读取文件内容代码(txt,js等)
Dec 06 PHP
php set_time_limit()函数的使用详解
Jun 05 PHP
laravel 5 实现模板主题功能
Mar 02 PHP
PHP使用mysqldump命令导出数据库
Apr 14 PHP
php准确计算复活节日期的方法
Apr 18 PHP
thinkphp命名空间用法实例详解
Dec 30 PHP
深入理解PHP原理之执行周期分析
Jun 01 PHP
PHP实现对数组分页处理实例详解
Feb 07 PHP
PHP的mysqli_thread_id()函数讲解
Jan 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
一个程序下载的管理程序(三)
2006/10/09 PHP
让你同时上传 1000 个文件 (一)
2006/10/09 PHP
MYSQL数据库初学者使用指南
2006/11/16 PHP
对于PHP 5.4 你必须要知道的
2013/08/07 PHP
php中AES加密解密的例子小结
2014/02/18 PHP
PHP 使用redis简单示例分享
2015/03/05 PHP
基于php编程规范(详解)
2017/08/17 PHP
文本有关的样式和jQuery求对象的高宽问题分别说明
2013/08/30 Javascript
jquery交替变换颜色的三种方法 实例代码
2013/11/19 Javascript
innerText 使用示例
2014/01/23 Javascript
用js正确判断用户名cookie是否存在的方法
2014/01/28 Javascript
基于jquery实现简单的分页控件
2016/03/17 Javascript
AngularJS基础 ng-class-odd 指令示例
2016/08/01 Javascript
js判断checkbox是否选中个数的方法(超简单)
2016/08/19 Javascript
servlet+jquery实现文件上传进度条示例代码
2017/01/25 Javascript
使用javaScript实现鼠标拖拽事件
2020/04/03 Javascript
简单理解Vue中的nextTick方法
2018/01/30 Javascript
小程序测试后台服务的方法(ngrok)
2019/03/08 Javascript
新手快速入门微信小程序组件库 iView Weapp
2019/06/24 Javascript
vue-router结合vuex实现用户权限控制功能
2019/11/14 Javascript
[02:36]DOTA2上海特锦赛 回忆电竞生涯的重要瞬间
2016/03/25 DOTA
[01:30:15]DOTA2-DPC中国联赛 正赛 Ehome vs Aster BO3 第二场 2月2日
2021/03/11 DOTA
python刷投票的脚本实现代码
2014/11/08 Python
python中numpy基础学习及进行数组和矢量计算
2017/02/12 Python
Python实现自动登录百度空间的方法
2017/06/10 Python
python构建自定义回调函数详解
2017/06/20 Python
在python3环境下的Django中使用MySQL数据库的实例
2017/08/29 Python
不同版本中Python matplotlib.pyplot.draw()界面绘制异常问题的解决
2017/09/24 Python
python九九乘法表的实例
2017/09/26 Python
Python返回数组/List长度的实例
2018/06/23 Python
django基础学习之send_mail功能
2019/08/07 Python
python中如何使用insert函数
2020/01/09 Python
python unichr函数知识点总结
2020/12/16 Python
信息科学与技术专业求职信范文
2014/02/20 职场文书
诚信承诺书模板
2014/05/26 职场文书
2015团员个人年度总结
2015/11/24 职场文书