Перегрузить поведение count() при вызове определенных объектов

Возможный дубликат:
Подсчет элементов для объектов, реализующих ArrayAccess с использованием count()?

В PHP 5 вы можете использовать магические методы, перегружать некоторые классы и т. Д. В C++ вы можете реализовывать функции, которые существуют до тех пор, пока типы аргументов различны. Есть ли способ сделать это в PHP?

Пример того, что я хотел бы сделать, это:

class a {
    function a() {
        $this->list = array("1", "2");
    }
}

$blah = new a();

count($blah);

Я хотел бы, чтобы бла вернул 2. IE подсчитывает значения определенного массива в классе. Таким образом, в C++ способ, которым я бы сделал это, мог бы выглядеть так:

int count(a varName) { return count(varName->list); }

По сути, я пытаюсь упростить вызовы данных для большого приложения, чтобы я мог позвонить и сделать это:

count($object);

скорее, чем

count($object->list);

Список будет потенциально списком объектов, поэтому, в зависимости от того, как он используется, это может быть очень неприятное утверждение, если кто-то должен сделать это текущим способом:

count($object->list[0]->list[0]->list);

Итак, я могу сделать что-то похожее на это:

function count(a $object) {
    count($object->list);
}

Я знаю, что число PHP принимает смешанную переменную, поэтому я не знаю, могу ли я переопределить отдельный тип.

2 ответа

Решение

Похоже, вы хотите реализовать Countable интерфейс:

class a implements Countable {
    public function __construct() {
        $this->list = array("1", "2");
    }

    public function count() {
      return count($this->list);
    }
}

$blah = new a();

echo count($blah); // 2

tl;dr - ответ внизу:)

В PHP эта модель обратная; вместо перегрузки функций (не методов) разными типами аргументов каждый класс предназначен для определения магических методов для каждой из этих функций.

Ниже приведен список функций, для которых можно определить магическое поведение внутри вашего класса. В примерах каждая ссылка на $obj это экземпляр вашего класса, ->unknown относится к отсутствующему свойству и ->blamethod() относится к отсутствующему методу.

  1. __toString() - этот метод вызывается, когда ваш объект используется в строковом контексте, например echo "My object is: $obj\n";

  2. __invoke([$arg1..n]) - когда ваш объект используется как функция, вызывается этот метод, например $obj($a, $b);

  3. __get($prop) - позволяет перехватить попытку доступа к несуществующему свойству вашего класса, например $obj->unknown; Между прочим, это иногда может использоваться как способ отложенной загрузки определенных свойств, которые в противном случае потребовали бы значительного объема обработки, когда выполнялись в конструкторе.

  4. __set($prop, $value) - вызывается при установке несуществующего свойства, например $obj->unknown = 42;

  5. __isset($prop) - вызывается для определения существования несуществующего свойства (я понимаю, как это смешно звучит), например isset($obj->unknown) назвал бы $obj->__isset('unknown')

  6. __unset($prop) - вызывается в таких случаях unset($obj->unknown);

  7. __call($name, $arguments) - перехватывает вызов нереализованного метода вашего класса, например $obj->blamethod(1, 2, 3); вызовет $obj->__call('blamethod', array(1, 2, 3));

  8. __callStatic($name, $arguments) - лайк __call() но вы не сможете использовать $this внутри вашей реализации.

  9. __clone () - вызывается когда $x = clone $obj; называется, так что вы можете решить, какие данные хранятся, а что выбрасываются.

С SPL было введено еще несколько концепций посредством реализации определенных интерфейсов:

  1. Traversable - абстрактный интерфейс, который определяет, что делает ваш класс при использовании в foreach строить; конкретный интерфейс называется Iterator,

  2. ArrayAccess - интерфейс, который позволяет использовать экземпляры вашего класса как массив.

  3. Serializable - интерфейс, который определяет два метода для вызова serialize() или же unserialize(), Это взаимоисключающее использование __sleep() а также __wakeup(),

  4. Countable - определяет один метод, который будет вызываться всякий раз, когда count() выполняется на вашем экземпляре класса.

Другие вопросы по тегам