我什么时候在php中使用静态变量/函数?

72 php oop static

我在使用PHP的OOP上刷新自己,我看到了将函数和/或变量设置为静态的示例.我何时以及为什么要将变量/函数设置为静态?我已经完成了其他语言,并且不记得曾经使用静态,我从来没有找到真正的目的.我知道它的作用,但为什么不只是使用变量呢?

e-s*_*tis 55

当您想要使用未绑定到实例的方法/变量时,可以使用static.这可能发生在:

  • 与您的目的和实例没有任何关系(对于不允许OOP之类的其他任何语言的工具箱很有用,但在PHP中没用).

  • 您想要控制对实例的访问.大多数情况下,您编写代码时未定义要处理的实例,但将在执行时执行.的单例模式是最好的例证.您可以使用静态方法作为工厂根据上下文创建对象或与其他实例共享资源.EG:静态成员可以访问数据库层,因此应用程序的一部分可以从任何地方访问同一个应用程序,并且可以打开/关闭而不会发生冲突.

  • 表演很重要,方法将被执行很多次.在这种情况下,您将节省一些CPU时间,以防止解释器在每次调用时将成员查找到实例.但是,如果你遇到这样的问题,那么你可能需要重新考虑你的体系结构,或者使用绑定到代码关键部分的更快的语言.

  • 您有一个与类型相关但将应用于另一个类型的方法.将方法写入第一种类型的声明是有意义的,但将其设置为静态,因为它需要另一种类型的实例.

完美的例子是一个String解析器:

class MyObject 
{
 static function parse($str)
 {
    $obj = new MyObject();
    // some parsing/setting happens here
    return $obj;
 }
}

// you create an object "MyObject" from a string, so it's more obvious
// to read it this way :
$new_obj = MyObject::parse("This a description of a super cool object");
Run Code Online (Sandbox Code Playgroud)

  • 在第四种情况的例子中,您实际上将它用作一种工厂,我将使用非静态函数.在这种情况下,使用静态函数的唯一实际需要将是单例及其所有实例控制表兄弟的第二种情况. (3认同)

Tyl*_*ter 22

静态函数和变量用于访问全局范围中的变量/函数,如下所示:

echo myClass::myVariable;
echo myClass::myFunction();
Run Code Online (Sandbox Code Playgroud)

当某些东西是静态的时,它可以在任何地方访问,并且与过程类型函数非常相似,除了它可以使用self并包含在类范围中.

class myClass{
    static $myVariable = "myVar";
    static function myFunction()
    {
       return "myFunc";
    }
}
Run Code Online (Sandbox Code Playgroud)

使用它的方法之一是只保留一个类的实例或Singleton方法.

class myClass
   {
    static $class = false;
    static function get_connection()
    {
        if(self::$class == false)
        {
            self::$class = new myClass;
        }
        else
        {
            return self::$class;
        }
    }
    private function __construct()
    {
         // my constructor
    }
    // Then create regular class functions.
   }
Run Code Online (Sandbox Code Playgroud)

因为它有一个私有构造函数,所以它不能用new运算符实例化,所以你被迫调用myClass::get_connection()来获取一个类.该函数可以创建新类(因为它是类的成员).然后它将类存储在静态变量中,如果再次调用该函数,它将只返回创建的类.

最后,static关键字用于保持对范围的引用,即静态.这意味着由于当前范围,您不希望任何"更改".虽然Singleton方法略微延伸了这一点,但它始终保持着相同的想法,即你总是拥有"相同"的类,无论你在什么范围内.

PHP文档
静态关键字
范围解析运算符

StackOverflow知识
如何避免使用PHP全局对象
在不使用全局变量的情况下在PHP中的函数之间共享变量
使全局变量可访问类中的每个函数全局变量
或单例数据库连接
PHP类:何时使用:: vs. - >?


prd*_*tur 10

如果一个方法经常被调用并做同样的事情,它对于缓存非常有用,例如:

/**
 * Returns true if the user is logged in through shibboleth
 *
 * @return boolean true on success, else false
 */
protected function is_logged_in() {

    //Check shibboleth headers
    if (!empty($_SERVER['HTTP_SHIB_IDENTITY_PROVIDER']) || !empty($_SERVER['Shib-Identity-Provider'])) {
        if (!empty($_SERVER[$this->core->dbconfig("shib_auth", self::SHIB_AUTH_CONFIG_UID)])) {
            return true;
        }
    }
    return false;
}
Run Code Online (Sandbox Code Playgroud)

这个方法将在我的框架中经常被调用,并且它会在每次调用时为我的配置$ _SERVER键进行数据库查找

因此,当页面被处理时,我在一个页面加载中调用可能10次,它将有10个数据库调用,但我将其更改为:

/**
 * Returns true if the user is logged in through shibboleth
 *
 * @return boolean true on success, else false
 */
protected function is_logged_in() {
    static $logged_in = null;
    if($logged_in != null) {
        return $logged_in;
    }

    //Check shibboleth headers
    if (!empty($_SERVER['HTTP_SHIB_IDENTITY_PROVIDER']) || !empty($_SERVER['Shib-Identity-Provider'])) {
        if (!empty($_SERVER[$this->core->dbconfig("shib_auth", self::SHIB_AUTH_CONFIG_UID)])) {
            $logged_in = true;
            return true;
        }
    }
    $logged_in = false;
    return false;
}
Run Code Online (Sandbox Code Playgroud)

因此,如果我登录并缓存结果,它只检查每次页面加载一次正常行为.下次它只返回缓存的值.我经常使用此功能来获得更多性能.

希望这可以帮助.


lan*_*nce 7

这是静态和实例方法之间差异的随机但非常好的描述.

从帖子:

实例方法是实例方法,因为它们依赖于特定对象实例的状态.实例方法与特定实例相关联,因为该方法调用的行为依赖于该特定实例的状态.

将方法声明为static时,将该方法定义为类方法.类方法适用于类而不是任何特定实例.类方法发起的行为不依赖于特定实例的状态.实际上,静态方法不能依赖实例的状态,因为静态方法无法访问此引用.相反,类方法的行为要么取决于所有对象在类级别共享的状态,要么完全独立于任何状态.

如果方法依赖于对象实例的状态,则它应该是实例方法.如果方法对于所有类或没有类的实例是通用的,并且不依赖于对象状态,则它应该是静态方法.实例方法是最常用的.然而,静态方法对于实用程序和工厂类非常有用,因为许多其他用途都是如此.