Статические переменные PHP в абстрактных классах - PullRequest
6 голосов
/ 17 октября 2011

Я работаю над проектом, в котором я хотел бы иметь возможность объявлять статическую переменную-член внутри абстрактного базового класса. У меня есть класс Model, промежуточный класс Post и, наконец, класс Post для конкретного сайта, что-то вроде следующего:

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();
    }

    ...
}

Я бы хотел, чтобы из класса Model было очевидно, что требуются члены $ _table и $ _database. Однако $ _table действительно статичен с точки зрения класса PostModel, а $ _database действительно статичен с точки зрения класса SitePostModel.

Это законный способ достижения моей цели? Означает ли объявление статических переменных в самой модели, что они должны существовать только один раз для абстрактного базового класса или только один раз для фактического экземпляра класса?

Ответы [ 2 ]

1 голос
/ 28 октября 2011

Это законный способ достижения моей цели?

Нет. Он не работает, поэтому не проходит базовый тест на легитимность.

Означает ли объявление статических переменных в самой модели, что они должны существовать только один раз для абстрактного базового класса или только один раз для фактического экземпляра класса?

Статические переменные являются глобальными, они существуют один раз. В вашем случае для каждого имени класса. Если у вас есть три имени класса, у вас будет три (глобальные) переменные. Защищенное ключевое слово контролирует только видимость / область действия трех статических переменных:

<?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
0 голосов
/ 15 октября 2012

Недавно я столкнулся с той же проблемой и пришел к тому же решению - поместить настройки в статические переменные и получить к ним доступ с помощью ключевого слова static.Это также работает в тех случаях, когда у вас есть настройки по умолчанию (например, количество строк на странице), которые вы можете переопределить в подклассах.Это только казалось наиболее интуитивным и эффективным способом.

Альтернативы, которые я рассмотрел:

  • Используйте статическую абстрактную функцию получения.Для этого требуется больше строк кода и больше вызовов функций.
  • Сохраните настройку в нестатической переменной-члене и позвольте конструктору дочернего класса беспокоиться об этом.Я отклонил эту опцию, потому что моим дочерним классам иначе не требовался конструктор.
...