Перегрузить поведение 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()
относится к отсутствующему методу.
__toString()
- этот метод вызывается, когда ваш объект используется в строковом контексте, напримерecho "My object is: $obj\n";
__invoke([$arg1..n])
- когда ваш объект используется как функция, вызывается этот метод, например$obj($a, $b);
__get($prop)
- позволяет перехватить попытку доступа к несуществующему свойству вашего класса, например$obj->unknown
; Между прочим, это иногда может использоваться как способ отложенной загрузки определенных свойств, которые в противном случае потребовали бы значительного объема обработки, когда выполнялись в конструкторе.__set($prop, $value)
- вызывается при установке несуществующего свойства, например$obj->unknown = 42;
__isset($prop)
- вызывается для определения существования несуществующего свойства (я понимаю, как это смешно звучит), напримерisset($obj->unknown)
назвал бы$obj->__isset('unknown')
__unset($prop)
- вызывается в таких случаяхunset($obj->unknown);
__call($name, $arguments)
- перехватывает вызов нереализованного метода вашего класса, например$obj->blamethod(1, 2, 3);
вызовет$obj->__call('blamethod', array(1, 2, 3));
__callStatic($name, $arguments)
- лайк__call()
но вы не сможете использовать$this
внутри вашей реализации.__clone () - вызывается когда
$x = clone $obj;
называется, так что вы можете решить, какие данные хранятся, а что выбрасываются.
С SPL было введено еще несколько концепций посредством реализации определенных интерфейсов:
Traversable
- абстрактный интерфейс, который определяет, что делает ваш класс при использовании вforeach
строить; конкретный интерфейс называетсяIterator
,ArrayAccess
- интерфейс, который позволяет использовать экземпляры вашего класса как массив.Serializable
- интерфейс, который определяет два метода для вызоваserialize()
или жеunserialize()
, Это взаимоисключающее использование__sleep()
а также__wakeup()
,Countable
- определяет один метод, который будет вызываться всякий раз, когдаcount()
выполняется на вашем экземпляре класса.