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

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.