Исправление ошибки "Only variable references should be returned by reference" в PHP

Рассмотрим проблему, возникающую при реализации метода доступа к элементам массива с возвратом значения по ссылке. В представленном коде метод at() должен возвращать элемент массива по индексу, а при его отсутствии - значение null. Однако текущая реализация генерирует предупреждение PHP.

Проблема и её причина

Исходный код содержит класс MyStack с методом &at(), который объявлен с возвратом по ссылке. При использовании оператора null coalescing (??) для возврата статического свойства self::$_NULL возникает предупреждение:

PHP Notice: Only variable references should be returned by reference

Ошибка возникает потому, что оператор ?? возвращает значение, а не ссылку на переменную. Даже если self::$_NULL является переменной, результат выражения $this->a[$i] ?? self::$_NULL - это временное значение, на которое нельзя создать ссылку.

Корректное решение

Для правильной реализации необходимо явно проверять наличие элемента и возвращать ссылку только на существующую переменную. Вот исправленная версия класса:

class MyStack 
{
    private $a = [];
    private static $_NULL = null;

    public function __construct($arr = []) 
    {
        $this->a = (array)$arr;
    }
    
    public function &at($index)
    {
        if (isset($this->a[$index])) {
            return $this->a[$index];
        }
        
        return self::$_NULL;
    }
}

Ключевые изменения

  • Замена оператора ?? на явную проверку isset()
  • Возврат ссылки на элемент массива только при его существовании
  • Возврат статического свойства self::$_NULL как fallback-значения
  • Использование модификаторов доступа private и public вместо устаревшего var

Альтернативный подход

Если требуется сохранить логику с оператором ??, можно отказаться от возврата по ссылке и переработать интерфейс класса. Однако это изменит поведение кода, где происходит модификация возвращаемого объекта.

Представленное решение сохраняет исходную функциональность, устраняя предупреждение PHP и соблюдая требования к возврату значений по ссылке.