3

Where can I find the ArrayObject's complete source code (in PHP)?

What I dont understand is why you can use the "arrow" when add an element to your ArrayObject, for example:

$a = new ArrayObject();
$a['arr'] = 'array data';                             
$a->prop = 'prop data';  //here it is

You can see $a->prop = 'prop data'; is used.

Is there any magic method or what was used, and how PHP knows for example that $a['prop'] and $a->prop means the same ? (in this context)

Filkor
  • 642
  • 6
  • 18
  • 1
    You always can do this: `public function __set( $key, $val){$this->arr[$key] = $val;}` and the same with getter .) – Vyktor Feb 07 '12 at 22:31
  • It's actually [just written in C](http://svn.php.net/viewvc/php/php-src/trunk/ext/spl/spl_array.c?view=markup) although, you could make the same one with pure PHP. – Wrikken Feb 07 '12 at 22:47
  • *(source)* http://lxr.php.net/opengrok/xref/PHP_TRUNK/ext/spl/spl_array.c – Gordon Feb 07 '12 at 22:49

1 Answers1

2

Yes, it is magic and it can be accomplished directly in PHP. Take look at Overloading http://www.php.net/manual/en/language.oop5.overloading.php

You can use __get() and __set in a class to do this. To make objects behave like arrays, you have to implement http://www.php.net/manual/en/class.arrayaccess.php

This is my example code:

<?php
class MyArrayObject implements Iterator, ArrayAccess, Countable
{
    /**  Location for overloaded data.  */
    private $_data = array();

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

    public function __get($name)
    {
        if (array_key_exists($name, $this->_data)) {
            return $this->_data[$name];
        }

        $trace = debug_backtrace();
        trigger_error(
            'Undefined property via __get(): ' . $name .
            ' in ' . $trace[0]['file'] .
            ' on line ' . $trace[0]['line'],
            E_USER_NOTICE);
        return null;
    }

    /**  As of PHP 5.1.0  */
    public function __isset($name)
    {
        return isset($this->_data[$name]);
    }

    /**  As of PHP 5.1.0  */
    public function __unset($name)
    {
        unset($this->_data[$name]);
    }

    public function offsetSet($offset, $value) {
        if (is_null($offset)) {
            $this->_data[] = $value;
        } else {
            $this->_data[$offset] = $value;
        }
    }

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

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

    public function offsetGet($offset) {
        return isset($this->_data[$offset]) ? $this->_data[$offset] : null;
    }
    public function count(){
        return count($this->_data);
    }
    public function current(){
        return current($this->_data);
    }
    public function next(){
        return next($this->_data);
    }
    public function key(){
        return key($this->_data);
    }
    public function valid(){
        return key($this->_data) !== null;
    }
    public function rewind(){
        reset($this->_data);
    }
}

Instead of current($a), next($a) use $a->current(), $a->next()

Timo Huovinen
  • 53,325
  • 33
  • 152
  • 143
iblue
  • 29,609
  • 19
  • 89
  • 128
  • You wrote this example now (under 1 min)?:D Do you know where can i find the exact implementation? – Filkor Feb 07 '12 at 22:39
  • Actually I stole it from the PHP documentation and edited some parts. – iblue Feb 07 '12 at 22:40
  • 1
    The exact implementation is not written in PHP, but in C and can be found in the PHP sourcecode. Download it from http://php.net/downloads.php and take a look at `ext/spl/spl_array.c` – iblue Feb 07 '12 at 22:45
  • 4
    Or you can take a look at the implementation in the repository at http://svn.php.net/viewvc/php/php-src/trunk/ext/spl/spl_array.c?view=log – VolkerK Feb 07 '12 at 22:49
  • Then I have to use http://www.php.net/manual/en/class.arrayaccess.php. Hold on a sec, I will edit my post. – iblue Feb 07 '12 at 22:54
  • Okay, very good. It's getting clear. The problem was that the docs didn't mentioned the __set, and __get magic methods anywhere , so it was a little bit strange.. And yeah, its inherits from ArrayAccess, so yeah its clear now guys. Thx again. – Filkor Feb 07 '12 at 23:01