Можно ли перегрузить операторы в PHP?

В частности, я хотел бы создать класс Array и хотел бы перегрузить оператор [].

Ответы

Ответ 1

Если вы используете PHP5 (и вы должны быть), ознакомьтесь с классами SPL ArrayObject. Документация не слишком хорошая, но я думаю, что если вы расширите ArrayObject, у вас будет свой "поддельный" массив.

EDIT: Вот мой быстрый пример; Боюсь, у меня нет полезного варианта:

class a extends ArrayObject {
    public function offsetSet($i, $v) {
        echo 'appending ' . $v;
        parent::offsetSet($i, $v);
    }
}

$a = new a;
$a[] = 1;

Ответ 2

На самом деле оптимальным решением является реализация четырех методов интерфейса ArrayAccess: http://php.net/manual/en/class.arrayaccess.php

Если вы также хотели бы использовать свой объект в контексте "foreach", вам необходимо реализовать интерфейс "Итератор": http://www.php.net/manual/en/class.iterator.php

Ответ 3

PHP-концепция перегрузки и операторов (см. Overloading и Array Operators) не похож на концепцию С++. Я не верю, что можно перегрузить операторы, такие как +, -, [] и т.д.

Возможные решения

Ответ 4

Для простого и чистого решения в PHP 5.0+ вам необходимо реализовать ArrayAccess интерфейс и переопределить функции offsetGet, offsetSet, offsetExists и offsetUnset. Теперь вы можете использовать объект как массив.

Пример:

<?php
class A implements ArrayAccess {
    private $data = array();

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

    public function offsetSet($offset, $value) {
        if ($offset === null) {
            $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]);
    }
}

$obj = new A;
$obj[] = 'a';
$obj['k'] = 'b';
echo $obj[0], $obj['k']; // print "ab"

Ответ 5

Кажется, что это не особенность языка, см. этот bug. Однако, похоже, что package, который позволяет выполнять какую-то перегрузку.

Ответ 6

Проще говоря, нет; и я бы предположил, что если вы считаете, что вам нужна перегрузка в стиле С++, вам может потребоваться переосмыслить решение вашей проблемы. Или, возможно, не стоит использовать PHP.

Перефразируя Джейми Завински: "У вас есть проблема и подумайте", я знаю, я буду использовать перегрузку оператора! " Теперь у вас есть две проблемы.