[PHP advanced features] ArrayAccess (array access) interface

php provides six commonly used predefined interfaces to implement certain specific capabilities. The most commonly used one is ArrayAccess, which is used in popular frameworks like Laravel.

What is ArrayAccess

As stated in the official documentation, it "provides an interface to the ability to access objects like arrays.".

It provides four interfaces

/**
 * Interface to provide accessing objects as arrays.
 * @link http://php.net/manual/en/class.arrayaccess.php
 */
interface ArrayAccess {

    /**
     * Whether a offset exists
     * @link http://php.net/manual/en/arrayaccess.offsetexists.php
     * @param mixed $offset <p>
     * An offset to check for.
     * </p>
     * @return boolean true on success or false on failure.
     * </p>
     * <p>
     * The return value will be casted to boolean if non-boolean was returned.
     * @since 5.0.0
     */
    public function offsetExists($offset);

    /**
     * Offset to retrieve
     * @link http://php.net/manual/en/arrayaccess.offsetget.php
     * @param mixed $offset <p>
     * The offset to retrieve.
     * </p>
     * @return mixed Can return all value types.
     * @since 5.0.0
     */
    public function offsetGet($offset);

    /**
     * Offset to set
     * @link http://php.net/manual/en/arrayaccess.offsetset.php
     * @param mixed $offset <p>
     * The offset to assign the value to.
     * </p>
     * @param mixed $value <p>
     * The value to set.
     * </p>
     * @return void
     * @since 5.0.0
     */
    public function offsetSet($offset, $value);

    /**
     * Offset to unset
     * @link http://php.net/manual/en/arrayaccess.offsetunset.php
     * @param mixed $offset <p>
     * The offset to unset.
     * </p>
     * @return void
     * @since 5.0.0
     */
    public function offsetUnset($offset);
}

We implement these four interfaces, which correspond to the isset, read, set and unset operations of the array in turn.

What's the usage?

The definition makes it clear that it provides the ability to access objects like arrays. With it, a class can support both object reference and array reference.

Use example

class Container implements ArrayAccess
{

    /**
     * @var array Singleton object index
     */
    private $instances = [];

    /**
     * @var array Index of instantiable object definition
     */
    private $definitions = [];

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

    public function offsetGet($offset)
    {
        if (isset($this->instances[$offset])) {
            return $this->instances[$offset];
        } elseif (isset($this->definitions[$offset])) {
            return $this->make($offset);
        }

        throw new \Exception('Object definition not provided');
    }

    public function offsetSet($offset, $value)
    {
        // Omit some comparative judgments
        $this->definitions[$offset] = $value;
    }

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

    private function make($offset)
    {
        $definition = $this->definitions[$offset];

        if ($definition instanceof \Closure) {
            return $this->instances[$offset] = $definition();
        }

        if (is_object($definition)) {
            return $this->instances[$offset] = $definition;
        }

        if (is_array($definition)) {
            $class = $definition['class'];
            $reflection = new \ReflectionClass($class);

            $dependencies = [];
            // ... omit reflection implementation code
            $object = $reflection->newInstanceArgs($dependencies);
            return $this->instances[$offset] = $object;
        }

        throw new \Exception('Illegal object definition');
    }
}

Reference resources

Predefined interface

Keywords: PHP Laravel

Added by cheechm on Fri, 06 Dec 2019 13:55:26 +0200