Quelle interface PHP permet les propriétés d'objets soient accessibles avec la notation de tableau?
-
22-09-2019 - |
Question
Quelle interface PHP SPL permet aux objets de le faire:
$object->month = 'january';
echo $object['month']; // january
$record['day'] = 'saturday';
echo $record->day; // saturday
par exemple. par exemple dans les bibliothèques comme doctrine (Doctrine_Record)
Comment puis-je mettre cela? Je l'ai essayé d'utiliser ArrayObject, mais ils ne se comportent pas comme je pensais qu'ils le feraient.
i.e..
$object = new ArrayObject();
$object['a'] = 'test';
$object['a'] == $object->a; // false
EDIT:
J'ai essayé une implémentation barebone que j'ai appelé Array,.
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);
}
}
La solution
Il est ArrayAccess
Voir la sourcecode pour Doctrine_Record
abstract class Doctrine_Record
extends Doctrine_Record_Abstract
implements Countable, IteratorAggregate, Serializable
abstract class Doctrine_Record_Abstract extends Doctrine_Access
et enfin Doctrine_Access
abstract class Doctrine_Access
extends Doctrine_Locator_Injectable
implements ArrayAccess
De DocBlock
fournit une interface d'accès au tableau et la surcharge de la propriété pour les sous-classes Doctrine
Un objet qui implémente ArrayAccess doit avoir ces méthodes
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 );
Il est un exemple d'utilisation de base dans le manuel PHP (lien ci-dessus)
Autres conseils
Vous utilisez ici deux choses différentes:
L'interface ArrayAccess pour $a[key]
et
http://php.net/manual/en/language.oop5.overloading. php pour $a->key
Qu'est-ce qui se passe est
$a[key]
appellera $a->offsetGet(key)
(hérité de ArrayAccess) et $a->key
appellera $a->__get(key)
ou $a->__set(key, val)
(dans des contextes comme $a->key = val
).
Je pense que vous pouvez jeter objet et tableaux ..
$object = (object)array('name'=>'aviv');
echo $object->name; // prints aviv
Et vice versa ..
$array= (array)$object;
echo $array['name']; // prints aviv
Vous pouvez implémenter votre propre classe par exemple.
class PropertyTest {
$month;
}
puis dans l'utilisation de code
$object = new PropertyTest;
$object->month = "January";
echo $obejct->month;
Je réponds à la question en utilisant votre code d'exemple avec un ajout mineur:
<?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
Démo : https://3v4l.org/Nd5NW
ArrayObject
accepte un 2ème argument du constructeur, qui est soit
-
ArrayObject :: STD_PROP_LIST Les propriétés de l'objet ont leur fonctionnement normal en cas d'accès liste (var_dump, foreach, etc.).
-
ArrayObject :: ARRAY_AS_PROPS Les entrées sont accessibles en tant que propriétés (lecture et écriture).
Référencez : http://php.net/ manuel / de / class.arrayobject.php