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

问题描述 投票:71回答:8

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

php oop static
8个回答
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");

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


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键进行数据库查找

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

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

希望这可以帮助。


7
投票

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

从帖子:

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

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

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


3
投票

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


1
投票

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

  1. 首先,它们可以从脚本的任何位置获得(假设您可以访问该类)。这意味着您可以访问功能,而无需将类的实例从对象传递到对象,或者更糟糕的是,将实例存储在全局变量中。
  2. 其次,静态属性可用于类的每个实例,因此您可以设置希望对类型的所有成员可用的值。
  3. 最后,您不需要实例来访问静态属性或方法的事实可以使您免于实例化对象纯粹是为了获得简单的函数。

0
投票

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

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


0
投票

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

© www.soinside.com 2019 - 2024. All rights reserved.