Динамическое заполнение статической переменной в PHP

У меня есть два статических значения: «type» и «typeID». Тип является читаемым человеком и постоянным, а typeID необходимо искать из базы данных на основе значения типа. Мне нужно, чтобы поиск выполнялся один раз, когда сначала загружается определение класса

Чтобы проиллюстрировать, вот какой-то код, который не работает, потому что вы не можете вызывать функции в пространстве декларации.

MyClass extends BaseClass { protected static $type = "communities"; protected static $typeID = MyClass::lookupTypeID(self::$type); } 

Есть ли волшебный метод, который вызывается ровно один раз, когда загружается определение класса? Если есть что-то очевидное, я пропущу его.

бесстыдно вытащил из статических комментариев ключевого слова php manual:

 Because php does not have a static constructor and you may want to initialize static class vars, there is one easy way, just call your own function directly after the class definition. for example. <?php function Demonstration() { return 'This is the result of demonstration()'; } class MyStaticClass { //public static $MyStaticVar = Demonstration(); //!!! FAILS: syntax error public static $MyStaticVar = null; public static function MyStaticInit() { //this is the static constructor //because in a function, everything is allowed, including initializing using other functions self::$MyStaticVar = Demonstration(); } } MyStaticClass::MyStaticInit(); //Call the static constructor echo MyStaticClass::$MyStaticVar; //This is the result of demonstration() ?> 

Простая и не требующая магии, не забывайте, что вы всегда можете определить переменную как нуль и проверить, что она равна нулю (только тогда вызов db). Тогда это просто вопрос, хотите ли вы, чтобы это произошло, когда класс был построен или включен (include_once и т. Д.)

 MyClass extends BaseClass { protected static $type = "communities"; protected static $typeID = null; public function __construct(){ if(is_null(self::$typeID)){ self::lookupTypeID(self::$type); } } public static lookupTypeID($type){ self::$typeID = //result of database query } } 

или

 MyClass::lookupTypeID(); //call static function when class file is included (global space) MyClass extends BaseClass { protected static $type = "communities"; protected static $typeID = null; public function __construct(){ } public static lookupTypeID($type=null){ if(is_null($type)){ $type = self::$type; } self::$typeID = //result of database query (SELECT somefield FROM sometable WHERE type=$type) etc.. } } 

статический конструктор больше похож на заводский метод

 if(!function_exists(build_myclass)){ function build_myclass(){ return MyClass::build(); } } MyClass extends BaseClass { protected static $type = "communities"; protected static $typeID = null; public function __construct(){ } public static function build(){ return new self(); //goes to __construct(); } } $class = new MyClass(); //or $class = MyClass::build(); //or $class = build_myclass(); 

Такую вещь обычно называют «статическим конструктором», но PHP не хватает таких вещей. Возможно, вы захотите рассмотреть один из обходных путей, предложенных в комментариях к PHP, например http://www.php.net/manual/en/language.oop5.static.php#95217