【问题标题】:Accessing a public/private function inside a static function?在静态函数中访问公共/私有函数?
【发布时间】:2013-05-01 23:05:39
【问题描述】:

由于您不能在静态函数中使用 $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

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

【问题讨论】:

  • 如果你想调用它们,你必须将不访问$this的函数更改为静态函数。
  • 将类引用传递给您的静态方法。
  • 我该怎么做?就像在 hey() 中一样,返回 $this->get("hello")?
  • 对不起,但是……你真的了解静态和 oop 吗?请不要误会我的意思。
  • 你不能那样做。静态方法在类范围内操作,你不能访问实例方法,因为你必须实例化这个类的一个对象(例如单例模式)

标签: php oop methods


【解决方案1】:

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

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

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

如果您只需要一个实例,也可以使用singleton pattern(evaluate 此选项)。

【讨论】:

    【解决方案2】:

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

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

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

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

    【讨论】:

    • 其实对于工厂来说这是一个非常有效的模式。这也是重载构造函数的一种方式......在某种意义上。工厂 + 各种初始化函数。
    【解决方案3】:

    我通过在静态方法中创建相关类的对象来解决这个问题。这样我也可以将一些特定的公共函数公开为静态函数。其他公共功能只能使用$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(); 或 TokenManager::verifyToken("TokenHere"); 这样的令牌字符串,但我也可以发出像 $manager = new TokenGenerator(); 这样的令牌对象,因此我可以使用 $manager->createToken();、$manager->updateToken(updateObjectHere); 或 @987654330 这样的功能@

    【讨论】:

      猜你喜欢
      • 2015-04-02
      • 1970-01-01
      • 2012-05-29
      • 1970-01-01
      • 2016-01-09
      • 1970-01-01
      • 2019-10-02
      • 1970-01-01
      • 2015-09-13
      相关资源
      最近更新 更多