PHP 类型提示原始值?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/5724677/
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
PHP type-hinting to primitive values?
提问by Felipe Almeida
I'd like to know whether one can type-hint a method to expect primitive types?
我想知道是否可以对一种方法进行类型提示以期待原始类型?
Something like this:
像这样的东西:
public function someMethod(string $str)
//^^^^^^
Or:
或者:
private function anotherMethod(int $num)
//^^^
the same way you would:
和你一样:
private function otherMethod(Person $rambo)
//^^^^^^
Is that possible in php?
这在php中可能吗?
回答by afuzzyllama
In PHP 7 they added the following:
在 PHP 7 中,他们添加了以下内容:
Type declarations allow functions to require that parameters are of a certain type at call time. If the given value is of the incorrect type, then an error is generated: in PHP 5, this will be a recoverable fatal error, while PHP 7 will throw a TypeError exception.
类型声明允许函数在调用时要求参数为特定类型。如果给定值的类型不正确,则会生成错误:在 PHP 5 中,这将是一个可恢复的致命错误,而 PHP 7 将抛出 TypeError 异常。
Reference: http://php.net/manual/en/functions.arguments.php#functions.arguments.type-declaration
参考:http: //php.net/manual/en/functions.arguments.php#functions.arguments.type-declaration
When this answer was asked, PHP 5 was the latest and said the following:
当这个答案被问到时,PHP 5 是最新的,并说如下:
PHP 5 introduces type hinting. Functions are now able to force parameters to be objects (by specifying the name of the class in the function prototype), interfaces, arrays (since PHP 5.1) or callable (since PHP 5.4). However, if NULL is used as the default parameter value, it will be allowed as an argument for any later call.
If class or interface is specified as type hint then all its children or implementations are allowed too.
Type hints cannot be used with scalar types such as int or string.Resources and Traits are not allowed either.
PHP 5 引入了类型提示。函数现在能够强制参数为对象(通过在函数原型中指定类的名称)、接口、数组(自 PHP 5.1 起)或可调用(自 PHP 5.4 起)。但是,如果将 NULL 用作默认参数值,则将允许将其作为任何后续调用的参数。
如果将类或接口指定为类型提示,则也允许其所有子项或实现。
类型提示不能用于标量类型,例如 int 或 string。资源和特征也是不允许的。
Reference: http://php.net/manual/en/language.oop5.typehinting.php
回答by Rafe Kettler
Nope. You can't type hint for primitives because PHP has automatic conversions for primitives. See http://bugs.php.net/bug.php?id=29508. This will never change, unless the PHP team has a sudden change of heart (which is doubtful, they're pretty stubborn).
不。您不能为基元键入提示,因为 PHP 具有基元的自动转换。请参阅http://bugs.php.net/bug.php?id=29508。这永远不会改变,除非 PHP 团队突然改变主意(这是值得怀疑的,他们非常固执)。
回答by Purushottam
Yes, Now its possible, After a long discussion, a proposal to implement type hinting for scalar function parameters and return values was just approved with the highest vote count so far, check for details :
是的,现在有可能,经过长时间的讨论,一项为标量函数参数和返回值实现类型提示的提案刚刚获得批准,目前投票数最高,请查看详细信息:
Scalar type hinting consists of declaring the types of function parameters and return values that can be of the types int, float, string and bool.This allows the PHP runtime engine to check if the types of values passed to parameter functions and return values are of the expected types in order to detect eventual programming mistakes. Type hinting for objects, arrays and callables was already allowed in past PHP versions. The current implementation introduces five new reserved words: int, float, bool, string and numeric. These were not previously reserved, because casting is a special case in the lexer.
标量类型提示包括声明函数参数和返回值的类型,这些类型可以是 int、float、string 和 bool 类型。这允许 PHP 运行时引擎检查传递给参数函数和返回值的值类型是否属于预期的类型,以便检测最终的编程错误。在过去的 PHP 版本中已经允许对象、数组和可调用对象的类型提示。当前的实现引入了五个新的保留字:int、float、bool、string 和 numeric。这些以前没有保留,因为转换是词法分析器中的特殊情况。
Example :
function test(float $a) {
var_dump($a);
}
test(1); // float(1)
test("1"); // float(1)
test(1.0); // float(1)
test("1a"); // E_RECOVERABLE_ERROR
test("a"); // E_RECOVERABLE_ERROR
test(""); // E_RECOVERABLE_ERROR
test(1.5); // float(1.5)
test(array()); // E_RECOVERABLE_ERROR
test(new StdClass); // E_RECOVERABLE_ERROR
You have also an option to declare into source file where you can allow Scaler type hinting.It must be 1st line of your config script and can't be declared elsewhere in the same file.
您还可以选择在源文件中声明,您可以在其中允许 Scaler 类型提示。它必须是配置脚本的第一行,并且不能在同一文件中的其他地方声明。
Like : declare(strict_types=1);
At runtime, when the PHP engine tries to return a value, it will check if doesn't match as declared it will throw a fatal error like, Fatal error: Argument 1 passed to increment() must be of the type integer, string given
在运行时,当 PHP 引擎尝试返回一个值时,它会检查是否与声明的不匹配,它会抛出一个致命错误,例如致命错误:传递给 increment() 的参数 1 必须是整数类型,给出的字符串
With this new features of declaration, you can write more robust applications by detecting early programming mistakes caused by passing values of the wrong types to functions.
使用这个新的声明特性,您可以通过检测由于将错误类型的值传递给函数而导致的早期编程错误来编写更健壮的应用程序。
Automatic changes of types may also happen. For example, int types can be change into float type parameters automatically,
也可能发生类型的自动更改。例如,int 类型可以自动转换为 float 类型参数,
function test(float $x){
var_dump($x);
}
test(10); // works fine
Declaring the Return Type
声明返回类型
We can declare the return types adding a colon followed by the expected type between the last parenthesis and the first bracket in the function declaration.
我们可以在函数声明中的最后一个括号和第一个括号之间添加一个冒号,后跟预期类型来声明返回类型。
For functions that do not return any value, nothing should be added in the return type declaration section.
对于不返回任何值的函数,不应在返回类型声明部分添加任何内容。
function mustReturnInt(): int { ... }
function mustReturnString(): string { ... }
function mustReturnBool(): bool { ... }
function mustReturnFloat(): float { ... }
function doesNotReturnAnything() { ... }
A Little Bit more Complex Example
稍微复杂一点的例子
declare(strict_types=1);
class StrictTypesTestingClass {
public function returnSameInt(int $value): int { return $value; }
public function returnSameFloat(float $value): float { return $value; }
public function returnSameString(string $value): string { return $value; }
public function returnSameBool(bool $value): bool { return $value; } }
$check = new StrictTypesTestingClass(); // calls that work print $check->returnSameInt(10);
print $check->returnSameFloat(10.0);
print $check->returnSameString("test");
print $check->returnSameBool(true) ? 'true' : 'false'; // calls that throw exceptions
print $check->returnSameInt("10");
print $check->returnSameFloat("10.0");
print $check->returnSameString(10);
print $check->returnSameBool("true");
Behavior of Weak Type Checking and Type Conversion : The weak type checking mode can be used with the statement declare(strict_types=0); or the absence of the strict types declaration. There are a few of points to take into account: Weak type checked calls to an extension or built-in PHP function have the same behaviour as in previous PHP versions The weak type checking rules for new scalar type declarations are mostly the same as those of extension or built-in PHP functions. NULL is a special case in order to be consistent with the current type declarations for classes, callables and arrays. NULL is not accepted by default, unless it is a parameter and is explicitly given a default value of NULL, for instance: function sample(int $a = NULL);
弱类型检查和类型转换的行为:弱类型检查模式可以与语句 declare(strict_types=0) 一起使用;或者没有严格类型声明。有几点需要考虑: 对扩展或内置 PHP 函数的弱类型检查调用与以前的 PHP 版本具有相同的行为 新标量类型声明的弱类型检查规则与扩展或内置 PHP 函数。NULL 是一种特殊情况,以便与类、可调用对象和数组的当前类型声明保持一致。默认情况下不接受 NULL,除非它是一个参数并且明确给出了 NULL 的默认值,例如: function sample(int $a = NULL);
There are a lots of advantages to this approach. You get type safety. Which means that you can finally statically analyze code! You can detect bugs where you accidentally take a string from one function and pass it as an integer to another.For me, a developer that uses PHP on a daily basis and sees Java as a reference for OOP languages, this is great progress for PHP.
这种方法有很多优点。你得到类型安全。这意味着您终于可以静态分析代码了!你可以检测到你不小心从一个函数中取出一个字符串并将它作为整数传递给另一个函数的错误。 .
回答by TCB13
Everyone already said it, you can't do type hint for primitives because PHP doest not support it. The reason behind this is not only related to automatic conversions but also to community reaction.
每个人都已经说过,您不能对原语进行类型提示,因为 PHP 不支持它。这背后的原因不仅与自动转换有关,也与社区反应有关。
So far, I can remember that in May of 2010 support for scalar type hinting was added to the PHP trunk. But because of community response this feature didn't make it into the 5.4 release.
到目前为止,我记得在 2010 年 5 月,对标量类型提示的支持被添加到 PHP 主干中。但是由于社区的反应,此功能没有包含在 5.4 版本中。
There was a bit of controversy about this. Those who opposed the change argued that this support would go against the fundamental designs of PHP. PHP is considered to be a weak typed language. In essence, this means that PHP does not require you to declare data types. Variables still have data types associated with them but you can do radical things like adding a string to an integer without resulting in an error.
这件事引起了一些争议。那些反对改变的人认为这种支持会违背 PHP 的基本设计。PHP 被认为是一种弱类型语言。本质上,这意味着 PHP 不需要您声明数据类型。变量仍然具有与其关联的数据类型,但您可以做一些激进的事情,例如将字符串添加到整数而不会导致错误。
IMHO:Scalar type hinting should be added into PHP ASAP, it's a feature we all need, I really respect that PHP is weak typed language, but for high end development and production, specially on OO contexts, scalar type hinting is a must have. We can have both alternatives in PHP, just like procedural and OO.
恕我直言:标量类型提示应该尽快添加到 PHP 中,这是我们都需要的功能,我真的很尊重 PHP 是弱类型语言,但是对于高端开发和生产,特别是在 OO 上下文中,标量类型提示是必须的。我们可以在 PHP 中同时拥有这两种选择,就像过程式和 OO 一样。
回答by Sergii Smirnov
Yes, it is possible.
对的,这是可能的。
http://ru2.php.net/manual/ru/language.oop5.typehinting.php#83442
http://ru2.php.net/manual/ru/language.oop5.typehinting.php#83442
Warning:there is a typo in original manual: resrouce instead of resource
警告:原始手册中有一个错字:res rouce 而不是 res ource
People often ask about scalar/basic typehints. Here is a drop in class that I use in my MVC framework that will enable typehints through the use of a custom error handler.
人们经常询问标量/基本类型提示。这是我在 MVC 框架中使用的一个类,它将通过使用自定义错误处理程序启用类型提示。
Note: You should include this code above all other code in your include headers and if you are the using set_error_handler() function you should be aware that this uses it as well. You may need to chain your set_error_handlers()
注意:您应该将此代码包含在包含标头中的所有其他代码之上,如果您正在使用 set_error_handler() 函数,您应该知道这也使用它。您可能需要链接您的 set_error_handlers()
Why?
为什么?
- Because people are sick of using the is_* functions to validate parameters.
- Reduction of redundant coding for defensive coders.
- Functions/Methods are self defining/documenting as to required input.
- 因为人们厌倦了使用 is_* 函数来验证参数。
- 减少防御性编码器的冗余编码。
- 功能/方法是关于所需输入的自我定义/记录。
Also.. Follow the discussion for typehints in PHP 6.0 on the PHP Internals boards.
另外.. 在 PHP Internals 板上关注 PHP 6.0 中的类型提示的讨论。
<?php
define('TYPEHINT_PCRE', '/^Argument (\d)+ passed to (?:(\w+)::)?(\w+)\(\) must be an instance of (\w+), (\w+) given/');
class Typehint
{
private static $Typehints = array(
'boolean' => 'is_bool',
'integer' => 'is_int',
'float' => 'is_float',
'string' => 'is_string',
'resource' => 'is_resource'
);
private function __Constrct() {}
public static function initializeHandler()
{
set_error_handler('Typehint::handleTypehint');
return TRUE;
}
private static function getTypehintedArgument($ThBackTrace, $ThFunction, $ThArgIndex, &$ThArgValue)
{
foreach ($ThBackTrace as $ThTrace)
{
// Match the function; Note we could do more defensive error checking.
if (isset($ThTrace['function']) && $ThTrace['function'] == $ThFunction)
{
$ThArgValue = $ThTrace['args'][$ThArgIndex - 1];
return TRUE;
}
}
return FALSE;
}
public static function handleTypehint($ErrLevel, $ErrMessage)
{
if ($ErrLevel == E_RECOVERABLE_ERROR)
{
if (preg_match(TYPEHINT_PCRE, $ErrMessage, $ErrMatches))
{
list($ErrMatch, $ThArgIndex, $ThClass, $ThFunction, $ThHint, $ThType) = $ErrMatches;
if (isset(self::$Typehints[$ThHint]))
{
$ThBacktrace = debug_backtrace();
$ThArgValue = NULL;
if (self::getTypehintedArgument($ThBacktrace, $ThFunction, $ThArgIndex, $ThArgValue))
{
if (call_user_func(self::$Typehints[$ThHint], $ThArgValue))
{
return TRUE;
}
}
}
}
}
return FALSE;
}
}
Typehint::initializeHandler();
?>
An are some examples of the class in use:
<?php
function teststring(string $string) { echo $string; }
function testinteger(integer $integer) { echo $integer; }
function testfloat(float $float) { echo $float; }
// This will work for class methods as well.
?>
You get the picture..
你看图。。
回答by Luc M
Accordind to PHP documentationtype hinting is not supported for primitive types.
根据 PHP 文档,原始类型不支持类型提示。
It's supported for classes and interfaces though.
虽然它支持类和接口。
Edit: I forgot to mention that's also supported for arrays.
编辑:我忘了提到数组也支持。
回答by Lee Blue
Here is short syntax for forcing a boolean value out of a passed in parameter. If $state
is true, then $this->is_active
is set to true. For all other types of values it is set to false.
下面是从传入的参数中强制布尔值的简短语法。如果$state
为真,则$this->is_active
设置为真。对于所有其他类型的值,它被设置为 false。
function set_active ( $state ) {
$this->is_active = true === $state;
}
回答by Carwyn Stephen
I guess you don't need type hinting for PHP because you're given type checking functions such as is_bool(), is_string() etc etc, so you could check whatever your trying to put into an argument against these functions before actually making it an argument, although the method they use to check array and object types would be much cleaner.
我猜你不需要 PHP 的类型提示,因为你得到了类型检查函数,比如 is_bool()、is_string() 等,所以你可以在实际制作之前检查你试图放入这些函数的参数中的任何内容一个参数,尽管他们用来检查数组和对象类型的方法会更清晰。