Stefano
Stefano

Reputation: 3258

PHP ArrayAccess - multidimensional array and offsetGet with reference

I read a lot of past questions about ArrayAccess PHP interface and it's method offsetGet that can return a reference. I have a simple class implementing this interface that wraps a variable of type array. The offsetGet method returns a reference, however I get an error saying Only variable references should be returned by reference. Why?

class My_Class implements ArrayAccess {
    private $data = array();

    ...

    public function &offsetGet($offset) {
        return isset( $this->data[ $offset ] ) ? $this->data[ $offset ] : null;
    }

    ...
}

I would like to be able to use multidimensional arrays with this class:

$myclass = new My_Class();

$myclass['test'] = array();
$myclass['test']['test2'] = array();
$myclass['test']['test2'][] = 'my string';

Upvotes: 0

Views: 966

Answers (3)

Pierre-Olivier Vares
Pierre-Olivier Vares

Reputation: 1769

In this code :

public function &offsetGet($offset) {
    $returnValue = isset( $this->data[ $offset ] ) ? $this->data[ $offset ] : null;
    return $returnValue;
}

$returnValue is a copy of $this->data[$offset], not a reference.

You have to make itself a reference, and for that you have to replace the ternary operator with an if statement :

public function &offsetGet($offset) {
    if (isset($this->data[$offset]) {
        $returnValue &= $this->data[$offset]; // note the &=
    }
    else {
        $returnValue = null;
    }
    return $returnValue;
}

should do the trick.

For the non-existent case, I'd rather throw an Exception, like the one you got when asking for a non-existing key of an array. Since the value you return won't be a reference,

$myclass['non-existing']['test2'] = array();

will presumably throw an indirect overloaded modification error, and should therefore be forbidden.

Upvotes: 1

Nalin Singapuri
Nalin Singapuri

Reputation: 463

The method '&offsetGet' is returning a reference (pointer) to a variable.

You need to either modify the method signature from '&offsetGet' to 'offsetGet' or use a variable to hold the return value.

// modify method signiture
public function offsetGet($offset) {
    return isset( $this->data[ $offset ] ) ? $this->data[ $offset ] : null;
}

// or use a variable to hold the return value.
public function &offsetGet($offset) {
    $returnValue = isset( $this->data[ $offset ] ) ? $this->data[ $offset ] : null;
    return $returnValue;
}

Upvotes: 0

Arron
Arron

Reputation: 916

I think this is becuase you are returning the result of an expression, not a variable. Try writing the if statement out and return the actual variable.

see php manual -> second note

Upvotes: 0

Related Questions