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

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

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

据我所知,我们可以将其视为一个函数:

class hello{
    public function __invoke(){
        return ['one','two','three'];
    }
}

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

我需要做的是去掉 (): 意味着将其视为变量并使其 return 成为(数组或其他对象)

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

是否有像 __invoke() 这样的神奇方法来做到这一点......或者甚至是一种 hacky 方法来做到这一点???

不,这是不可能的,因为不能扩展像 array 这样的内置东西。不过,有一些方法可以实现您想要的部分内容:

正在 var_dump()

打印自定义数据

这是 PHP 5.6 中随 __debugInfo() magic method 引入的一项功能。

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

var_dump(new Hello);

This would output:

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

像数组一样工作

虽然你不能让你的对象成为数组(即扩展它),但如果你实现ArrayAccess interface,它们可以像数组一样工作:

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() 接口。

除了 之外,与 \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] );
        }
    }
}