30

I need to be able to set my object like this:

$obj->foo = 'bar';

then I need to use it as an array like that:

if($obj['foo'] == 'bar'){
  //more code here
}

9 Answers 9

23

Just add implements ArrayAccess to your class and add the required methods:

  • public function offsetExists($offset)
  • public function offsetGet($offset)
  • public function offsetSet($offset, $value)
  • public function offsetUnset($offset)

See http://php.net/manual/en/class.arrayaccess.php

Sign up to request clarification or add additional context in comments.

Comments

20

Try extending ArrayObject

You'll also need to implement a __get Magic Method as Valentin Golev mentioned.

Your class will need to looks something like this:

Class myClass extends ArrayObject {
    // class property definitions...
    public function __construct()
    {
        //Do Stuff
    }

    public function __get($n) { return $this[$n]; }

    // Other methods
}

3 Comments

I have this class Obj extends ArrayObject{} But when i am doing my unit testing i get a failure on the above.
yes, now you need to define there function __get() and __set(). For example, function __get($n) { return $this[$n]; }
Thank you very much, i was missing the helper function.
17

ArrayObject implements the ArrayAccess interface (and some more). Using the ARRAY_AS_PROPS flag it provides the functionality you're looking for.

$obj = new ArrayObject(array(), ArrayObject::ARRAY_AS_PROPS);
$obj->foo = 'bar';
echo $obj['foo'];

Alternatively you can implement the ArrayAccess interface in one of your own classes:

class Foo implements ArrayAccess {
  public function offsetExists($offset) {
    return isset($this->$offset);
  }

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

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

  public function offsetUnset($offset) {
    unset($this->$offset);
  }
}

$obj = new Foo;
$obj->foo = 'bar';
echo $obj['foo'];

Comments

10

You can access PHP object as PHP array, but in different ways. Try this:

$obj->{'foo'}

That is similar with accessing array like this:

$arr['foo']

You can also do this:

$propertyName = 'foo';
$obj->$propertyName; // same like first example

2 Comments

Upvoting because syntactical sugar.
Doesn't convert the object to an actual array.
9

You'll have to implement the ArrayAccess interface to be able to do that -- which only means implementing a few (4 to be exact) simple methods :

There is a full example on the manual's page I pointed to ;-)

1 Comment

@Gordon : ergh, thanks ! I generally copy-paste the names of classes/methods to avoid that kind of mistake... This time I thought "I can type this"... Well, it seems not ^^
9

You're mixing objects and arrays. You can create and access an object like so:

$obj = new stdClass;
$obj->foo = 'bar';

if($obj->foo == 'bar'){
// true
}

and an array like so:

$obj = new Array();
$obj['foo'] = 'bar';

if($obj['foo'] == 'bar'){
// true
}

You can define a class and add implements ArrayAccess if you want to access your class as both an array and a class.

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

Comments

3

Your object must implement the ArrayAccess interface, then PHP will allow you to use the square brackets like that.

Comments

3

You could also cast the object as an array:

if((array)$obj['foo'] == 'bar'){
  //more code here
}

1 Comment

The expression (array)$obj['foo'] as given here applies the array conversion to the object used as an array, which gives a fatal error. What you want is ((array)$obj)['foo']. Then it appears to work much simpler than any of the other answers. You can convert an object to a true array like this: $arr=(array)$obj;. So simple.
2

Enhance Class capability with no functionality drawbacks

You can also use ArrayAccess to access a single array property in your class and leave other properties being accessed in OOP way. Yet still it will work as you requested.

class Foo implements \ArrayAccess
{

/**
* mixed[] now you can access this array using your object 
* like a normal array Foo['something'] = 'blablabla'; echo  Foo['something']; ... and so on
* other properties will remain accessed as normal: $Foo->getName();
*/
private myArrayOptions = [];

private $name = 'lala';

    ...

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

    public function offsetGet($offset)
    {
        if ($this->offsetExists($offset)) {
            return $this->myArrayOptions[$offset];
        }

        return null; // or throw the exception;
    }

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

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

    public function getName()
    {
        return $this->name;
    }

    public function __set($offset, $value){
        $this->myArrayOptions[$offset] = $value;
    }

    ...

}

The above will work as you expected.

$obj->foo = 'bar';
if($obj['foo'] == 'bar'){
    echo "WoWo";
}

Also note that Foo['name'] !== Foo->getName() those a two different variables

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.