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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/1257371/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-25 01:46:16  来源:igfitidea点击:

When do I use static variables/functions in php?

phpoopstatic

提问by

I am refreshing myself on OOP with PHP and I saw an example of setting functions and/or variables as static. When and why would I set a variable/function to static? I've done other languages and don't really recall ever using static, I never found a real purpose to it. I know what it does but why not just use a variable instead?

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

回答by e-satis

You use staticwhen you want to use a method / variable that is not tied to an instance. That can happen when :

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

  • There is no relation with your purpose and an instance (useful for toolboxes in languages that doesn't allow anything else that OOP like Java, but not useful in PHP).

  • You want to control the access to the instance. Most often, the instance you want to deal with is not defined when you write the code, but will be at execution. The Singleton patternis the best example. You can use static methods as factories to create an object according to the context or sharing resources with other instances. E.G : a static member can give access to a data base layer so part of the app accesses the same one from anywhere and it's opened/closed without conflicts.

  • Performances matter and the method will be executed a lot of times. In that case, you will save some CPU time preventing the interpreter from looking up the member to an instance at each call. But still, if perfs becomes such an issues that you come to this solution, it might time to reconsider your architecture, or the use of a binding to a faster language for the critical parts of the code.

  • You have a method that is related to a type but will be applied to another. It can make sense to write the method into the declaration of the first type, but set it static since it expects an instance of the another one.

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

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

  • 性能很重要,该方法将被执行很多次。在这种情况下,您将节省一些 CPU 时间,防止解释器在每次调用时查找成员到实例。但是,如果 perfs 成为您使用此解决方案的一个问题,那么可能是时候重新考虑您的架构,或者对代码的关键部分使用与更快语言的绑定。

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

The perfect example is a String parser :

一个完美的例子是一个字符串解析器:

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

回答by Tyler Carter

Static functions and variable are used to access Variables/functions in a global scope, like this:

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

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

When something is static, it can be accessed anywhere, and is very similar to a procedural type function, except it can use self and is contained in the classes scope.

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

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

One of the ways to use this is to keep only one instance of a class, or a Singleton Method.

使用它的一种方法是只保留一个类的一个实例,或一个单例方法。

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

Because it has a private constructor, it cannot be instantiated with the newoperator, so you are forced to call myClass::get_connection()to get a class. That function can make the new class (because it is a member of the class). Then it stores the class in a static variable, and if you call the function again, it will simply returned the created class.

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

In the end, the static keyword is used to keep things, well, static, in reference to scope. It means you don't want anything 'changing' because of the current scope. While the Singleton method stretches this a little, it keeps with the same idea that you always have the 'same' class, not matter what scope you are in.

最后, static 关键字用于使事物保持静态,以引用作用域。这意味着您不希望由于当前范围而发生任何“改变”。虽然 Singleton 方法对此进行了一些扩展,但它与始终拥有“相同”类的相同想法保持一致,无论您处于什么范围。

PHP Documentation
Static Keyword
Scope Resolution Operator

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

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

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

回答by prdatur

Also it is very usefull for caching if a method will be called very often and do just the same thing, for example:

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

/**
 * 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;
}

This method will be called within my framework very often and there it will do for every call a database lookup for my configuration $_SERVER key

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

So while the page is processed i call maybe 10 times in one page load it will have 10 database calls but i changed it to:

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

So it just check for every page load one time the normal behaviour if i logged in and cache the result. next time it will just return the cached value. This feature i use very often to have more performance.

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

Hope this helps.

希望这可以帮助。

回答by lance

Here's a random, though fairly good description of the differences between static and instance methods.

这是对静态方法和实例方法之间差异的随机但相当好的描述

From the post:

从帖子:

Instance methods are instance methods because they rely on the state of the specific object instance. Instance methods are tied to a particular instance because the behavior that the method invokes relies upon the state of that particular instance.

When you declare a method as static, you define that method as being a class method. A class method applies to the class as opposed to any particular instance. The behavior instigated by a class method does not rely on the state of a particular instance. In fact, a static method cannot rely on an instance's state since static methods lack access to this reference. Instead, the behavior of a class method either depends on a state that all objects share at the class level, or is independent of any state at all.

If a method relies on an object instance's state it should be an instance methods. If a method is general for all or no instances of a class, and does not rely on the object state, it should be a static method. Instance methods are most commonly used. However static methods are very useful for utility and factory classes amogst many other uses.

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

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

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

回答by ujwal dhakal

Generally using static function you can optimize the speed as well as memory and the scope of method should not be changed its should be static in nature and you can access the objects static properties ,methods without initiating them so saves the memory in mean time.

通常使用静态函数可以优化速度和内存,并且方法的范围不应改变,它本质上应该是静态的,您可以访问对象的静态属性,方法而无需启动它们,因此同时节省了内存。

回答by Dhairya Lakhera

Static elements have a number of characteristics that can be useful.

静态元素有许多有用的特性。

  1. First, they are available from anywhere in your script (assuming that you have access to the class). This means you can access functionality without needing to pass an instance of the class from object to object or, worse, storing an instance in a global variable.

  2. Second, a static property is available to every instance of a class, so you can set values that you want to be available to all members of a type.

  3. Finally, the fact that you don't need an instance to access a static property or method can save you from instantiating an object purely to get at a simple function.

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

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

  3. 最后,您不需要实例来访问静态属性或方法这一事实可以使您免于仅仅为了获得一个简单的函数而实例化一个对象。

回答by palash140

If you want to share data with all instances, like counter for number of instances created on current execution .

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

回答by Hamm

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

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

Static methods are nothing more than namespaced global functions. Namespacing, I think we can all agree on, is great. As for global functions: We use those all the time. The native functions in PHP form our basic building blocks.

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