Which PHP interface allows objects' properties to be accessible with array notation?
Which PHP SPL interface allows objects to do this:
$object->month = 'january';
echo $object['month']; // january
$record['day'] = 'saturday';
echo $record->day; // saturday
e.g. such as in libraries like Doctrine (Doctrine_Record)
how do I implement this? I've tried using ArrayObject, but they don't behave as I thought they would.
i.e.
$object = new ArrayObject();
$object['a'] = 'test';
$object['a'] == $object->a; // false
EDIT:
I tried a barebone implementation that I called 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)
{
$th开发者_开发百科is->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);
}
}
It's ArrayAccess
See the sourcecode for Doctrine_Record
abstract class Doctrine_Record
extends Doctrine_Record_Abstract
implements Countable, IteratorAggregate, Serializable
and Doctrine_Record_Abstract
abstract class Doctrine_Record_Abstract extends Doctrine_Access
and finally Doctrine_Access
abstract class Doctrine_Access
extends Doctrine_Locator_Injectable
implements ArrayAccess
From DocBlock
Provides array access and property overload interface for Doctrine subclasses
An object implementing ArrayAccess has to have these methods
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 );
There is a basic usage example in the PHP manual (linked above)
You are using two different things here:
The ArrayAccess interface for $a[key]
and
http://php.net/manual/en/language.oop5.overloading.php for $a->key
What happens is
$a[key]
will call $a->offsetGet(key)
(inherited from ArrayAccess) and $a->key
will call $a->__get(key)
or $a->__set(key, val)
(in contexts like $a->key = val
).
I think you can cast object and arrays..
$object = (object)array('name'=>'aviv');
echo $object->name; // prints aviv
And vise versa ..
$array= (array)$object;
echo $array['name']; // prints aviv
You can implement your own class e.g.
class PropertyTest {
$month;
}
then in code use
$object = new PropertyTest;
$object->month = "January";
echo $obejct->month;
I'm answering the question using your example code with a minor addition:
<?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
Demo: https://3v4l.org/Nd5NW
ArrayObject
accepts a 2nd constructor argument, which is either
ArrayObject::STD_PROP_LIST Properties of the object have their normal functionality when accessed as list (var_dump, foreach, etc.).
ArrayObject::ARRAY_AS_PROPS Entries can be accessed as properties (read and write).
Referencing: http://php.net/manual/de/class.arrayobject.php
精彩评论