PHP的types – 提示原始值?

我想知道是否可以键入提示一种方法来期望原始types?

像这样的东西:

public function someMethod(string $str) //^^^^^^ 

要么:

 private function anotherMethod(int $num) //^^^ 

您将以同样的方式:

 private function otherMethod(Person $rambo) //^^^^^^ 

这是可能的PHP?

在PHP 7中,他们添加了以下内容:

types声明允许函数在通话时要求参数具有某种types。 如果给定的值是不正确的types,那么会产生一个错误:在PHP 5中,这将是一个可恢复的致命错误,而PHP 7将抛出一个TypeErrorexception。

参考: http : //php.net/manual/en/functions.arguments.php#functions.arguments.type-declaration


当这个答案被问到,PHP 5是最新的,并说:

PHP 5引入了types提示。 函数现在可以强制参数成为对象(通过在函数原型中指定类的名称),接口,数组(自PHP 5.1起)或可调用(自PHP 5.4起) 。 但是,如果将NULL用作默认参数值,则可以将其作为任何稍后调用的参数。

如果类或接口被指定为types提示,那么它的所有子节点或实现也被允许。

types提示不能与标量types(如int或string)一起使用。 资源和特性也是不允许的。

参考: http : //php.net/manual/en/language.oop5.typehinting.php

不。 您不能为原语键入提示,因为PHP对原语有自动转换。 请参阅http://bugs.php.net/bug.php?id=29508 。 这绝不会改变,除非PHP团队突然改变了心(这是值得怀疑的,他们非常固执)。

是的,现在是可能的,经过长时间的讨论,一个提议实现了标量函数参数和返回值的types提示,刚刚获得了最高票数的批准,请查看细节:

标量types提示包括声明函数参数的types和返回值,可以是int,float,string和booltypes。这允许PHP运行时引擎检查传递给参数函数和返回值的值的types是预期的types,以检测最终的编程错误。 在过去的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 

你也可以select在源文件中声明Scalertypes提示。它必须是configuration脚本的第一行,不能在同一个文件的其他地方声明。

 Like : declare(strict_types=1); 

在运行时,当PHP引擎试图返回一个值时,它将检查是否与声明不匹配,这将引发致命错误,如致命错误:传递给increment()的参数1必须是integertypes的string

通过声明的这些新特性,您可以通过检测将错误types的值传递给函数而导致的早期编程错误,编写更强大的应用程序。

types的自动更改也可能发生。 例如,inttypes可以自动更改为floattypes的参数,

 function test(float $x){ var_dump($x); } test(10); // works fine 

声明返回types

我们可以声明返回types添加一个冒号,然后是函数声明中最后一个括号和第一个括号之间的期望types。

对于不返回任何值的函数,不应该在返回types声明部分添加任何内容。

 function mustReturnInt(): int { ... } function mustReturnString(): string { ... } function mustReturnBool(): bool { ... } function mustReturnFloat(): float { ... } function doesNotReturnAnything() { ... } 

一点点更复杂的例子

 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"); 

弱types检查和types转换的行为:弱types检查模式可以使用语句declare(strict_types = 0); 或没有严格的types声明。 有几点需要考虑:对扩展或内置PHP函数的弱types检查调用与以前的PHP版本具有相同的行为新的标量types声明的弱types检查规则大部分与扩展或内置的PHPfunction。 为了与类,可调用数组和数组的当前types声明保持一致,NULL是一种特殊情况。 除非它是一个参数,并且被显式地赋予一个默认值NULL,否则默认情况下不接受NULL,例如:function sample(int $ a = NULL);

这种方法有很多优点。 你得到types安全。 这意味着你可以最终静态分析代码! 您可以检测到意外从一个函数中获取string并将其作为整数传递给另一个函数的错误。对于我来说,一个每天使用PHP的开发人员将Java视为OOP语言的参考,这对于PHP 。

大家已经说过了,你不能为原语input提示,因为PHP不支持它。 这背后的原因不仅与自动转换有关,还与社区反应有关。

到目前为止,我还记得2010年5月,对PHP中继添加了对标量types提示的支持。 但是由于社区的反应,这个function并没有进入5.4版本。

对此有一些争议。 那些反对这一改变的人认为,这种支持将违背PHP的基本devise。 PHP被认为是一种弱types语言。 实质上,这意味着PHP不要求你声明数据types。 variables仍然有与之相关的数据types,但是你可以做一些激进的事情,比如把一个string添加到一个整数而不会导致错误。

恕我直言:标量types提示应该被添加到PHP ASAP中,这是我们都需要的一个特性,我真的很尊重PHP是弱types语言,但是对于高端开发和生产,特别是在OO上下文中,标量types提示是必须的。 我们可以在PHP中有两种select,就像程序和OO一样。

对的,这是可能的。

http://ru2.php.net/manual/ru/language.oop5.typehinting.php#83442

警告:原始手册中存在拼写错误:资源而不是资源

人们经常会问标量/基本types的提示。 这里是我在我的MVC框架中使用的一个类,它将通过使用自定义error handling程序来启用types提示。

注意:你应该把这个代码包含在include头文件中的所有其他代码的上面,如果你使用的是set_error_handler()函数,你应该知道它也使用它。 你可能需要链接你的set_error_handlers()

为什么?

  1. 因为人们厌倦了使用is_ *函数来validation参数。
  2. 减less防御性编码器的冗余编码。
  3. function/方法是自定义/logging所需的input。

另请参阅PHP Internals板上的PHP 6.0中的typehints的讨论。

 <?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. ?> 

你明白了

基本types不支持符合PHP文档types提示。

尽pipe它支持类和接口。

编辑:我忘了提及,也支持数组。

下面是从传入的参数中强制布尔值的简短语法。 如果$state为true,那么$this->is_active设置为true。 对于所有其他types的值,它被设置为false。

 function set_active ( $state ) { $this->is_active = true === $state; } 

我想你不需要为PHP提供types提示,因为你有types检查函数,比如is_bool(),is_string()等等,所以你可以在实际制作之前检查你试图把这些函数放进一个参数一个参数,虽然他们用来检查数组和对象types的方法会更干净。