在类型提示时使用类似于JAVA的包装类

时间:2014-11-17 11:54:52

标签: php type-conversion boxing type-hinting php-7

在php-s类型提示中,我不能使用标量类型,如整数或字符串。所以这是无效的:

function myFunc(int $num) {
    //...
}

是否可以使用包装类,如JAVA?整数,字符串,布尔值等......

我想像这样使用它:

function myFunc(Integer $num) {
    //...
}

myFunc(5);     // ok
myFunc("foo"); // error

我知道,默认情况下,php中没有包装类。但怎么可能写一个呢?

2 个答案:

答案 0 :(得分:5)

从PHP 5开始,PHP允许type hinting使用类(强制函数/方法的参数是类的实例)。

所以你可以创建一个int类,它在构造函数中获取一个PHP整数(或者如果允许包含整数的字符串解析整数,例如下面的例子中),并期望它在函数中# 39; s参数。

int

<?php

class int
{

   protected $value;

   public function __construct($value)
   {
      if (!preg_match("/^(0|[-]?[1-9][0-9])*$/", "$value"))
      {
         throw new \Exception("{$value} is not a valid integer.");
      }
      $this->value = $value;
   }

   public function __toString()
   {
      return '' . $this->value;
   }

}

演示

$test = new int(42);
myFunc($test);

function myFunc(int $a) {
  echo "The number is: $a\n";
}

结果

KolyMac:test ninsuo$ php types.php 
The number is: 42
KolyMac:test ninsuo$ 

但你应该注意副作用。

如果您在表达式(例如int)中使用true实例,而不是$test + 1,则42实例将评估为"$test" + 1 。您应该使用43表达式来获取__toString,因为只有在尝试将对象转换为字符串时才调用array

注意:您不需要打包float类型,因为您可以在函数/方法的参数上原生地键入提示。

<?php class float { protected $value; public function __construct($value) { if (!preg_match("/^(0|[-]?[1-9][0-9]*[\.]?[0-9]*)$/", "$value")) { throw new \Exception("{$value} is not a valid floating number."); } $this->value = $value; } public function __toString() { return $this->value; } }

string

<?php class string { protected $value; public function __construct($value) { if (is_array($value) || is_resource($value) || (is_object($value) && (!method_exists($value, '__toString')))) { throw new \Exception("{$value} is not a valid string or can't be converted to string."); } $this->value = $value; } public function __toString() { return $this->value; } }

bool

class bool { protected $value; public function __construct($value) { if (!strcasecmp('true', $value) && !strcasecmp('false', $value) && !in_array($value, array(0, 1, false, true))) { throw new \Exception("{$value} is not a valid boolean."); } $this->value = $value; } public function __toString() { return $this->value; } }

object

class object { protected $value; public function __construct($value) { if (!is_object($value)) { throw new \Exception("{$value} is not a valid object."); } $this->value = $value; } public function __toString() { return $this->value; // your object itself should implement __tostring` } }

{{1}}

答案 1 :(得分:1)

原始值没有包装类,没有。我想你可以手动检查类型:

function myFunc($num) {
    if( !is_int($num) ) {
        throw new Exception('First parameter must be a number');
    }
    // ...
}
但是,它不是真正的类型暗示。

最好的方法可能是很好地记录你的代码并希望它被正确使用。

/**
 * @param int $num
 */
function myFunc($num) {
    // ...
}