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

我正在用OOP刷新自己,我看到一个将函数和/或variables设置为静态的例子。 何时以及为什么要将variables/函数设置为静态? 我已经做了其他的语言,并没有真正记得使用静态,我从来没有find一个真正的目的。 我知道它做什么,但为什么不只是使用一个variables呢?

当你想使用一个没有绑定到实例的方法/variables时,你使用静态的 。 这可能发生在:

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

  • 你想控制对实例的访问。 大多数情况下,当你编写代码时,你想要处理的实例没有被定义,而是会被执行。 Singleton模式就是最好的例子。 您可以使用静态方法作为工厂来根据上下文创build对象或与其他实例共享资源。 EG:静态成员可以访问数据库层,因此部分应用程序可以从任意位置访问同一个应用程序,并且可以打开/closures而不会发生冲突。

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

  • 你有一个与某个types相关的方法,但会被应用到另一个types。 将方法写入第一个types的声明是有意义的,但是将其设置为静态,因为它需要另一个types的实例。

完美的例子是一个stringparsing器:

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

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

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

当某些东西是静态的时候,它可以在任何地方被访问,并且与过程types函数非常相似,除了它可以使用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()来获得一个类。 该函数可以使新类(因为它是类的成员)。 然后它将类存储在一个静态variables中,如果再次调用该函数,它将简单地返回创build的类。

最后,使用static关键字来保持事物的稳定性。 这意味着你不想因为当前的范围而改变任何东西。 虽然辛格尔顿方法延伸了这一点,它保持相同的想法,你总是有“相同”的类,无论你在什么范围。

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

StackOverflow知识
如何避免使用PHP全局对象
在不使用全局variables的情况下在PHP中的函数之间共享variables
为一个类中的每个函数创build一个全局variables
全局或单一数据库连接
PHP类:何时使用::与 – >?

如果一个方法经常被调用,并且执行相同的操作,那么对于caching也是非常有用的,例如:

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

这个方法会在我的框架内被经常调用,并且在每次调用时都会为我的configuration$ _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; } 

所以,如果我login并caching结果,它只检查每一页加载一次正常的行为。 下次它只会返回caching的值。 我经常使用这个function来获得更多的性能。

希望这可以帮助。

下面是一个随机的,虽然相当不错的静态和实例方法之间的差异的描述 。

从post:

实例方法是实例方法,因为它们依赖于特定对象实例的状态。 实例方法绑定到特定实例,因为方法调用的行为依赖于特定实例的状态。

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

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

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

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

静态方法不过是名称空间的全局函数。 命名空间,我想我们都可以同意,是伟大的。 至于全球function:我们一直使用这些function。 PHP中的本地函数构成了我们的基本构build块。

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