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

时间:2009-08-10 21:41:40

标签: php oop static

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

8 个答案:

答案 0 :(得分:54)

如果要使用未绑定到实例的方法/变量,请使用 static 。这可能发生在:

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

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

  • 表演很重要,方法会被执行很多次。在这种情况下,您将节省一些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");

答案 1 :(得分:22)

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

echo myClass::myVariable;
echo myClass::myFunction();

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

class myClass{
    static $myVariable = "myVar";
    static function myFunction()
    {
       return "myFunc";
    }
}

使用它的方法之一是只保留一个类的实例或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.
   }

因为它有私有构造函数,所以无法使用new运算符进行实例化,因此您不得不调用myClass::get_connection()来获取类。该函数可以创建新类(因为它是类的成员)。然后它将类存储在静态变量中,如果再次调用该函数,它将只返回创建的类。

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

PHP文档
Static Keyword
Scope Resolution Operator

StackOverflow知识
How to Avoid Using PHP Global Objects
Share Variables Between Functions in PHP Without Using Globals
Making a Global Variable Accessible For Every Function inside a Class
Global or Singleton for Database Connection
PHP Classes: when to use :: vs. -> ?

答案 2 :(得分: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;
}

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

因此,当页面被处理时,我在一个页面加载中调用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;
}

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

希望这有帮助。

答案 3 :(得分:7)

这是一个随机的,但是fairly good description of the differences between static and instance methods

来自帖子:

  

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

     

将方法声明为static时,将该方法定义为a   类方法。类方法适用于类而不是任何类   特殊情况。类方法引发的行为确实如此   不依赖于特定实例的状态。其实是静态的   因为静态方法缺乏,所以方法不能依赖实例的状态   访问此参考。相反,类方法的行为   要么取决于所有对象在班级共享的状态,   或完全独立于任何州。

     

如果方法依赖于对象实例的状态,那么它应该是一个   实例方法。如果一个方法对于所有或没有a的实例是通用的   类,并不依赖于对象状态,它应该是静态的   方法。实例方法是最常用的。然而静态   方法对于实用程序和工厂类非常有用   其他用途。

答案 4 :(得分:3)

一般使用静态函数你可以优化速度和内存,方法的范围不应该改变它本质上应该是静态的,你可以访问对象的静态属性,方法而不启动它们所以节省内存的意思时间。

答案 5 :(得分:1)

静态元素具有许多有用的特征。

  1. 首先,它们可以从您脚本的任何位置获得(假设您可以访问该类)。这意味着您可以访问功能,而无需将类的实例从对象传递到对象,或者更糟糕的是,将实例存储在全局变量中。

  2. 其次,静态属性可用于类的每个实例,因此您可以设置希望对类型的所有成员可用的值。

  3. 最后,您不需要实例来访问静态属性或方法,这样可以避免实例化对象,只是为了获得简单的函数。

答案 6 :(得分:0)

访问:http://verraes.net/2014/06/when-to-use-static-methods-in-php/

  

静态方法只不过是命名空间的全局函数。命名空间,我想大家都同意,很棒。至于全球功能:我们一直使用这些功能。 PHP中的本机函数构成了我们的基本构建块。

答案 7 :(得分:0)

如果要与所有实例共享数据,例如计算当前执行时创建的实例数。