【问题标题】:call a static method inside a class?在类中调用静态方法?
【发布时间】:2011-01-13 07:48:20
【问题描述】:

如何从同一个类中的另一个方法调用静态方法?

$this->staticMethod();

$this::staticMethod();

【问题讨论】:

  • 您可能对此感兴趣(self vs. $this):stackoverflow.com/questions/151969/php-self-vs-this
  • 仅供参考,您的第一个示例是调用静态方法的实例变量,这是不可能的,因为静态方法是类的一部分,无法通过实例变量访问。
  • 你现在可以删除 $this 如果只使用静态方法并且没有实例存在,它不起作用。
  • 难以置信地找到这个问题和答案是多么困难。这是因为 PHP 没有将它们称为“类方法”或“类函数”。 眼球

标签: php


【解决方案1】:

【讨论】:

  • ...但是为什么呢? $this->staticMethod() 也可以。你能解释一下为什么 self::staticMethod() 更正确(如果是的话)吗?
  • @Ian Dunn 简而言之,$this 仅在对象已被实例化时才存在,并且您只能在现有对象中使用 $this->method。如果你没有对象,只是调用一个静态方法,并且你想在同一个类中调用另一个静态方法,你必须使用self::。所以为了避免潜在的错误(和严格的警告),最好使用self
  • 谢谢!在 laravel 中,我发现我不小心使用 $this 在扩展控制器上调用了静态方法,但直到代码被推送到 stage 时问题才浮出水面。没有错误回来,值只是0。小心这个,使用self::
【解决方案2】:

假设这是你的班级:

class Test
{
    private $baz = 1;

    public function foo() { ... }

    public function bar() 
    {
        printf("baz = %d\n", $this->baz);
    }

    public static function staticMethod() { echo "static method\n"; }
}

foo() 方法中,让我们看看不同的选项:

$this->staticMethod();

所以调用staticMethod() 作为实例方法,对吗?它不是。这是因为该方法被声明为public static,解释器会将其作为静态方法调用,因此它会按预期工作。有人可能会说,这样做会使代码中静态方法调用的发生变得不那么明显。

$this::staticMethod();

从 PHP 5.3 开始,您可以使用 $var::method() 来表示 <class-of-$var>::;这很方便,尽管上面的用例仍然非常规。所以这给我们带来了调用静态方法的最常见方式:

self::staticMethod();

现在,在您开始认为:: 静态调用运算符之前,让我再举一个例子:

self::bar();

这将打印baz = 1,这意味着$this->bar()self::bar() 做完全相同的事情;那是因为:: 只是一个范围解析运算符。它可以让parent::self::static:: 工作并让您访问静态变量;如何调用方法取决于其签名以及调用者的调用方式。

要查看所有这些操作,请参阅this 3v4l.org output

【讨论】:

  • self::bar() 似乎具有误导性 - 现在是否已弃用? (使用self:: 调用实例方法而不是静态方法)。
  • @ToolmakerSteve 你会以什么方式说它具有误导性?
  • 从逻辑上讲,调用静态方法时没有self。根据定义:静态方法可以从任何地方调用,并且不接收“self”参数。尽管如此,我看到php 语法的便利性,因此您不必编写MyClassName::。我习惯于静态类型语言,其中编译器必须提供当前范围内可用的所有变量,因此(相当于)self:: 可以省略。所以只说self instanceMethod;没有理由说self staticMethod
【解决方案3】:

这是一个很晚的回复,但在之前的答案中添加了一些细节

当在 PHP 中从同一类的另一个静态方法调用静态方法时,区分 self 和类名很重要。

以这段代码为例:

class static_test_class {
    public static function test() {
        echo "Original class\n";
    }

    public static function run($use_self) {
        if($use_self) {
            self::test();
        } else {
            $class = get_called_class();
            $class::test(); 
        }
    }
}

class extended_static_test_class extends static_test_class {
    public static function test() {
        echo "Extended class\n";
    }
}

extended_static_test_class::run(true);
extended_static_test_class::run(false);

这段代码的输出是:

原班

扩展类

这是因为self 指的是代码所在的类,而不是调用它的代码的类。

如果你想使用在继承原始类的类上定义的方法,你需要使用类似的东西:

$class = get_called_class();
$class::function_name(); 

【讨论】:

  • 我发现了这个信息。一个小笨蛋,我不会说其他答案是“误导性的”。更准确地说,它们是“不完整的”;他们没有解决 self:: 在(罕见的)静态方法 A 调用另一个静态方法 B 并且 B 已在子类中被覆盖的情况下所做的(未提出的)问题。恕我直言,将方法覆盖限制为“实例”方法就不那么令人困惑了;在静态级别上谨慎使用该能力。换句话说,您的代码的读者期望方法覆盖实例方法(这是 OO 编码的本质),而不是静态方法。
  • 非常有帮助,并且类的扩展不是原始类是有道理的。因此,在这种情况下不会使用self 是理所当然的。您已经声明了一个单独的类作为第一个类的扩展。在扩展类中使用self 将引用扩展类。这与其他答案并不矛盾,但它肯定有助于证明self 的范围。
【解决方案4】:

在以后的 PHP 版本中self::staticMethod(); 也将不起作用。它会抛出严格的标准错误。

在这种情况下,我们可以创建同一类的对象并按对象调用

这里是例子

class Foo {

    public function fun1() {
        echo 'non-static';   
    }

    public static function fun2() {
        echo (new self)->fun1();
    }
}

【讨论】:

  • 可以这样做,但如果fun1 没有使用self,那么将其作为实例方法是不合逻辑的。在 php 中执行此操作的正确方法是声明 public static function fun1,然后通过指定类来调用:Foo::fun1。我确定这是修复该严格标准错误的预期方法。
【解决方案5】:

在类中调用静态方法

className::staticFunctionName

示例

ClassName::staticMethod();

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2015-09-15
    • 2021-04-09
    • 2012-05-24
    • 2010-10-30
    • 2011-07-21
    • 2012-06-25
    • 2023-04-11
    • 1970-01-01
    相关资源
    最近更新 更多