7

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

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

是否可以像在 JAVA 中那样使用包装类?整数、字符串、布尔值等...

我想这样使用它:

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

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

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

4

2 回答 2

5

自 PHP 5 起,PHP 允许使用类进行类型提示(强制函数/方法的参数成为类的实例)。

因此,您可以int在构造函数中创建一个接受 PHP 整数的类(如果您允许包含整数的字符串,则解析整数,如下例所示),并在函数的参数中期望它。

The int class

<?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;
   }

}

Demo

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

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

Result

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

但是你应该小心副作用。

如果您在表达式(例如,)中使用它,您的int实例将评估为,而不是在我们的例子中。您应该使用表达式来获取,因为仅在尝试将对象转换为字符串时才调用。true$test + 142"$test" + 143__toString

注意:您不需要包装array类型,因为您可以在函数/方法的参数上本地类型提示它。

The float class

<?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;
   }

}

The string class

<?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;
   }

}

The bool class

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;
   }

}

The object class

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`
   }

}
于 2014-11-19T13:51:54.957 回答
1

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

function myFunc($num) {
    if( !is_int($num) ) {
        throw new Exception('First parameter must be a number');
    }
    // ...
}

不过,这不是真正的类型提示。

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

/**
 * @param int $num
 */
function myFunc($num) {
    // ...
}
于 2014-11-17T12:01:45.563 回答