我正在尝试创建一个包含一组属性的类。它会像这样使用:
$class = new test_class();
$class->property;
$class->second_property;
基本上,如果属性存在,则它们为真,如果属性不存在,则它们为假。这些属性没有价值,只有存在。
现在,我想做这样的事情:
$class = new test_class();
var_dump($class->property); // false - property does not exist
var_dump($class->second_property); // true - second_property exists
var_dump( (bool) $class); // true
因此,即使存在测试类的一个属性,var转储$class
也会显示为true,因为它是一个对象。
但是,在类没有属性的情况下,我希望这种情况发生:
$class = new test_class();
var_dump($class->property); // false - property does not exist
var_dump($class->second_property); // false - second_property does not exist
var_dump( (bool) $class); // false
但是,我仍然希望$class
为instanceof
test_class
,但在逻辑测试中返回false。
这一切都可能吗?如果是这样,我该怎么做?
谢谢,Ozzy
修改
为了澄清,我已经在使用__get()魔术函数了。我想要发生的是,如果test_class
没有属性,那么当对其执行var_dump
时,它会返回false,但instanceof
将返回test_class
。
阐述...
我正在创建一个复杂的权限系统。 用户获得指定的部分,每个部分都有一组权限。
它会像这样工作:
$user = permissions::get_user(USER_ID_HERE);
// Every property of the $user is a section
var_dump($user->this_section_exists); // true - returns an object
var_dump($user->this_section_doesnt); // false - returns a boolean
如果存在某个部分,则它返回部分权限的对象。
var_dump($user->this_section_exists); // true
var_dump($user->this_section_exists->this_permission_exists); // true
var_dump($user->this_section_exists->this_permission_doesnt); // false
继承边缘案例:
var_dump($user->this_section_doesnt); // false
var_dump($user->this_section_doesnt->some_permission);
// This should also return false, which it does,
// But it throws a notice: "Trying to get property of non-object"
我希望能够在没有对调用类的代码进行任何修改的情况下抑制该通知,即,没有@抑制..或者能够在逻辑测试中返回没有属性值为false的对象。
答案 0 :(得分:1)
我想要发生的是如果test_class没有属性,那么当对它执行var_dump时,它返回false但是instanceof将返回test_class。
这是不可能的,var_dump
将始终显示正确的类型,就是它的用途。
答案 1 :(得分:0)
不,你不能完全像你写的那样去做。但你可以模仿类似的东西:
class A {
public function __toString() { // this is what you want, but it only works when you use your object as a string, not as a bool.
if (count(get_class_vars(__CLASS__))) { // so if the class has at least 1 attribute, it will return 1.
return '1';
} else {
return '0';
}
}
}
$a = new A;
var_dump((bool)(string)$a); // false
如果我在A类中添加一个属性,它将返回true。您也可以在没有(bool)
的情况下使用它。
if ((string)$a) {
echo 'I am not empty';
} else {
echo 'I am an empty object';
}
如果您不想使用(string)
,则还剩下一个选项,即创建一个包含__toString()
代码的方法,并将其调用而不是投射。
参考文献:
PS:关于你所说的 - 在对象上做var_dump()
以返回false。不,那是不可能的。
答案 2 :(得分:-1)
您可以尝试PHP magic function
<?php
class Test {
private $name = 'name';
public $age = 20;
public function __get($name) {
return isset($this->$name) ? true : false;
}
public function __toString() {
return true;
}
}
$object = new Test();
var_dump($object->name); // output `true`
var_dump($object->age); // output `20`
var_dump($object->notfound); // output `false`
var_dump((bool)$object); // output `true`
答案 3 :(得分:-1)
您可以使用__get()进行一些包装来操纵答案。
说出类似
的内容class test_class {
private $_validProperties;
public function __construct()
{
$this->validProperties = array('foo', 'bar', 'widget');
}
public function __get($prop)
{
if (isset($this->_validProperties[$prop])
{
return true;
}
return false;
}
}
$a = new test_class();
var_dump($a->foo); //true
var_dump($a->tree); //false
答案 4 :(得分:-1)
如果我理解正确,我只能这样做。
希望它可以帮到你
<?php
class Permissions {
private $userPermissions = array(
1 => array(
'Blog' => array('Post'),
),
);
private $permission;
public function __construct($id) {
$this->permission = $this->userPermissions[$id];
}
public function __get($name) {
if(isset($this->permission[$name])) {
return new $name($this->permission[$name]);
}
return new Notfound();
}
}
class Blog {
private $permission;
public function __construct($permission) {
$this->permission = $permission;
}
public function __get($name) {
if(($key = array_search($name, $this->permission)) !== false) {
return new $name();
}
return new Notfound();
}
public function __tostring() {
return true;
}
}
class Post {
public function __get($name) {
return isset($this->$name) ? true : new Notfound();
}
public function __tostring() {
return true;
}
}
class Notfound {
public function __get($name) {
return false;
}
public function __tostring() {
return false;
}
}
$user = new Permissions(1);
var_dump('Blog ', $user->Blog); // return Blog
var_dump('Blog:Post', $user->Blog->Post); // return Post
var_dump('News', $user->News); // return Notfound
var_dump('News:Post', $user->News->Post); // return false