PHP - 函数的静态变量

时间:2012-12-05 23:49:09

标签: php function methods static

在C中我们可以做到(如果我记得很清楚):

void foo()
{
    static bool firstCall = true;

    if(firstCall)
    {
        // stuff to do on first call

        firstCall = false;
    }

    // more stuff
}

我想在PHP中这样做,以避免我的模型在多次调用相同的方法时多次查询数据库。

class User
{
    public static function & getAll($reload = false)
    {
        static $result = null;

        if($reload && null === $result)
        {
            // query the database and store the datas in $result
        }

        return $result;
    }
}

允许吗?它有用吗?它是否与PHP兼容< 5.3?

如果是,那么我有另一个问题:

假设我们有几种通用于所有模型的方法,我会将它们分组在一个抽象基类中:

abstract class AbstractModel
{
    public static function & getAll($tableName, $reload = false)
    {
        static $result = array();

        if($reload && !isset($result[$tableName]))
        {
            // query the database depending on $tableName,
            // and store the datas in $result[$tableName]
        }

        return $result[$tableName];
    }
}

class User extends AbstractModel
{
    public static function & getAll($reload = false)
    {
        $result = parent::getAll('users', $reload);
        return $result;
    }
}

class Group extends AbstractModel
{
    public static function & getAll($reload = false)
    {
        $result = parent::getAll('groups', $reload);
        return $result;
    }
}

这会有效吗?可以改进吗?

感谢您的帮助:)

1 个答案:

答案 0 :(得分:2)

是的,你可以这样做。从PHP 5.0.0开始支持它。

为了澄清我想区分PHP中两个使用static关键字的非常不同的东西。首先,是class static scope,它专门属于整个班级。第二,是variable static scope,它特别属于函数的局部范围。

这是类静态范围(仅在PHP> = 5.3.0中可用):

class Foo {
    public static $var;

    public static function GetVar() {
        return ++static::$var;
    }
}

var_dump(Foo::GetVar(),Foo::GetVar());

以上代码会为您提供int(1) int(2),这正是您所期望的。

这是变量静态范围(这在PHP> = 5.0.0中可用):

class Foo {
    public static function GetVar() {
        static $var = 0;
        return ++$var;
    }
}

var_dump(Foo::GetVar(),Foo::GetVar());

上面的代码也会给你int(1) int(2),这也是你所期待的。

请注意,一个特定于函数的本地范围(即使该函数是一个类成员),另一个特定于该类。

另请注意,我在第一个示例中使用了 static 关键字而不是 self 关键字,因为self不允许您执行 LSB Late Static Binding)。当你继承并调用父类时,这可能是你需要考虑的事情,特别是如果你要在函数的局部范围内使用类静态变量而不是静态变量。 / p>