8

由于您不能在静态函数中使用 $this->,您应该如何访问静态函数中的常规函数​​?

private function hey()
{
    return 'hello';
}

public final static function get()
{
    return $this->hey();
}

这会引发错误,因为您不能在静态中使用 $this->。

private function hey()
{
    return 'hello';
}

public final static function get()
{
    return self::hey();
}

这会引发以下错误:

Non-static method Vote::get() should not be called statically

如何访问静态方法中的常规方法?在同一个班*

4

3 回答 3

7

您可以提供对静态方法的实例的引用:

class My {
    protected myProtected() {
        // do something
    }

    public myPublic() {
        // do something
    }

    public static myStatic(My $obj) {
        $obj->myProtected(); // can access protected/private members
        $obj->myPublic();
    }

}

$something = new My;

// A static method call:
My::myStatic($something);

// A member function call:
$something->myPublic();

如上所示,静态方法可以访问它们所属的类的对象上的私有成员和受保护成员(属性和方法)。

或者,如果您只需要一个实例,您可以使用单例模式评估此选项)。

于 2013-05-07T21:09:03.623 回答
7

静态方法只能调用类中的其他静态方法。如果要访问非静态成员,则方法本身必须是非静态的。

或者,您可以将对象实例传入静态方法并访问其成员。由于静态方法与您感兴趣的静态成员在同一个类中声明,它应该仍然可以工作,因为 PHP 中的可见性是如何工作的

class Foo {

    private function bar () {
        return get_class ($this);
    }

    static public function baz (Foo $quux) {
        return $quux -> bar ();
    }
}

但请注意,仅仅因为您可以这样做,您是否应该这样做是值得怀疑的。这种代码破坏了良好的面向对象编程实践。

于 2013-05-07T21:11:33.463 回答
0

我通过在静态方法中创建相关类的对象来解决这个问题。这样我也可以将一些特定的公共函数公开为静态函数。其他公共功能只能像$object->public_function();

一个小代码示例:

class Person
{
  public static function sayHi()
  {
    return (new Person())->saySomething("hi");
  }

  public function saySomething($text)
  {
    echo($text);
  }

  private function smile()
  {
    # dome some smile logic
  }
}

这样,您只能说hi是否使用静态函数,但您也可以在创建对象时说其他内容,例如$peter->saySomething('hi');. 公共函数也可以通过这种方式使用私有函数。

请注意,我不确定这是否是最佳实践,但它适用于我希望能够生成令牌而无需每次都手动创建对象的情况。

例如,我可以简单地发出或验证一个令牌字符串,例如TokenManager::getTokenToken();orTokenManager::verifyToken("TokenHere");但我也可以发出一个令牌对象,$manager = new TokenGenerator();这样我就可以使用功能$manager->createToken();$manager->updateToken(updateObjectHere);或者$manager->storeToken();

于 2021-07-22T07:29:51.997 回答