Skip to content
Advertisement

Static counter of subclass instances in PHP

I’m aware of a pattern for adding a static counter to a class to count the number of instances of that class

class Vehicle
{
  private static $_count=0;

  public static function getCount() {
    return self::$_count;
  }

  public function __construct()
  {
    self::$_count++;
  }
}

What I would like to do is to add a couple of subclasses to Vehicle and count instances of those independently

class Bike extends Vehicle
{
   ...
}

class Car extends Vehicle 
{
   ...
}

So calling Bike::getCount() and Car::getCount() would get the count of the number of Bikes and Cars respectively

Is this possible without

  • repeating code in the subclasses?
  • setting up some kind of counting array keyed by class name in the superclass?

Advertisement

Answer

A lot depends on where you define the count and how you access it. If you have 1 count in the base class, then there is only 1 count. If you have a count in each class, then you need to be aware of how to access the right value. Using self or static is discussed more What is the difference between self::$bar and static::$bar in PHP?

class Vehicle
{
    protected static $_count=0;

    public static function getCount() {
        return static::$_count;
    }

    public function __construct($type, $year)
    {
        // Access the count in the current class (Bike or Car).
        static::$_count++;
        // Access the count in this class
        self::$_count++;
    }
}

class Bike extends Vehicle
{
    protected static $_count=0;
}

class Car extends Vehicle
{
    protected static $_count=0;
}

This has both, and in the constructor, it increments them both. This means there is a total of all vehicles and of each type…

echo "Vehicle::getCount()=".Vehicle::getCount().PHP_EOL;
echo "Car::getCount()=".Car::getCount().PHP_EOL;
echo "Bike::getCount()=".Bike::getCount().PHP_EOL;
$a = new Car("a", 1);
echo "Vehicle::getCount()=".Vehicle::getCount().PHP_EOL;
echo "Car::getCount()=".Car::getCount().PHP_EOL;
echo "Bike::getCount()=".Bike::getCount().PHP_EOL;
$a = new Bike("a", 1);
echo "Vehicle::getCount()=".Vehicle::getCount().PHP_EOL;
echo "Car::getCount()=".Car::getCount().PHP_EOL;
echo "Bike::getCount()=".Bike::getCount().PHP_EOL;

gives (not very clear though)…

Vehicle::getCount()=0
Car::getCount()=0
Bike::getCount()=0
Vehicle::getCount()=1
Car::getCount()=1
Bike::getCount()=0
Vehicle::getCount()=2
Car::getCount()=1
Bike::getCount()=1
User contributions licensed under: CC BY-SA
9 People found this is helpful
Advertisement