Qual interface PHP permite que as propriedades dos objetos sejam acessíveis com a notação de matriz?

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

  •  22-09-2019
  •  | 
  •  

Pergunta

Qual interface PHP SPL permite que os objetos façam isso:

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

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

por exemplo, como em bibliotecas como a doutrina (doutrina_record)

Como faço para implementar isso? Eu tentei usar o ArrayObject, mas eles não se comportam como eu pensei que o faria.

ou seja

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

EDITAR:

Eu tentei uma implementação sem ossos que chamei de 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); 
    }
}
Foi útil?

Solução

Isso é ArrayAccess

Veja o SourCecode para Doutrine_record

abstract class Doctrine_Record 
    extends Doctrine_Record_Abstract 
    implements Countable, IteratorAggregate, Serializable

e Doutrina_record_abstract

abstract class Doctrine_Record_Abstract extends Doctrine_Access

e finalmente Doutrina_access

abstract class Doctrine_Access 
    extends Doctrine_Locator_Injectable 
    implements ArrayAccess

De docblock

Fornece acesso à matriz e interface de sobrecarga de propriedades para subclasses de doutrina


Um objeto que implementa o ArrayAccess deve ter esses métodos

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 );

Há um exemplo de uso básico no manual do PHP (vinculado acima)

Outras dicas

Você está usando duas coisas diferentes aqui:

A interface ArrayAccess para $a[key] ehttp://php.net/manual/en/language.oop5.overloading.php por $a->key

O que acontece é

$a[key] chamará $a->offsetGet(key) (herdado de ArrayAccess) e $a->key chamará $a->__get(key) ou $a->__set(key, val) (em contextos como $a->key = val).

Eu acho que você pode lançar objeto e matrizes ..

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

E vice -versa ..

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

Você pode implementar sua própria classe, por exemplo

class PropertyTest {
 $month;
}

então em uso de código

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

Estou respondendo à pergunta usando seu código de exemplo com uma pequena adição:

<?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

Demonstração: https://3v4l.org/nd5nw


ArrayObject aceita um segundo argumento do construtor, que é

  • ArrayObject :: std_prop_listAs propriedades do objeto têm sua funcionalidade normal quando acessadas como lista (var_dump, foreach, etc.).

  • ArrayObject :: Array_AS_PropsAs entradas podem ser acessadas como propriedades (leia e escreva).

Referência: http://php.net/manual/de/class.arrayobject.php

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top