PHP 中的严格类型有什么作用?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/48723637/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
What do strict types do in PHP?
提问by sufuko
I've seen the following new line in PHP 7, but nobody really explains what it means. I've googled it and all they talk about is will you be enabling it or not like a poll type of thing.
我在 PHP 7 中看到了以下新行,但没有人真正解释它的含义。我在谷歌上搜索过它,他们谈论的只是你是否会启用它,或者不喜欢投票类型的事情。
declare(strict_types = 1);
What does it do? How does it affect my code? Should I do it?
它有什么作用?它如何影响我的代码?我应该这样做吗?
Some explanation would be nice.
一些解释会很好。
回答by saif
From the Treehouse blog:
来自树屋博客:
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 7 中,我们现在添加了标量类型。具体来说:int、float、string 和 bool。
通过添加标量类型提示和启用严格要求,希望可以编写更正确和自文档化的 PHP 程序。它还使您可以更好地控制代码并使代码更易于阅读。
默认情况下,标量类型声明是非严格的,这意味着它们将尝试更改原始类型以匹配类型声明指定的类型。换句话说,如果您将一个以数字开头的字符串传递给需要浮点数的函数,它将从头开始获取数字并删除其他所有内容。将浮点数传递给需要 int 的函数将变为 int(1)。
By default, PHP will cast values of the wrong type into the expected scalar type if possible. For example, a function that is given an integer for a parameter that expects a string will get a variable of type string.
默认情况下,如果可能,PHP 会将错误类型的值转换为预期的标量类型。例如,为期望字符串的参数提供整数的函数将获得字符串类型的变量。
Strict types disabled (eval):
禁用严格类型(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)
*/
It is possible to enable strict mode on a per-file basis. In strict mode, only a variable of exact type of the type declaration will be accepted, or a TypeError will be thrown. The only exception to this rule is that an integer may be given to a function expecting a float. Function calls from within internal functions will not be affected by the strict_types declaration.
可以在每个文件的基础上启用严格模式。在严格模式下,只接受类型声明的确切类型的变量,否则将抛出 TypeError。此规则的唯一例外是整数可能会被赋予需要浮点数的函数。来自内部函数的函数调用不会受到 strict_types 声明的影响。
To enable strict mode, the declare statement is used with the strict_types declaration:
要启用严格模式,将声明语句与 strict_types 声明一起使用:
Strict types enabled (eval):
启用严格类型(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
Working example:
工作示例:
<?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');
回答by bishop
strict_types
affects type coercion.
strict_types
影响类型强制。
Using type hints without strict_types
may lead to subtle bugs.
使用类型提示strict_types
可能会导致细微的错误。
Prior to strict types, int $x
meant "$x
must have a value coercibleto an int." Any value that could be coerced to an int
would pass the type hint, including:
在严格类型之前,int $x
意味着“$x
必须有一个可强制转换为 int的值”。任何可以强制转换为 an 的值int
都会传递类型提示,包括:
- an int proper (
242
), - a float (
10.17
), - a bool (
true
), null
, or- a string with leading digits (
"13 Ghosts"
).
- 一个适当的整数(
242
), - 一个浮点数 (
10.17
), - 一个布尔值 (
true
), null
, 或者- 带有前导数字 (
"13 Ghosts"
)的字符串。
By setting strict_types=1
, you tell the engine that int $x
means "$x must only be an int proper, no type coercion allowed." You have great assurance you're getting exactly and only what was given, without any conversion and potential loss.
通过设置strict_types=1
,你告诉引擎这int $x
意味着“$x 必须是一个正确的 int,不允许类型强制”。您有很大的保证,您得到的只是所提供的,没有任何转换和潜在的损失。
Example:
例子:
<?php
function get_quantity(): int {
return '100 apples';
}
echo get_quantity() . PHP_EOL;
Yields a potentially confusing result:
产生一个可能令人困惑的结果:
Notice: A non well formed numeric value encountered in /Users/bishop/tmp/pmkr-994/junk.php on line 4
100
Most developers would expect, I think, an int
hint to mean "only an int". But it doesn't, it means "anything like an int". Enabling strict_types gives the likely expected and desired behavior:
我认为,大多数开发人员会期望int
暗示“只有一个整数”。但事实并非如此,它的意思是“任何类似 int 的东西”。启用 strict_types 给出了可能的预期和期望的行为:
<?php declare(strict_types=1);
function get_quantity(): int {
return '100 apples';
}
echo get_quantity() . PHP_EOL;
Yields:
产量:
Fatal error: Uncaught TypeError: Return value of get_quantity() must be of the type int, string returned in example.php:4
I think there's two lessons here, if you use type hints:
如果您使用类型提示,我认为这里有两个教训:
- Use
strict_types=1
, always. - Convert notices to exceptions, in case you forget to add the
strict_types
pragma.
strict_types=1
始终使用。- 将通知转换为异常,以防您忘记添加
strict_types
编译指示。