我可以在类方法中使用静态关键字吗?它有什么后果


Can I use static keyword in class method? What consequence it has?

class Foo {
  private $items;
public function getItems() {
  static $loaded = FALSE;
  if (isset($this->items) && $loaded) {
     return $this->items;
  } else if ($loader = $this->getLoader()) {
    //logic for fetching items from other source;
    $this->loaded = TRUE;
  } else {
    $this->items = array();
  }
  return $this->items;
}
}

使用静态变量或更好地引入类属性是否有效?不是每个类实例都共享$loaded吗?(例如:类静态变量(?

两者都

是可能的(在方法中使用静态变量并使用私有静态类属性(。

静态

变量与静态类属性有何不同?

  1. 在到达行static $loaded = FALSE;之前,不会实例化静态变量。在下面的示例中,当您第一次调用 getItems(( 时,您将收到"未定义的变量:已加载"错误:

    function getItems()
    {
        var_dump($loaded);
        static $loaded = 1;
    }
    
  2. 静态变量仅存在于当前函数/方法的作用域中,因此无法从另一个方法读取或写入它,甚至无法从子类的getItems读取或写入它。在以下示例中,您还将收到"未定义的变量:已加载"错误:

    class Foo
    {
        public function getItems()
        {
            static $loaded = 1;
        }
    }
    class Bar extends Foo
    {
        public function getItems()
        {
            parent::getItems();
            var_dump($loaded);
        }
    }
    (new Bar)->getItems();
    

TL;DR:它基本上只是另一个局部变量,除了它在对同一方法的后续调用中保持其值(独立于对象!


另一个示例来证明变量独立于实际对象:

class Foo
{
    public function getItems()
    {
        static $loaded = 1;
        $loaded++;
        var_dump($loaded);
    }
}
$foo1 = new Foo;
$foo2 = new Foo;
$foo1->getItems();
$foo2->getItems();

输出:

int(2)
int(3)
方法

"getItems((" 是一个普通方法,除非创建类,否则无法调用。如果创建了类并且您调用了"getItems((",则静态变量"$loaded"设置为false,并且您的第一个if语句的计算结果始终为false。由于该静态是在"getItems(("方法中定义的,因此没有其他方法可以检查该值。所以基本上这是一个关于如何使用静态变量的非常糟糕的例子。

我相信你知道即使类被破坏,它们也会保留它们的值,但像这样的检查应该更好地放在 __construct 方法中,并在类范围内定义静态。这样,即使尚未创建类,您也可以始终验证该类是否已启动,或者使用它来检查它是否以其他方法加载。

但是要回答您的问题,是的,您可以。它们甚至可以放置在正常功能中。