是否可以将类对象视为变量?

时间:2015-08-05 21:19:54

标签: php oop magic-methods

是否可以将类对象视为变量???

我知道我们可以将它视为一种功能:

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()这样的魔术方法来做到这一点......或者甚至是一种黑客的做法?

2 个答案:

答案 0 :(得分:2)

不,这样做是不可能的,因为无法扩展内置的内容,例如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()接口作为包装对象。

答案 1 :(得分:0)

除了Anonymous's answer以及\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] );
        }
    }
}