我想知道是否有可能限制php变量只接受它定义为接受的某种类型的变量.
例如,如果我们在C#中看到
public int variable = 20;
public string variable2 = "Hello World";
Run Code Online (Sandbox Code Playgroud)
那么如果我想限制变量的类型,那将是什么样的PHP.
public int $variable = 20;
Run Code Online (Sandbox Code Playgroud)
所以,如果我尝试将字符串分配给整数变量,我得到错误.
public int $varaible = "Hello World"; //As type is integer, it should throw error.
Run Code Online (Sandbox Code Playgroud)
是否有这样的事情在PHP中为变量定义类型之前给它赋值?
eli*_*ide 10
TL; DR不直接,没有.PHP不是严格类型的.但是,在函数参数或类的属性的上下文中,有一些可能对您有用的变通方法.
答案很长: PHP不是严格类型的语言,而是松散类型的.无论初始化方式如何,您都可以为变量提供所需的任何值.所以,你不能简单地键入类似的东西,int $myVar并期望$myVar = "foo";抛出错误.但PHP确实提供了一些方便的功能,可以在处理函数参数或类的属性时使您达到同样的目的.
您可以对函数参数使用"类型提示":
class SomeClass
{
/* code here */
}
function foo(SomeClass $data)
{
/* code here */
}
Run Code Online (Sandbox Code Playgroud)
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
}
}
}
Run Code Online (Sandbox Code Playgroud)
优点:
缺点:
这种方法是我最喜欢的,也是最复杂的.使用__set()magic方法处理类属性.
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
Run Code Online (Sandbox Code Playgroud)
优点:
缺点:
switching或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);
Run Code Online (Sandbox Code Playgroud)
如果你真的想要硬核,那么你可以使用Hack进行强类型操作,代价是使你的代码不那么便携,而且与主要的IDE相比(现在)兼容性差.
当然,这些都不能替代显式验证用户输入并彻底测试应用程序对意外输入类型的响应.
| 归档时间: |
|
| 查看次数: |
2844 次 |
| 最近记录: |