Quelle interface PHP permet les propriétés d'objets soient accessibles avec la notation de tableau?

StackOverflow https://stackoverflow.com/questions/2312833

  •  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); 
    }
}
Était-ce utile?

La solution

Il est ArrayAccess

Voir la sourcecode pour Doctrine_Record

abstract class Doctrine_Record 
    extends Doctrine_Record_Abstract 
    implements Countable, IteratorAggregate, Serializable

et Doctrine_Record_Abstract

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

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top