我想知道是否可以限制php变量只接受它定义为接受的某种类型的变量。
如果我们在C#中看到的话,请注意
public int variable = 20;
public string variable2 = "Hello World";
那么如果我想限制变量的类型,那会是什么样的。
public int $variable = 20;
因此,如果我尝试将字符串分配给整数变量,我会得到错误。
public int $varaible = "Hello World"; //As type is integer, it should throw error.
是否有这样的事情在PHP中为变量定义类型之前为它赋值?
答案 0 :(得分:9)
TL; DR 不直接,没有。 PHP不是严格类型的。但是,在函数参数或类属性的上下文中,有一些可能对您有用的变通方法。
长答案: PHP不是严格类型的语言,而是松散类型的语言。无论初始化方式如何,您都可以为变量提供所需的任何值。因此,您不能简单地输入类似int $myVar
的内容并期望$myVar = "foo";
抛出错误。但PHP确实提供了一些方便的功能,可以在处理函数参数或类的属性时使您达到同样的目的。
您可以使用"type hint"作为函数参数:
class SomeClass
{
/* code here */
}
function foo(SomeClass $data)
{
/* code here */
}
foo()
只接受SomeClass
类型的参数。传递它,比如说,int
会引发一个致命的错误。这不适用于PHP< 7如果参数是基本类型,如int
,string
等,那么您无法执行function foo(int $data) {...}
。也就是说,有一些库试图以牺牲一点速度为代价来强制它运行。此外,PHP 7为基于PHP的Hack语言添加了很多支持。
<强>优点:强>
<强>缺点:强>
你也可以使用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
}
}
}
<强>优点:强>
<强>缺点:强>
这种方法是我的最爱,也是最复杂的。使用__set()
magic method处理类属性。
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
<强>优点:强>
<强>缺点:强>
switch
或if
/ else
逻辑最后,如果您使用的是像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);
如果你真的想要去核心,你可以使用Hack进行强力打字,代价是使你的代码不那么便携,而且与主要的兼容性差(现在) IDE中。
当然,这些都不能替代明确验证用户输入并彻底测试应用程序对意外输入类型的响应。
答案 1 :(得分:4)
没有。 PHP不是严格类型的语言。但是,您可以在函数和方法中使用type hints
。
如果将类或接口指定为类型提示,则也允许其所有子项或实现。
类型提示不能与标量类型(如int或string)一起使用。资源和特征也是不允许的。
标量类型为:
string
bool
int
float
示例:
function (array $theArr) {
// body
}
class X {
public function __construct(SomeOtherClass $arg) {
// body
}
public function setFoo(Foo $foo) {
}
}
有关详细信息,请参阅手册:http://php.net/manual/en/language.oop5.typehinting.php
答案 2 :(得分:0)
你必须亲自动手,例如:
function setInt(&$var, $value) {
if(!is_integer($value) {
throw new Exception("Integer wanted " . gettype($value) . " received");
}
$var = $value;
}