Overload the behavior of count() when called on certain objects [duplicate]
Asked Answered
F

2

16

Possible Duplicate:
Count elements for objects implementing ArrayAccess using count()?

In PHP 5, you can use magic methods, overload some classes, etc. In C++, you can implement functions that exist as long as the argument types are different. Is there a way to do this in PHP?

An example of what I'd like to do is this:

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

$blah = new a();

count($blah);

I would like blah to return 2. IE count the values of a specific array in the class. So in C++, the way I would do this might look like this:

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

Basically, I am trying to simplify data calls for a large application so I can call do this:

count($object);

rather than

count($object->list);

The list is going to be potentially a list of objects so depending on how it's used, it could be really nasty statement if someone has to do it the current way:

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

So, can I make something similar to this:

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

I know PHP's count accepts a mixed var, so I don't know if I can override an individual type.

Fuge answered 14/12, 2011 at 18:52 Comment(2)
Note: You can't overload STL functions...Impart
It tells you the answer on the count docs page. "For objects, if you have SPL installed, you can hook into count() by implementing interface Countable. The interface has exactly one method, Countable::count(), which returns the return value for the count() function."Individually
S
35

It sounds like you want to implement the Countable interface:

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
Straw answered 14/12, 2011 at 18:54 Comment(0)
L
23

tl;dr - answer is at the bottom :)

In PHP, this model is reversed; rather than overloading functions (not methods) with different argument types, each class is meant to define magic methods for each of those functions.

Below is the list of functions that magic behaviour can be defined for inside your class. In the examples, each reference to $obj is an instance of your class, ->unknown refers to a missing property and ->blamethod() refers to a missing method.

  1. __toString() - this method is called when your object is used in a string context, e.g. echo "My object is: $obj\n";

  2. __invoke([$arg1..n]) - when your object is used as a function, this method gets called, e.g. $obj($a, $b);

  3. __get($prop) - allows for intercepting an attempt to access a non-existing property of your class, e.g. $obj->unknown; btw, this can sometimes be used as a way to lazy load certain properties that would otherwise take a considerable amount of processing when done in the constructor.

  4. __set($prop, $value) - gets called when a non-existing property is being set, e.g. $obj->unknown = 42;

  5. __isset($prop) - called to determine the existence of a non-existing property (I realize how funny that sounds), e.g. isset($obj->unknown) would call $obj->__isset('unknown')

  6. __unset($prop) - called in cases like these unset($obj->unknown);

  7. __call($name, $arguments) - intercepts a call to an unimplemented method of your class, e.g. $obj->blamethod(1, 2, 3); will invoke $obj->__call('blamethod', array(1, 2, 3));

  8. __callStatic($name, $arguments) - like __call() but you will not be able to use $this inside your implementation.

  9. __clone() - called when $x = clone $obj; is called, so you get to decide what data is kept and what's thrown away.

With SPL, a few more concepts were introduced by means of implementing certain interfaces:

  1. Traversable - an abstract interface that defines what your class does when used in a foreach construct; the concrete interface is called Iterator.

  2. ArrayAccess - an interface that allows using instances of your class to be used like an array.

  3. Serializable - an interface that defines two methods to be called upon serialize() or unserialize(). It's mutually exclusive to using __sleep() and __wakeup().

  4. Countable - defines one method to be called whenever count() is performed on your class instance.

Lazare answered 3/9, 2012 at 9:36 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.