开发者

Dynamically populating a static variable in PHP

开发者 https://www.devze.com 2023-03-06 20:13 出处:网络
I have two static values: \"type\" and \"typeID\".Type is human readable and constant,开发者_开发知识库 and typeID needs to be looked up from the database, based on the value of type.I need the lookup

I have two static values: "type" and "typeID". Type is human readable and constant,开发者_开发知识库 and typeID needs to be looked up from the database, based on the value of type. I need the lookup to happen once, when the class definition is first loaded

To illustrate, here is some code that doesn't work because you can't call functions in the declaration space.

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

Is there a magic method that is called exactly once when the class definition is loaded? If there is something obvious I'm missing it.


shamelessly pulled from the php manual's static keyword comments:

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()
?>


Simple and no magic needed, don't forget you can always define a variable as null and test that it is null (doing the db call only then). Then it's just a matter if you want that to happen when the class is constructed or included (include_once etc...)

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
    }
}

or

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..
    }
}

a static constructor is more like a factory method

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


Such a thing would normally be called a "static constructor", but PHP lacks such things. You might want to consider one of the workarounds suggested in the PHP manual comments, e.g. http://www.php.net/manual/en/language.oop5.static.php#95217

0

精彩评论

暂无评论...
验证码 换一张
取 消