【问题标题】:Static methods in PHPPHP中的静态方法
【发布时间】:2012-03-01 16:21:24
【问题描述】:

为什么在 PHP 中你可以通过某个类的实例访问静态方法,而不仅仅是通过类型名称?

更新:我是 .net 开发人员,但我也与 php 开发人员一起工作。最近我发现了关于从实例调用的静态方法的这一刻,但不明白为什么它会有用。

示例:

class Foo
{
    public static Bar()
    {
    }
}

我们可以接受这样的方法:

var $foo = new Foo();
$foo.Bar(); // ??????

【问题讨论】:

  • 静态方法和属性起初有点棘手。您需要记住的是,静态方法或属性无需先实例化对象即可使用。
  • 您能澄清一下您对代码 sn-p 的确切含义吗?你的问题有点模棱两可。
  • 这不是 PHP 特定的。在 Python 中,您还可以从实例中访问用 @staticmethod 装饰器装饰的方法,唯一的区别是静态方法不接收调用它们的上下文(对象)。

标签: php static-methods


【解决方案1】:

在 PHP 中

例如,该类使用 new 关键字进行实例化;

$MyClass = new MyClass();

并且可以使用范围解析运算符或对象引用运算符来访问静态方法或属性。例如,如果类MyClass 包含静态方法Foo(),那么您可以通过任一方式访问它。

$MyClass->Foo();

或者

MyClass::Foo()

唯一的规则是静态方法或属性不在对象上下文中。例如,您不能在静态方法中使用$this。

【讨论】:

  • 虽然使用实例也可以:$class->staticMethod()
  • @Ibrahim - 实际上,这是不正确的。您可以从类的实例或类本身访问静态和非静态方法。只有在调用静态引用 $this 的方法时才会出现错误。
  • 从 PHP 7 开始,静态调用非静态方法已被弃用,可能会被删除
【解决方案2】:
Class Do {
  static public function test() {
      return 0;
  }
}

这样使用:

echo Do::test();

【讨论】:

    【解决方案3】:

    为什么在 PHP 中你可以通过某个类的实例访问静态方法,而不仅仅是通过类型名称?

    与您可能习惯使用的 .NET 不同,PHP 具有动态类型。考虑:

    class Foo
    {
      static public function staticMethod() { }
    }
    
    class Bar
    {
      static public function staticMethod() { }
    }
    
    function doSomething($obj)
    {
      // What type is $obj? We don't care.
      $obj->staticMethod();
    }
    
    doSomething(new Foo());
    doSomething(new Bar());
    

    因此,通过允许通过对象实例访问静态方法,您可以更轻松地跨不同类型调用同名的静态函数。

    现在我不知道是否有充分的理由允许通过-> 访问静态方法。 PHP (5.3?) 还支持:

    $obj::staticMethod();
    

    这也许不那么令人困惑。当使用:: 时,它必须是一个静态函数以避免警告(不像->,它允许两者之一)。

    【讨论】:

    • 也许在你的例子中应该使用带有接口的非静态方法,因为这样使用静态方法有点混乱,不是吗?
    • @donRumatta,我不会声称上面的代码是好的。但是由于 PHP 的动态特性,接口并不是绝对必要的,许多人在没有它们的情况下编写代码。请注意,PHP 并不总是具有良好的 OOP 支持,因此“为什么”的一些答案只是“过去版本的错误设计决策”。
    • 在 PHP 7 上不推荐使用 -> 进行静态处理。
    • @SamuelÅslund 我认为你倒退了,它使用:: 来调用已弃用的非静态:php.net/manual/en/language.oop5.static.php
    • @Omn 无法使用箭头操作符通过对象访问静态属性 -> - 来自here。
    【解决方案4】:

    在 PHP 中,虽然您可以通过引用类的实例来访问静态方法,但您不一定需要这样做。 例如,这是一个带有静态函数的类:

    class MyClass{
        public static function  MyFunction($param){
            $mynumber=param*2;
            return $mynumber;
    }
    

    您可以像这样通过类型名称访问静态方法,但在这种情况下,您必须使用双冒号 (::),而不是“->”。

    $result= MyClass::MyFunction(2);
    

    (请注意,您也可以通过类的实例访问静态方法,也可以使用“-->”)。更多信息:http://php.net/manual/en/language.oop5.static.php

    【讨论】:

      【解决方案5】:

      在 PHP 7 中,您似乎绝对有必要能够做到$this->staticFunction()。因为,如果这段代码是在抽象类中编写的,并且staticFunction() 在您的抽象类中也是抽象的,那么$this-> 和self:: 会产生不同的结果!

      当从抽象类的(非抽象)子级执行$this->staticFunction() 时,您最终会得到child::staticFunction()。一切都很好。

      但是,从抽象类的(非抽象)子级执行self::staticFunction(),最终会得到parent::staticFunction(),它是抽象的,因此会引发异常。

      我猜这只是 PHP 设计不佳的另一个例子。 或者我自己需要更多的咖啡......

      【讨论】:

      • 我想这只是另一个受过良好教育的开发人员的例子,.. RTFM 在访问静态方法时使用 $this 绝不是一个好主意。如果您阅读文档,您会知道在这种情况下(除其他外),您可以使用“self::”或“static::”在父类和子类之间进行选择,请参阅php.net/manual/en/language.oop5.late-static-bindings.php 通过静态方法的继承可能毕竟不是最好的策略。
      【解决方案6】:

      有时,如果我们可以在类而不是对象的上下文中访问方法和属性,这很有用。为此,您可以使用 static 关键字。所以我们可以使用类名和作用域解析来访问静态方法。

      class User
      {
          public static $name = 'john';
      
          public static function display()
          {
              return self::$name;
          }
      }
      
      echo User::display();
      

      看这里,我们在 User 类中声明了一个静态方法。因此,如果我们声明一个静态方法,那么我们可以只使用类名访问那里。无需创建对象即可访问那里。希望你能理解所有的程序。

      注意:这实际上是与普通方法的主要区别:$this 在此类方法中不可用。

      从这里阅读全文How to Use Static Properties in PHP ?

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2011-01-07
        • 1970-01-01
        • 2017-12-19
        • 2011-01-27
        相关资源
        最近更新 更多