我在PHP 7中看到了下面的新行,但没有人真正解释它的含义。我在谷歌上搜索过,他们谈论的都是你是否会启用它,就像一个投票类型的东西。
declare(strict_types = 1);
它能做什么?它如何影响我的代码?我应该这么做吗?
解释一下就好了。
我在PHP 7中看到了下面的新行,但没有人真正解释它的含义。我在谷歌上搜索过,他们谈论的都是你是否会启用它,就像一个投票类型的东西。
declare(strict_types = 1);
它能做什么?它如何影响我的代码?我应该这么做吗?
解释一下就好了。
当前回答
摘自Treehouse博客:
With PHP 7 we now have added Scalar types. Specifically: int, float, string, and bool. By adding scalar type hints and enabling strict requirements, it is hoped that more correct and self-documenting PHP programs can be written. It also gives you more control over your code and can make the code easier to read. By default, scalar type-declarations are non-strict, which means they will attempt to change the original type to match the type specified by the type-declaration. In other words, if you pass a string that starts with a number into a function that requires a float, it will grab the number from the beginning and remove everything else. Passing a float into a function that requires an int will become int(1).
默认情况下,如果可能的话,PHP将把错误类型的值转换为预期的标量类型。例如,如果函数的形参为整数,而该形参期望为字符串,则该函数将获得一个字符串类型的变量。
禁用严格类型(eval):
<?php
function AddIntAndFloat(int $a, float $b) : int
{
return $a + $b;
}
echo AddIntAndFloat(1.4, '2');
/*
* without strict typing, PHP will change float(1.4) to int(1)
* and string('2') to float(2.0) and returns int(3)
*/
可以在每个文件的基础上启用严格模式。在严格模式下,只有类型声明的确切类型的变量将被接受,否则将抛出TypeError。该规则的唯一例外是,可以将整数赋给期望浮点数的函数。从内部函数内部进行的函数调用不会受到strict_types声明的影响。
要启用严格模式,declare语句与strict_types声明一起使用:
启用严格类型(eval):
<?php declare(strict_types=1);
function AddIntAndFloat(int $a, float $b): int
{
return (string) $a + $b;
}
echo AddIntAndFloat(1.4,'2');
// Fatal error: Uncaught TypeError: Argument 1 passed to AddIntAndFloat() must be of the type int, float given
echo AddIntAndFloat(1,'2');
// Fatal error: Uncaught TypeError: Argument 2 passed to AddIntAndFloat() must be of the type float, string given
// Integers can be passed as float-points :
echo AddIntAndFloat(1,1);
// Fatal error: Uncaught TypeError: Return value of AddIntAndFloat() must be of the type integer, string returned
工作的例子:
<?php
declare(strict_types=1);
function AddFloats(float $a, float $b) : float
{
return $a+$b;
}
$float = AddFloats(1.5,2.0); // Returns 3.5
function AddFloatsReturnInt(float $a, float $b) : int
{
return (int) $a+$b;
}
$int = AddFloatsReturnInt($float,1.5); // Returns 5
function Say(string $message): void // As in PHP 7.2
{
echo $message;
}
Say('Hello, World!'); // Prints "Hello, World!"
function ArrayToStdClass(array $array): stdClass
{
return (object) $array;
}
$object = ArrayToStdClass(['name' => 'azjezz','age' => 100]); // returns an stdClass
function StdClassToArray(stdClass $object): array
{
return (array) $object;
}
$array = StdClassToArray($object); // Returns array
function ArrayToObject(array $array): object // As of PHP 7.2
{
return new ArrayObject($array);
}
function ObjectToArray(ArrayObject $object): array
{
return $object->getArrayCopy();
}
var_dump( ObjectToArray( ArrayToObject( [1 => 'a' ] ) ) ); // array(1 => 'a');
其他回答
简短的回答
方法参数或类属性中的类型提示非常有用,它可以帮助您在运行代码之前捕获类型错误。 基于类的类型提示从PHP 5起就开始工作了,但是基元提示是相当新的。当将非预期类型传递给函数时,PHP将尝试自动将值转换为预期类型。如果已经声明了strict_types,那么PHP将抛出异常。
长回答
使用declare(strict_types=1)将告诉PHP在尝试(意外地)强制转换原语值时抛出类型错误。看一下这个没有严格类型声明的例子。
function dump(int $value): void
{
var_dump($value);
}
dump('13.37');
dump(19.42);
运行此脚本的结果如下所示:
int(13)
int(19)
您会注意到,即使我们在函数调用中给了它一个字符串,dump函数仍然期望整数。如果您尝试这样做,编辑器可能会调用您,但它仍然是有效的PHP代码。
为原语值启用严格类型非常简单,只需在PHP文件顶部添加一条语句即可。下面是上面添加了声明的示例。
declare(strict_types=1)
function dump(int $value): void
{
var_dump($value);
}
dump('13.37');
dump(19.42);
使用声明运行此脚本将导致以下错误:
Fatal error: Uncaught TypeError: dump(): Argument #1 ($value) must be of type int, string given, called in /Users/rienvanvelzen/Desktop/demo.php on line 10 and defined in /Users/rienvanvelzen/Desktop/demo.php:5
Stack trace:
#0 /Users/rienvanvelzen/Desktop/demo.php(10): dump('13.37')
#1 {main}
thrown in /Users/rienvanvelzen/Desktop/demo.php on line 5
使用strict_type声明可以通过限制PHP自动转换原语值来帮助您尽早捕获错误。当您开始使用它时,它可能有点令人生畏,因为您需要从一开始就正确地定义所有内容。
来源:declare(strict_types=1)在PHP中的工作方式
Strict_types影响类型强制转换。
使用类型提示而不使用strict_types可能会导致微妙的错误。
在严格类型之前,int $x意味着“$x必须具有可强制为int的值”。任何可以被强制转换为int类型的值都会传递类型提示,包括:
整数(242), 浮动(10.17), bool (true), 空,或 有前导数字的字符串(“13个幽灵”)。
通过设置strict_types=1,您告诉引擎int $x意味着“$x只能是int型,不允许类型强制转换”。你有很大的保证,你得到的是准确的,只有给予的,没有任何转换和潜在的损失。
例子:
<?php
function get_quantity(): int {
return '100 apples';
}
echo get_quantity() . PHP_EOL;
产生一个可能令人困惑的结果:
Notice: A non well formed numeric value encountered in /Users/bishop/tmp/pmkr-994/junk.php on line 4
100
我认为,大多数开发人员都认为int型暗示意味着“仅是int型”。但它不是,它的意思是“任何像int型的东西”。启用strict_types会给出可能的预期和期望的行为:
<?php declare(strict_types=1);
function get_quantity(): int {
return '100 apples';
}
echo get_quantity() . PHP_EOL;
收益率:
Fatal error: Uncaught TypeError: Return value of get_quantity() must be of the type int, string returned in example.php:4
如果你使用类型提示,我认为这里有两个教训:
始终使用strict_types=1。 将通知转换为异常,以防您忘记添加strict_types pragma。
摘自Treehouse博客:
With PHP 7 we now have added Scalar types. Specifically: int, float, string, and bool. By adding scalar type hints and enabling strict requirements, it is hoped that more correct and self-documenting PHP programs can be written. It also gives you more control over your code and can make the code easier to read. By default, scalar type-declarations are non-strict, which means they will attempt to change the original type to match the type specified by the type-declaration. In other words, if you pass a string that starts with a number into a function that requires a float, it will grab the number from the beginning and remove everything else. Passing a float into a function that requires an int will become int(1).
默认情况下,如果可能的话,PHP将把错误类型的值转换为预期的标量类型。例如,如果函数的形参为整数,而该形参期望为字符串,则该函数将获得一个字符串类型的变量。
禁用严格类型(eval):
<?php
function AddIntAndFloat(int $a, float $b) : int
{
return $a + $b;
}
echo AddIntAndFloat(1.4, '2');
/*
* without strict typing, PHP will change float(1.4) to int(1)
* and string('2') to float(2.0) and returns int(3)
*/
可以在每个文件的基础上启用严格模式。在严格模式下,只有类型声明的确切类型的变量将被接受,否则将抛出TypeError。该规则的唯一例外是,可以将整数赋给期望浮点数的函数。从内部函数内部进行的函数调用不会受到strict_types声明的影响。
要启用严格模式,declare语句与strict_types声明一起使用:
启用严格类型(eval):
<?php declare(strict_types=1);
function AddIntAndFloat(int $a, float $b): int
{
return (string) $a + $b;
}
echo AddIntAndFloat(1.4,'2');
// Fatal error: Uncaught TypeError: Argument 1 passed to AddIntAndFloat() must be of the type int, float given
echo AddIntAndFloat(1,'2');
// Fatal error: Uncaught TypeError: Argument 2 passed to AddIntAndFloat() must be of the type float, string given
// Integers can be passed as float-points :
echo AddIntAndFloat(1,1);
// Fatal error: Uncaught TypeError: Return value of AddIntAndFloat() must be of the type integer, string returned
工作的例子:
<?php
declare(strict_types=1);
function AddFloats(float $a, float $b) : float
{
return $a+$b;
}
$float = AddFloats(1.5,2.0); // Returns 3.5
function AddFloatsReturnInt(float $a, float $b) : int
{
return (int) $a+$b;
}
$int = AddFloatsReturnInt($float,1.5); // Returns 5
function Say(string $message): void // As in PHP 7.2
{
echo $message;
}
Say('Hello, World!'); // Prints "Hello, World!"
function ArrayToStdClass(array $array): stdClass
{
return (object) $array;
}
$object = ArrayToStdClass(['name' => 'azjezz','age' => 100]); // returns an stdClass
function StdClassToArray(stdClass $object): array
{
return (array) $object;
}
$array = StdClassToArray($object); // Returns array
function ArrayToObject(array $array): object // As of PHP 7.2
{
return new ArrayObject($array);
}
function ObjectToArray(ArrayObject $object): array
{
return $object->getArrayCopy();
}
var_dump( ObjectToArray( ArrayToObject( [1 => 'a' ] ) ) ); // array(1 => 'a');