PHP: Иерархия классов со статическими членами

#php #class #static

#php #класс #статический

Вопрос:

У меня есть эта система, над которой я работаю:

 abstract class Model {
    static $table = "";
    abstract static function init();

    public static function getById() {
        $table = self::$table;
    }
}

class Model_user extends Model {
    static function init() {
        self::$table = "users";
    }
}

class Model_post extends Model {
    static function init() { self::$table = "post"; }
}

// ...

Model_user::init();
Model_post::init();
$user = Model_user::getById(10);
$post = Model_user::getById(40);
  

Я хочу, чтобы каждый подкласс имел свой собственный набор статических членов, к которым могут быть доступны статические функции в модели. Я не могу использовать ключевое слово static ::, потому что я должен использовать PHP 5.2.16. К сожалению, я не могу просто сказать «self::» из-за проблемы с PHP, выявленной в приведенном ниже примере:

 class Foo {
    static $name = "Foo";

    static function printName() {
        echo self::$name;
    }
}

class Bar extends Foo {
    static $name = "Bar";
}

class Foobar extends Foo {
    static $name = "Foobar";
}

Bar::printName();
echo "<br />";
Foobar::printName();
  

Который отображает:

 Foo<br />Foo
  

Когда это должно отображаться:

 Bar<br />Foobar
  

Каким-либо образом это можно было бы сделать?

Ответ №1:

Кажется, вы не можете получить доступ к статическим членам дочерних классов в коде статического метода родительского. Решение было опубликовано в этом комментарии к документации php о ключевом слове static. Решением было бы сделать вашу табличную переменную массивом такой формы:

 $table = array ('classname' => 'tablename', 'secondClassname' => 'secondTablename');
  

Комментарии:

1. Я переработал свой класс, чтобы он был неабстрактным и принимал параметр типа, который является ключом к массиву, содержащему данные о модели, такие как структура таблицы. Я предполагаю, что это будет не так красиво, ну да ладно. Спасибо.

Ответ №2:

Все, что статично, принадлежит классу, а не объекту. Поэтому статические методы не наследуются от родительского класса и будут обращаться к членам только внутри класса, в котором они определены.

В Java такого рода вызов статического метода ( Foobar::printName() ) даже выдал бы ошибку.

Комментарии:

1. Тогда почему php даже не выдает ошибку строгих стандартов? Что именно вы подразумеваете под «не унаследованным»?

2. Я понимаю. тогда как следует реализовать систему, подобную той, о которой я упоминал, где каждый подкласс model может иметь статические заводские функции, которые используют статическую табличную переменную, специфичную для подкласса?

3. @Cosmic, вы не можете реализовать подобную систему. — @greg0ire, потому что PHP это не волнует? статические методы действительно принадлежат классу , обычные методы наследуются

4. Тогда есть какие-нибудь идеи, как, скажем, rails это делает? В rails большая часть функциональности моделей находится в суперклассе, но вы создаете подкласс, который расширяет модель, которая содержит все функциональные возможности суперкласса, включая статическую функциональность.

5. @halfdan : Я не вижу несовместимости между «принадлежностью к классу» и наследованием. Посмотрите на случай Animal класса : у него есть статический метод getCount() . Почему класс не смог Dog наследовать этот статический метод? Для меня это имеет смысл.