哪个PHP接口允许使用数组表示法访问对象的属性?

时间:2010-02-22 17:41:52

标签: php arrays spl arrayobject

哪个PHP SPL接口允许对象执行此操作:

$object->month = 'january';
echo $object['month']; // january

$record['day'] = 'saturday';
echo $record->day; // saturday

e.g。比如像Doctrine(Doctrine_Record)这样的图书馆

我该如何实现?我已经尝试过使用ArrayObject,但它们并没有像我想的那样表现。

$object = new ArrayObject();
$object['a'] = 'test';
$object['a'] == $object->a; // false

修改

我尝试了一个名为Arrayable的准系统实现。

class Arrayable implements ArrayAccess
{
    protected $container = array();

    # implement ArrayAccess methods to allow array notation 
    # $object = new Arrayable();
    # $object['value'] = 'some data';

    function offsetExists($offset)
    {
        return isset($this->container[$offset]);
    }

    function offsetGet($offset)
    {
        return $this->container[$offset];
    }

    function offsetSet($offset, $value)
    {
        $this->container[$offset] = $value;
    }

    function offsetUnset($offset)
    {
        unset($this->container[$offset]);
    }

    # now, force $object->value to map to $object['value'] 
    # using magic methods

    function __set($offset, $value)
    {
        $this->offsetSet($offset, $value);
    }

    function __get($offset)
    {
        return $this->offsetGet($offset); 
    }
}

5 个答案:

答案 0 :(得分:4)

这是ArrayAccess

请参阅sourcecode for Doctrine_Record

abstract class Doctrine_Record 
    extends Doctrine_Record_Abstract 
    implements Countable, IteratorAggregate, Serializable

Doctrine_Record_Abstract

abstract class Doctrine_Record_Abstract extends Doctrine_Access

最后Doctrine_Access

abstract class Doctrine_Access 
    extends Doctrine_Locator_Injectable 
    implements ArrayAccess

来自DocBlock

  

为Doctrine子类提供数组访问和属性重载接口


实现ArrayAccess的对象必须具有这些方法

abstract public boolean offsetExists  ( mixed $offset  );
abstract public mixed offsetGet ( mixed $offset );
abstract public void offsetSet ( mixed $offset , mixed $value );
abstract public void offsetUnset ( mixed $offset );

PHP手册中有一个基本用法示例(上面链接)

答案 1 :(得分:3)

你在这里使用两种不同的东西:

$a[key]$a->key的ArrayAccess接口 $a[key]

http://php.net/manual/en/language.oop5.overloading.php

会发生什么

$a->offsetGet(key)将调用$a->key(继承自ArrayAccess),$a->__get(key)将调用$a->__set(key, val)$a->key = val(在{{1}}等上下文中)。

答案 2 :(得分:0)

我认为你可以投射对象和数组..

$object = (object)array('name'=>'aviv');
echo $object->name; // prints aviv

反过来..

$array= (array)$object;
echo $array['name']; // prints aviv

答案 3 :(得分:0)

您可以实现自己的课程 例如

class PropertyTest {
 $month;
}

然后在代码中使用

$object = new PropertyTest;
$object->month = "January";
echo $obejct->month;

答案 4 :(得分:0)

我正在使用您的示例代码回答这个问题并添加一些小的内容:

<?php
$object = new ArrayObject([], ArrayObject::ARRAY_AS_PROPS);

$object['a'] = 'test';
var_dump($object['a'] == $object->a); // expected: bool(true)

$object->month = 'january';
echo $object['month'];               // expected: january

$object['day'] = 'saturday';
echo $object->day;                   // expected: saturday

演示https://3v4l.org/Nd5NW

ArrayObject 接受第二个构造函数参数,该参数为

  • <强> ArrayObject的:: STD_PROP_LIST 当以列表形式访问时,对象的属性具有其正常功能(var_dump,foreach等)。

  • <强> ArrayObject的:: ARRAY_AS_PROPS 条目可以作为属性(读取和写入)访问。

参考http://php.net/manual/de/class.arrayobject.php