是否可以像对待变量一样对待类对象?


is it possible to treat a class object like a variable?

是否可以像对待变量一样对待类对象??

我知道我们可以把它当作一个函数:

class hello{
    public function __invoke(){
        return ['one','two','three'];
    }
}
$obj = new hello;
var_export($obj()); //returns the defined array ['one','two','three']

我要做的就是去掉():意思是把它当作一个变量&让它返回一个(数组或其他对象)

$obj = new hello;
var_export($obj); //returns the defined array ['one','two','three']

有没有像__invoke()这样的神奇方法来做到这一点…或者甚至是一种粗俗的方式??

不,这是不可能的,因为不能扩展内置的东西,如array。这里有一些方法可以实现你想要的部分:

var_dump()上打印自定义数据

这是在php5.6中用__debugInfo()魔术方法引入的一个特性。

class Hello {
    public function __debugInfo(){
        return ['one','two','three'];
    }
}
var_dump(new Hello);

这将输出:

object(Hello)#1 (3) {
  [0]=>
  string(3) "one"
  [1]=>
  string(3) "two"
  [2]=>
  string(5) "three"
}

像数组一样运行

虽然您不能使对象成为数组(即扩展它),但如果实现ArrayAccess接口,它们可以表现得像数组:

class Hello implements ArrayAccess {
    private $data = [];
    public function offsetExists($offset) {
        return isset($this->data[$offset]);
    }
    /* insert the rest of the implementation here */
}

然后你可以像数组一样使用它:

$fake_array = new Hello();
$fake_array['foo'] = 'bar';
echo $fake_array['foo'];

注意,你不能把实现这个接口的类传递给array暗示的方法。


不幸的是,它不可能像任何其他原始数据类型那样工作。如果你想要极致的灵活性,你将不得不考虑Python和Scala。在PHP中,您需要为包装对象使用一些模式,如getData()setData()接口。

除了Anonymous的答案之外,与'ArrayAccess一起实现'IteratorAggregate(与foreach()一起工作)和'Countable(与count()一起工作)也很有用

namespace {
    abstract class AEnumerable implements 'IteratorAggregate, 'Countable, 'ArrayAccess {
        protected $_array;
        public function getIterator() {
            return new 'ArrayIterator($this->_array);
        }
        public function count() {
            return count($this->_array);
        }
        public function offsetExists( $offset ) {
            return isset($this->_array[$offset]);
        }
        public function offsetGet( $offset ) {
            return $this->_array[$offset];
        }
        public function offsetSet( $offset, $value ) {
            $this->_array[$offset] = $value;
        }
        public function offsetUnset( $offset ) {
            unset( $this->_array[$offset] );
        }
    }
}