PHP object like array

2020-02-10 01:35发布

问题:

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

$obj->foo = 'bar';

then after that is set i need the following to be true

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

回答1:

Want to improve this post? Provide detailed answers to this question, including citations and an explanation of why your answer is correct. Answers without enough detail may be edited or deleted.

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
}


回答2:

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



回答3:

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'];


回答4:

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 :

  • ArrayAccess::offsetExists : Whether or not an offset exists.
  • ArrayAccess::offsetGet : Returns the value at specified offset.
  • ArrayAccess::offsetSet : Assigns a value to the specified offset.
  • and ArrayAccess::offsetUnset : Unsets an offset.

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



回答5:

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



回答6:

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


回答7:

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



回答8:

You could also cast the object as an array:

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


回答9:

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