0

Listing a link from PHP's documentation Countable::count, how does the first example works?

<?php
class myCounter implements Countable {
    private $count = 0;
    public function count() {
        return ++$this->count;
    }
}

$counter = new myCounter;

for($i=0; $i<10; ++$i) {
    echo "I have been count()ed " . count($counter) . " times\n";
}

Is it possible for the function count to access the private field $count in the class myCounter, and how?

5
  • The count() function returns the amount of times. So not really. Commented Jun 13, 2016 at 14:19
  • 2
    Can you clarify which function you refer to when you say "the function count" - do you mean the function contained within myCounter, or do you mean the PHP function, count? One has access to $count, the other doesn't... Commented Jun 13, 2016 at 14:22
  • 1
    The method is executed when using the count() function on an object implementing Countable. Commented Jun 13, 2016 at 14:24
  • I suppose you wanted to do $counter->count(), right? Commented Jun 13, 2016 at 14:26
  • From your own link: "This method is executed when using the count() function on an object implementing Countable.". You could just call $counter->count(). Commented Jun 13, 2016 at 14:27

5 Answers 5

6

The PHP count function is not accessing the private $count. What is actually happening is this:

  1. count (the PHP function) is called with the argument $counter
  2. The function tests if $counter is an array, it isn't. It checks if $counter implements the interface Countable.
  3. Because $counter does implement the interface Countable, it has a public method count (separate from the PHP function).
  4. PHP calls $counter->count(), then returns its result.

As you can see, there was no mention of the private $count. The public count method can do whatever a regular class method can – including accessing the instance's private variables. Consider this:

class myCounter implements Countable {
    public function count() {
        return 42;
    }
}

$counter = new myCounter;
echo "I have " . count($counter) . " items.";

Which would result in:

I have 42 items.
Sign up to request clarification or add additional context in comments.

Comments

2

The php function count(arg) accept as argument an array or a Countable object. A Countable is an instance of a Class that implements the Countable interface: it means that it must have a count method that returns an integer number. How you implement it, it's up to you. You can keep the count with a variable like in the example, or you can return a random number, or whatever you want. So to answer your question, no the count() function does not access the private field $count, but it calls the count method implemented by the class.

Comments

1

This is just a basic example that is just incrementing a variable everytime count is run. You could easily swap this out with something like:

class Repository implements Countable {
    private $data = [];
    public function count() {
        return count($this->data);
    }
}

This is another example of a repository that contains records in the $data property. Using count($instanceOfRepository) will return the count of $data.

Comments

1

count function doesn't access private field $count in your class. It calls public method count described in the Countable interface.

This particular example is a little bit weird because it actually counts how many times count function was called and it might confuse the reader.

Comments

0

I'll also share some thoughts on this question.

First, the example on php.net is incorrect from an OOP perspective because it violates a couple of principles at once. Yes, it demonstrates the concept of Countable, but in a misleading way.

A more proper approach should look like this:

class Counter implements Countable
{
    private $count = 0;

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

    public function increment(): void
    {
        $this->count++;
    }
}

$counter = new Counter;

for ($i = 0; $i < 10; ++$i) {
    $counter->increment();
    echo "I have been incremented " . count($counter) . " times\n";
}

This is a proper OOP approach, where count() simply returns the number of elements, and increment() is used to change the state of the object.

The second point to consider is how you organize your code. If you're strictly using type hints and working with an object that implements Countable, the correct way to interact with it is via $object->count(). If you're unsure whether the object is Countable or just an array, then count($object) is acceptable, but ideally, you should handle this with proper type checking.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.