michaelxor
michaelxor

Reputation: 707

PHP Static Variables in Abstract Classes

I'm working on a project where I'd like to be able to declare a static member variable inside of an abstract base class. I've got a Model class, an intermediate Post class, and finally a site-specific Post class, something like the following:

abstract class Model {
    protected static $_table    = null;
    protected static $_database = null;

    ...
}

abstract class PostModel extends Model {
    public function __construct() {
        if ( !isset(self::$_table) ) {
            self::$_table = 'some_table';
        }

        parent::__construct();
    }

    ...
}

class SitePostModel extends PostModel {
    public function __construct() {
        if ( !isset(self::$_database) ) {
            self::$_database = 'some_database';
        }

        parent::__construct();
    }

    ...
}

I'd like to make it apparent from the Model class that the $_table and $_database members are required. However, $_table is really static from the point of view of the PostModel class, and $_database is really static from the point of view of the SitePostModel class.

Is this a legitimate way to accomplish my goal? Does declaring the static variables in the Model itself imply that they should exist only once for the abstract base class, or only once for the actual instantiated class?

Upvotes: 6

Views: 6532

Answers (2)

Jon Hulka
Jon Hulka

Reputation: 1319

I recently ran into the same problem and came to the same solution - putting settings into static variables and accessing them using the static keyword. It also works in cases where you have default settings (such as number of rows per page) that you might want to override in subclasses. This just seemed like the most intuitive and efficient way.

Alternatives I've considered:

  • Use a static abstract getter function. It requires more lines of code and more function calls.
  • Keep the setting in a non-static member variable and let the child class constructor worry about it. I rejected this option because my child classes didn't otherwise need a constructor.

Upvotes: 0

hakre
hakre

Reputation: 198247

Is this a legitimate way to accomplish my goal?

No. It does not work, so it fails a basic test for legitimacy.

Does declaring the static variables in the Model itself imply that they should exist only once for the abstract base class, or only once for the actual instantiated class?

Static variables are global, they exist once. In your case per each classname. If you have three classnames, you would have three (global) variables. The protected keyword only controls the visibility/scope of the three static variables:

<?php

class A {
   protected static $v = 'red';
   public static function get() { return self::$v . ' - ' . static::$v;}
}

class B extends A {
   protected static $v = 'blue';
}

class C extends B {
   protected static $v = 'green';
}

echo C::get(); # red - green

Upvotes: 2

Related Questions