首页 » 网站推广 » php声明即履行技巧_PHP中declarestrict_types 1

php声明即履行技巧_PHP中declarestrict_types 1

访客 2024-12-14 0

扫一扫用手机浏览

文章目录 [+]

PHP中开启严格模式须要在文件最开始添加declare(strict_types = 1),显示声明,PHP默认是弱类型校验,而且该声明仅对当前文件有效,其他文件`include`或`require`时须要重新在那个文件声明。

看几个例子

两个数相加函数:

php声明即履行技巧_PHP中declarestrict_types  1

function foo (int $a, int $b): int { return $a + $b;}var_dump(foo(1.0, 2.5)); // 结果是3var_dump(foo('1', 2)); // 3

在默认若类型下,传过去的float参数被截断成int类型,同样的,字符串在弱模式下也被自动转成了int,再来比拟下严格模式:

php声明即履行技巧_PHP中declarestrict_types  1
(图片来自网络侵删)

declare(strict_types=1);function foo (int $a, int $b): int { return $a + $b;}var_dump(foo(1.0, 2.5)); // 报错var_dump(foo('1', 2)); // 报错// Fatal error: Uncaught TypeError: Argument 1 passed to foo() must be of the type integer, float given, called in /in/JQAi6 on line 10 and defined in /in/JQAi6:6

直接报错了,说foo()只接管int类型,而传过去是float。

弱模式下,返回值类型也会被转换:

function foo (): int { $r = 1.0; return $r;}var_dump(foo()); // 1

严格模式下会报错:

declare(strict_types=1);function foo (): int { $r = 1.0; return $r;}var_dump(foo()); // 报错// Fatal error: Uncaught TypeError: Return value of foo() must be of the type int, float returned in /in/pRWIl:7

# 历史

PHP从PHP5.0开始已经有对支持class和interface参数类型声明,PHP5.1支持array以及PHP5.4支持callable。
这些类型声明让PHP在实行的时候传入精确的参数,让函数署名具有更多的信息。

先前曾经想添加标量类型声明,例如[Scalar Type Hints with Casts](https://wiki.php.net/rfc/scalar_type_hinting_with_cast "rfc:scalar_type_hinting_with_cast") RFC,由于各种缘故原由失落败了:

类型转换和校验机制,对付拓展和PHP内置函数不匹配它遵照一个弱类型方法它的“严格”弱类型修正考试测验,既没有知足严格类型的粉丝期望,也没有知足弱类型的粉丝

这个RFC考试测验办理全部问题。

弱类型和强类型

在当代编程措辞的实际运用中,有三种紧张的方法去检讨参数和返回值的类型:

全严格类型检讨(也便是不会有类型转换发生)。
例如F#、GO、Haskell、Rust和Facebook的Hack的用法广泛原始类型检讨(“安全”的类型转换会发生)。
例如Java、D和Pascal。
他们许可广泛原始类型转换(隐式转换),也便是说,一个8-bit的integer可以根据函数参数须要,被隐形转换为一个16-bit的integer,而且int也可以被转换为float的浮点数。
其他类型的隐式转换则不被许可弱类型检讨(许可所有类型转换,可能会引起警告),它被有限定地利用在C、C#、C++和Visual Basic中。
它们考试测验尽可能“不失落败”,完成一次转换

PHP在zend_parse_parameters的标量内部处理机制是采取了弱类型模式。
PHP的工具处理机制采取了广泛类型检讨办法,并不追求精确匹配和转换。
每个方法各有其优缺陷

这个提案中,默认采取弱类型校验机制,同时追加一个开关,许可转换为广泛类型校验机制(也便是严格类型校验机制)

为什么两者都支持?

目前为止,大部分的标量类型声明的推戴者都哀求同时支持严格类型校验和弱类型校验,并非仅仅支持个中一种。
这份RFC,使得弱类型校验为默认行为,同时,添加一个可选的指令来利用严格类型校验(同一个文件中),在这个选择的背后,有很多个缘故原由。

PHP社区很大一部分人看起来很喜好全静态类型。
但是,添加严格类型校验的标量类型声明将会引起一些问题:

引起明显的不一致性:拓展和PHP内置函数对标量类型参数利用弱类型校验,但是,用户的PHP函数将会利用严格类型校验相称一部分人更喜好弱类型校验,并不赞许这个提案,他们可能会阻挡它的履行已经存在的代码利用了PHP的弱类型,它会受到影响。
如果哀求函数添加标量类型声明到参数上,对付现有的代码库,这将大大增加繁芜性,特殊是对付库文件

这里仍旧有相称于一部分人是喜好弱类型校验的,但是,添加严格类型校验声明和添加弱类型校验声明都会引起一些问题:

大部分方向于严格类型校验的人将不会喜好这个提案,然后阻挡它的履行限定静态解析的机会它会隐蔽一些在类型自动转换中数据丢失的bug

第三种方案被提出来了,便是添加区分弱类型和严格类型声明的语法。
它也会带来一些问题:

不喜好弱类型和严格类型校验的人,会被强制分别处理被定义为严格类型或者弱类型校验的库像添加严格声明一样,这个也将和原来弱类型实现的拓展和PHP内置函数无法保持同等

为理解决这三种方案带来的问题,这个RFC提出了第四种方案:每个文件各自定义严格或者弱类型校验。
它带来了以下好处:

人们可以选择适宜他们的类型校验,也便是说,这个方案希望同时知足严格和弱类型校验两个阵营API不会被逼迫适应某个类型声明模式由于文件默认利用弱类型校验方案,已经存在的代码库,可以在不毁坏代码构造的情形下,添加标量类型声明。
也可以让代码库逐步添加类型声明,或者仅部分模块添加只须要一个单一语法,就可以定义标量类型声明更喜好严格类型校验的人,常日,不仅将这个特性利用在用户定义的函数,同时也利用在拓展和PHP内置函数中。
也便是说,PHP利用者会得到一个统一机制,而不会产生严格标量声明的抵牾在严格类型校验模式下,拓展和PHP内置函数产生的类型校验失落败的缺点级别,和用户自定函数产生的会保持同等,都是E_RECOVERABLE_ERROR它许可严格类型和弱类型代码,在一个单一的代码库中无缝集成
标签:

相关文章

大数据时代,探索常量与变量的奥秘

随着信息技术的飞速发展,大数据已经渗透到社会生活的方方面面。在这个数据爆炸的时代,人们不禁要问:大数据中的常量与变量究竟有何奥秘?...

网站推广 2024-12-16 阅读0 评论0