PHP类型提示原始值?

时间:2011-04-20 01:43:59

标签: php primitive-types type-hinting

我想知道是否可以键入提示方法以期望原始类型?

这样的事情:

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

或者:

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

就像你一样:

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

这可能在PHP吗?

8 个答案:

答案 0 :(得分:83)

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

  

类型声明允许函数在调用时要求参数具有某种类型。如果给定值的类型不正确,则会生成错误:在PHP 5中,这将是可恢复的致命错误,而PHP 7将引发TypeError异常。

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


当回答这个问题时,PHP 5是最新的,并说了以下内容:

  

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

     

如果将类或接口指定为类型提示,则也允许其所有子项或实现。

     

类型提示不能与标量类型(如int或string)一起使用。也不允许使用资源和特征。

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

答案 1 :(得分:29)

不。您不能为基元键入提示,因为PHP具有基元的自动转换。见http://bugs.php.net/bug.php?id=29508。这永远不会改变,除非PHP团队突然改变主意(这是令人怀疑的,他们非常顽固)。

答案 2 :(得分:16)

是的,现在它可能, 经过长时间的讨论,到目前为止,批准实施标量函数参数和返回值的类型提示的提议刚刚获得最高票数,请查看详细信息:

标量类型提示包括声明函数参数的类型和返回值,可以是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

您还可以选择在源文件中声明您可以允许Scaler类型提示。它必须是您的配置脚本的第一行,并且不能在同一文件的其他地方声明。

Like : declare(strict_types=1);

在运行时,当PHP引擎尝试返回一个值时,它将检查是否与声明不匹配,它会抛出致命错误,如: 致命错误:传递给increment()的参数1必须是整数类型,给定字符串

通过声明的这一新功能,您可以通过检测将错误类型的值传递给函数所导致的早期编程错误来编写更强大的应用程序。

也可能发生类型的自动更改。例如,int类型可以自动更改为float类型参数,

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

声明返回类型

我们可以声明返回类型,添加冒号,后跟函数声明中最后一个括号和第一个括号之间的预期类型。

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

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

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

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

答案 3 :(得分:5)

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

到目前为止,我记得在2010年5月,PHP主干中添加了对标量类型提示的支持。但是由于社区的反应,这个功能没有进入5.4版本。

对此存在一些争议。那些反对这种变化的人认为这种支持会违背PHP的基本设计。 PHP被认为是弱类型语言。实质上,这意味着PHP不要求您声明数据类型。变量仍然具有与它们相关联的数据类型,但是您可以执行诸如将字符串添加到整数而不会导致错误这样的激进事情。

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

答案 4 :(得分:3)

是的,这是可能的。

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

警告:原始手册中有拼写错误:res ro uce而不是res ou rce

人们经常会询问标量/基本类型提示。这是我在MVC框架中使用的一个类,它将通过使用自定义错误处理程序启用类型提示。

注意:您应该将此代码包含在include头中的所有其他代码之上,如果您使用的是set_error_handler()函数,则应该知道它也使用它。您可能需要链接set_error_handlers()

为什么?

  1. 因为人们厌倦了使用is_ *函数来验证参数。
  2. 减少防御编码员的冗余编码。
  3. 函数/方法是自定义/记录所需的输入。
  4. 还.. 在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.
    
    ?>
    

    你得到了照片..

答案 5 :(得分:1)

原始类型不支持

Accordind to PHP documentation类型提示。

它支持类和接口。

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

答案 6 :(得分:0)

这是从传入的参数中强制布尔值的简短语法。如果$state为真,则$this->is_active设置为true。对于所有其他类型的值,它设置为false。

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

答案 7 :(得分:-2)

我猜你不需要为PHP提供类型提示,因为你给了类型检查函数,比如is_bool(),is_string()等等,所以你可以检查你试图放入这些函数的参数实际上它是一个参数,虽然他们用来检查数组和对象类型的方法会更清晰。