TL;DR不直接,不。 PHP 不是严格类型的。但是,有一些解决方法可能适合您在函数参数或类属性的上下文中。
长答案:PHP 不是严格类型语言,而是松散类型语言。您可以为变量指定任何您想要的值,无论它是如何初始化的。所以,你不能简单地输入类似的内容int $myVar
并期望$myVar = "foo";
抛出错误。但是 PHP 确实提供了一些方便的功能,可以让您在处理函数参数或类的属性时达到相同的目的。
选项 1:键入提示
您可以使用“输入提示”对于函数参数:
class SomeClass
{
/* code here */
}
function foo(SomeClass $data)
{
/* code here */
}
foo()
只接受类型的参数SomeClass
。通过它,比方说,int
会抛出致命错误。如果参数是基本类型,则这在 PHP int, string
等等,所以你不能这样做function foo(int $data) {...}
。也就是说,有一些库试图以牺牲一点速度为代价来强制它工作。另外,PHP 7 增加了很多对这种东西的支持,基于 PHP 的 Hack 语言也是如此。
Pros:
Cons:
选项 2:Getter 和 Setter
您还可以使用 getter 和 setter,如下所示:
class SomeClass
{
private $foo = 0;
function setFoo($val = 0)
{
// force it to be an int
if (is_integer($val) {
$this->foo = $val;
} else {
// throw an error, raise an exception, or otherwise respond
}
}
}
Pros:
Cons:
- 仅适用于程序定义的类
- 不适用于基本类型
- 需要大量代码
选项 3:魔法方法
这个方法是我最喜欢的,但也是最复杂的。使用__set()魔术方法处理类属性。
class MyClass {
private $type = 0; // we will force this to be an int
private $string = ''; // we will force this to be a string
private $arr = array(); // we will force this to be an array
private $percent = 0; // we will force this to be a float in the range 0..100
function __set($name, $value) {
switch ($name) {
case "type":
$valid = is_integer($value);
break;
case "string":
$valid = is_string($value);
break;
case "arr":
$valid = is_array($value);
break;
case "percent":
$valid = is_float($value) && $value >= 0 && $value <= 100;
break;
default:
$valid = true; // allow all other attempts to set values (or make this false to deny them)
}
if ($valid) {
$this->{$name} = $value;
// just for demonstration
echo "pass: Set \$this->$name = ";
var_dump($value);
} else {
// throw an error, raise an exception, or otherwise respond
// just for demonstration
echo "FAIL: Cannot set \$this->$name = ";
var_dump($value);
}
}
}
$myObject = new MyClass();
$myObject->type = 1; // okay
$myObject->type = "123"; // fail
$myObject->string = 1; // fail
$myObject->string = "123"; // okay
$myObject->arr = 1; // fail
$myObject->arr = "123"; // fail
$myObject->arr = array("123"); // okay
$myObject->percent = 25.6; // okay
$myObject->percent = "123"; // fail
$myObject->percent = array("123"); // fail
$myObject->percent = 123456; // fail
Pros:
Cons:
- 仅适用于程序定义的类
- 不适用于基本类型
- 需要大量的
switch
ing or if
/else
logic
- 可能会导致 IDE 无法正确自动完成属性类型的问题
这是一个这种方法的演示.
结束语
最后,如果您使用 PHPStorm 这样的 IDE,请不要忘记 PHPDoc 类型提示:
/* @var integer */
$foo = 0; // will result in warnings if the IDE is configured properly and you try to do something like substr($foo, 1, 4);
如果你really想要成为硬核,你可以使用强类型Hack,代价是使您的代码的可移植性较差并且与主要 IDE 的兼容性(目前)较差。
当然,这些都不能替代显式验证用户输入并彻底测试应用程序对意外输入类型的响应。