3

我正在尝试创建一个包含一组属性的类。它将像这样使用:

$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 dumping the$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成为逻辑测试中instanceoftest_class但返回 false。

这是可能吗?如果是这样,我会怎么做?

谢谢,奥兹

编辑:

澄清一下,我已经在使用 __get() 魔术函数了。我想要发生的是,如果test_class没有属性,那么当var_dump对它执行 a 时,它返回 false 但 aninstanceof将返回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。

4

5 回答 5

1

我想要发生的是,如果 test_class 没有属性,那么当对其执行 var_dump 时,它会返回 false,但 instanceof 将返回 test_class。

那是不可能的,var_dump总是会告诉你正确的类型,这就是它的目的。

于 2013-01-25T12:37:45.250 回答
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。不,那是不可能的。

于 2013-01-25T12:37:35.227 回答
-1

你可以试试PHP 的魔法功能

<?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`
于 2013-01-25T12:30:39.767 回答
-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
于 2013-01-25T12:31:56.357 回答
-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
于 2013-01-25T13:33:42.807 回答