Type hints, Type safe

泊学实操视频 
泊学原文链接
PHP 7中最引人注目的新特性之一,无疑是Scalar type hints。我们可以在函数参数和返回值中使用scalar type hints,还可以指定scalar type的推导和匹配方式。

Scalar type hints

Type hints并不是什么新生事物,PHP 5.0第一次引入了type hints特性,允许我们指定函数的参数是一个特定class或interface类型。之后,在PHP 5.1中,我们可以指定参数是一个array type,在PHP 5.4中,我们可以指定参数是一个“可被调用(callable)”的类型(例如:function或Closure)。在经过了对RFC若干次的修改和讨论之后,PHP 7终于把scale type也加入到了type hint中。

PHP 7允许我们在type hints中使用下面这4种scalar type:

bool: true/false;
float: 表示浮点数类型;
int: 表示整数类型;
string: 表示字符串类型;
我们来看一个使用上面这些scalar type hints的例子:

<?php
function sendHttpResponse(int $statusCode, string $statusText) { } sendHttpResponse(200, "OK");
sendHttpResponse("404", "File not found");

对于上面的两个调用,是否满足sendHttpResponse的type hints,取决于我们对匹配方式的设置。

Coercive Type

这是PHP 7针对scalar type hints采取的默认方式,即尽可能尝试把参数转换成scalar type hints要求的类型。所以,在sendHttpResponse("404", "File not found")中,"404"会被转换成整数400,让函数得以正常执行。当然,方便总是有代价的,因为类型转换有时会导致精度丢失。我们来看一些常见的例子:

<?php

function coerciveInt(int $a) {
echo "a = ".$a;
} coerciveInt(1.5); // 1
coerciveInt("100.1"); // 100
coerciveInt("100int"); // 100 function coerciveFloat(float $a) {
echo "a = ".$a;
} coerciveFloat(1); // 1.0
coerciveFloat("3.14"); // 3.14
coerciveFloat("3.14PI"); // 3.14

在这里,要特别说一下bool类型,它和我们在C++中的处理逻辑类似,一切表达“空值”的概念,例如:0, 0.0, null, "0", ""(空字符串), [](空数组),$uninitializedVar(未经初始化的变量),都会被认为是false,除去这些情况之外的,则会被认为是true。

Strict Type

如果你不希望PHP 7执行上面的类型转换,要求类型严格匹配,你可以手动启用PHP 7的“严格模式”。在这个模式下,任何不严格匹配的类型都会导致抛出\TypeError异常。Strict type只能在web application的中使用,也就是说,如果你在编写一个library,你不能在你的代码里,开启strict type。

启用strict type很简单,在PHP代码中的第一行,写上declare(strict_types=1);。

*“PHP起始标记和declare(strict_types=1);之间,不能有任何内容,namespace必须紧跟在declare语句后面。”
特别提示*

我们来看一些例子,它们都会导致\TypeError异常:

<?php declare(strict_types=1);

function strictInt(int $a) {
echo "a = ".$a;
} strictInt(1.5); // \TypeError
strictInt("100.1"); // \TypeError
strictInt("100int"); // \TypeError function strictFloat(float $a) {
echo "a = ".$a;
} strictFloat(1); // \TypeError
strictFloat("3.14"); // \TypeError
strictFloat("3.14PI"); // \TypeError

Return Type Hints

在PHP 7,我们除了可以type hint函数参数之外,还可以type hint函数的返回值,像下面这样:

<?php

function divisible(int $dividend, int $divider): int {
return $dividend / $divider;
} divisible(6, 3);
divisible(6, 4);

Return type hints对类型的处理,和参数使用的规则是相同的。默认采用coersive type,当开启strict type之后,不满足约定的类型将会导致\TypeError异常。

原文:
https://segmentfault.com/a/1190000004150197

上手并过渡到PHP7(2)——必须传递int, string, bool参数?没问题的更多相关文章

  1. 上手并过渡到PHP7(4)——取代fatal error的engine exceptions

    上手并过渡到PHP7 取代fatal error的engine exceptions 泊学原文链接泊学代码秀视频 自从PHP 4以来,PHP的错误处理几乎就是一成不变的.只不过在PHP 5.0里添加了 ...

  2. 上手并过渡到PHP7(1)——基于Homestead的PHP7和XDdebug环境

    PHP7 up and running 泊学实操视频泊学原文链接PHP7, Xdebug and Homestead 在经历了13个RC版本之后,PHP 7终于来了.在我们上手评估PHP 7的新特性之 ...

  3. 上手并过渡到PHP7(3)——Uniform Variable Syntax到底统一了什么

    PHP7 up and running 泊学原文链接泊学实操视频 Uniform Variable Syntax 在PHP 7提出Uniform Variable Syntax之前,我们大多数人可能都 ...

  4. 上手并过渡到PHP7(5)——轻量级“集合”迭代器-Generator

    轻量级“集合”迭代器-Generator泊学视频链接泊阅文档链接Generator是PHP 5.5加入的新语言特性.但是,它似乎并没有被很多PHP开发者广泛采用.因此,在我们了解PHP 7对Gener ...

  5. Android java传递int类型数组给C

    接着前面的文章<Android java传递int类型数据给C><Android java传递string类型数据给C>,继续实践 实现public native int[] ...

  6. Android java传递int类型数据给C

    本文根据<Android jni简便开发流程>中的开发流程来实现一个java传递int类型数据给C 新建项目,进行简单的布局 <LinearLayout xmlns:android= ...

  7. Spring MVC如何接收浏览器传递来的请求参数--request--形参--实体类封装

    阅读目录 1. 通过HttpServletRequest获得请求参数和数据 2. 处理方法形参名==请求参数名 3. 如果形参名跟请求参数名不一样怎么办呢?用@RequestParam注解 4. 用实 ...

  8. 0056 Spring MVC如何接收浏览器传递来的请求参数--request--形参--实体类封装

    浏览器总会向服务器传递一些参数,那么Spring MVC如何接收这些参数? 先写个简单的html,向服务器传递一些书籍信息,如下: <!DOCTYPE html> <html> ...

  9. Shell脚本传递带有空格的参数[摘录自网络]

    参数处理 说明 $# 传递到脚本的参数个数 $* 以一个单字符串显示所有向脚本传递的参数 $$ 脚本运行的当前进程ID号 $! 后台运行的最后一个进程的ID号 $@ 与$#相同,但是使用时加引号,并在 ...

随机推荐

  1. iOS - UIMenuController

    前言 NS_CLASS_AVAILABLE_IOS(3_0) __TVOS_PROHIBITED @interface UIMenuController : NSObject 1.UIMenuCont ...

  2. KASAN实现原理

    1. 前言 KASAN是一个动态检测内存错误的工具.KASAN可以检测全局变量.栈.堆分配的内存发生越界访问等问题.功能比SLUB DEBUG功能齐全并且支持实时检测.越界访问的严重性和危害性通过我之 ...

  3. 获取Android运行apk的packagename 和activityname

    自动化测试中经常遇到这个问题,关于这个题目,方法众多,咱的目的是找个比较简单靠谱的: 方法一: 先进入cmd窗口,adb shell 后: cd /data/data ls 可以看到包名了吧,缺点很明 ...

  4. js判断字符串str是否包含字符串substr

    js判断字符串str是否包含字符串substr: function addUser(id,realName){ var userids = $("#userids").val(); ...

  5. linux系统下添加新硬盘的方法详解

    对于linux新手来说,在linux上添加新硬盘,是很有挑战性的一项工作. 在Linux服务器上把硬盘接好,启动linux,以root登陆. fdisk -l ## 这里是查看目前系统上有几块硬盘 D ...

  6. .NET执行SQL插入时间的问题

    错误描述: 一个项目,源码是BOSS给的,部署到网上了,运行没有问题,可是在本地运行,就会有问题,问题在于往一些表插入记录的时候,本地不管怎么样都插入不了,而网上就可以插入,都是相同的一份代码 解决: ...

  7. modelsim与debussy联调环境的搭建

    为了方便查看波形,找来了一款软件——debussy,它的一个优点是任你查看设计内信号,只需一个波形文件,如FSDB文件.而不用像modelsim那样想看某些信号,添加了之后还要重新编译仿真,浪费了很多 ...

  8. win常用

    //base.Invoke((MethodInvoker)delegate() //{ // this.Close(); //});

  9. C++windows内核编程笔记day13 进程、线程与信号量

    Windows进程 进程是一个容器,包括程序运行须要的代码.数据.资源等信息, windows进程的特点: 每一个进程都有自己的ID号 每一个进程都有自己的地址空间.进程之间无法訪问对方的地址空间. ...

  10. if else 的或(||)

    = "node01" ]; then ssh -p2222 root@.xx.xx.xxx else echo "hello world" #当$=='node ...