不论从事什么行业,当初都是活到老学到老的趋势,特地是咱们这堆码农。这回也不用说新技术用不上,光光是 PHP 文档的学习都会发现十分多的知识点其实本人并没有真正的把握,比如说这个办法参数的类型申明。上次文章中,对于 PHP 的办法参数类型束缚,咱们说过办法参数的类型束缚仅限于类、接口、数组或者 callable 回调函数,其实这是不谨严的,PHP 中也有一个严格模式的定义,如果指定了严格模式的话,一般的为办法参数类型指定一般的标量类型也是有成果的。
严格模式的定义:
declare (strict_types = 1);
int 类型
function testInt(int $a)
{echo $a, PHP_EOL;}
testInt(1);
// testInt(1.1); // Fatal error: Uncaught TypeError: Argument 1 passed to testInt() must be of the type int
// testInt('52AABB'); // Fatal error: Uncaught TypeError: Argument 1 passed to testInt() must be of the type int
// testInt(true); // Fatal error: Uncaught TypeError: Argument 1 passed to testInt() must be of the type int
在严格模式下,很显著地看出当初这个办法的参数只能接管 int 类型的值了,其余的类型都无奈接管,当然也不会像之前文章说过的那样会产生强制转换。
float 类型
function testFloat(float $a)
{echo $a, PHP_EOL;}
testFloat(1);
testFloat(1.1);
// testFloat('52AABB'); // Fatal error: Uncaught TypeError: Argument 1 passed to testInt() must be of the type int
// testInt(true); // Fatal error: Uncaught TypeError: Argument 1 passed to testInt() must be of the type int
这里须要留神的是,PHP 只有 int 和 float,而且 float 是 int 的超集,所以这里是能够传整数过去的,不过下面的 testInt(int $a) 则不能接管 1.1 这样的 float 值。这就波及到了高低转换的问题,向超集转换是 OK 的,然而超集向子集转换是就不 OK 了。
string 类型
function testString(string $a)
{echo $a, PHP_EOL;}
// testString(1); // Fatal error: Uncaught TypeError: Argument 1 passed to testString() must be of the type string
// testString(1.1); // Fatal error: Uncaught TypeError: Argument 1 passed to testString() must be of the type string
testString('52AABB');
// testString(true); // Fatal error: Uncaught TypeError: Argument 1 passed to testString() must be of the type string
这个就不必过多解释了,在非严格模式下咱们如果定义 string 类型的接管参数的话,其实是任何类型都能够接管过去做为 string 类型的,这里的类型转换就不多说了,能够说在非严格模式下定义 string 类型的成果跟没有任何定义是一样的。然而严格模式下就不同了,真的是只能接管双引或者单引号之内的字符串内容。
bool 类型
function testBool(bool $a)
{var_dump($a);
}
testBool(true);
testBool(false);
// testBool('52AABB'); // Fatal error: Uncaught TypeError: Argument 1 passed to testBool() must be of the type bool
// testBool(1); // Fatal error: Uncaught TypeError: Argument 1 passed to testBool() must be of the type bool
布尔值也是同理的,这里咱们也只能接管 true 和 false 关键字的值。
新学习一个 iterable 类型
最初来介绍个新家伙,除了一般模式下的类、数组、回调函数,严格模式下的各种标量类型申明外,还有一个 iterable 类型的申明,置信大家通过这个单词也能看进去了,可迭代的类型。
function testIterable(iterable $iterator)
{echo gettype($iterator), ':', PHP_EOL;
foreach ($iterator as $it) {echo $it, PHP_EOL;}
}
testIterable([1, 2, 3]);
testIterable(new ArrayIterator([1, 2, 3]));
// Generator 对象
testIterable((function () {
yield 1;
yield 2;
yield 3;
})());
// testIterable(1); // Fatal error: Uncaught TypeError: Argument 1 passed to testIterable() must be iterable
没错,它蕴含了数组、实现迭代器接口的类以及生成器相干的内容。也就是所有可用 foreach 迭代的内容都能够传递过去。生成器自身会是一个 Generator 对象,而在学习 PHP 生成器的应用这篇文章中,咱们曾经看过这个 Generator 对象的内容,它自身也是实现了 Iterator 接口。
总结
就像结尾说过的,原来在严格模式下咱们的语法还会有这么大的差别,这回真的是长见识了。咱们的学习之路还很长,也心愿各位可能继续关注一起加油!!
测试代码:
https://github.com/zhangyue0503/dev-blog/blob/master/php/202003/source/%E5%86%8D%E6%AC%A1%E5%AD%A6%E4%B9%A0%E6%96%B9%E6%B3%95%E5%8F%82%E6%95%B0%E7%B1%BB%E5%9E%8B%E5%A3%B0%E6%98%8E.php
参考文档:
《PHP7 编程实战》
https://wiki.php.net/rfc/scalar_type_hints_v5
https://www.php.net/manual/zh/class.generator.php
https://wiki.php.net/rfc/iterable
各自媒体平台均可搜寻【硬核项目经理】