【问题标题】:what's the point of declaring static functions in PHP?在 PHP 中声明静态函数有什么意义?
【发布时间】:2011-10-23 19:57:12
【问题描述】:

所以在 PHP 中你可以拥有

Class A{
   function B(){}
}

你可以把它当作一个静态函数来调用:

A::B();

我的问题是......如果我能做到这一点,那么为什么我应该将函数 B() 声明为静态的,因为这样做会使 $this 不可用,因此灵活性较低,所以你有一切可失去的,但没有什么可做的收获...

或者将函数声明为我不知道的静态函数有什么好处?

我还听说“非静态方法的静态调用”已被“弃用”......这究竟意味着什么,尤其是与这种情况有关?当 B() 未被声明为静态时,我不应该做的事情是调用 A::B() 吗?如果有,为什么会这样?

【问题讨论】:

  • 在严格模式下,将非静态方法作为静态方法调用会引发错误。这有望在未来成为默认行为。
  • (阅读提示) Statics considered harmful
  • "...如果我能做到这一点,那么为什么我应该将函数 B() 声明为静态,因为这样做会使 $this 不可用..."。如果你静态调用一个函数,那么$this 无论如何都不可用(PHP 抛出一个致命错误)。您仍然可以将self::$varstatic::$var 用于静态变量(非静态变量绑定到对象,而不是类)。
  • E_STRICT 错误将引发这些通知,以及有关如何优化代码的其他提示。错误报告(E_STRICT);

标签: php class function static static-methods


【解决方案1】:

因为 PHP 在严格性(?)方面往往有点松散,所以这些事情有效。它们已被弃用的事实意味着在未来的某个版本中,它可能不再不再工作了。因此,如果您在静态上下文中调用非静态函数,您的程序可能会在未来的 PHP 升级中中断。

至于现在使用它 - 将函数声明为静态的好处是您可以在那里决定如何使用该函数。如果您打算在静态上下文中使用函数,则无论如何都不能使用 $this,因此您最好清楚自己打算做什么。如果要静态使用该函数,请将其设为静态。如果你不这样做,那就不要。如果您想同时使用静态和非静态功能,请重新检查您的要求:P

【讨论】:

    【解决方案2】:

    用于兼容模式。现在静态调用非静态方法会生成 E_STRICT 级别的警告。

    为什么是静态的而不是实例化对象?每个程序员都会告诉你一个原因。我特别喜欢实例化对象而不是使用静态方法。它清晰、可追溯且可重复使用。

    我做了一个测试台,实例化和调用方法与静态调用相比差别很小。

    提示:如果您预见到调用方法也会静态定义它们;-)

    【讨论】:

      【解决方案3】:

      首先,你不能在你的帖子中用像 Java 这样的严格类型语言来做这样的事情。如果您在静态上下文中调用非静态内容,Java 代码将无法编译。 PHP 在这些事情上(目前)还没有那么严格,但你仍然不应该仅仅因为你可以就去做,尽管这是不好的做法,在某些语言中甚至是“不正确”的做法。

      使用静态方法肯定有好处。你一无所获,甚至失去灵活性是不对的。举个例子:

      class A {
      
        private static $prop_a = 'property_a';
      
        public static function b() {
          echo 'called b()';
          echo self::$prop_a;
      
          $A = new A();
          $A->c();
        }
      
        public function c() {
          echo 'called c()';
        }
      }
      

      现在我们可以这样调用类了:

      A::b();
      

      哪个输出

      • 叫_b
      • property_a
      • 叫_c

      但你也可以这样做:

      $a = new A();
      $a->b();
      $a->c();
      

      c() 现在执行了两次,但你明白了。在您的类中,您可以实例化类本身并像使用常规对象一样使用它。但是从外部看,它只是一行代码,而使用非静态方式是 3 行。很酷吧?

      如您所见,您可以在非静态上下文中使用静态函数,这意味着您可以将您的方法声明为静态,但如果您实例化您的类,您可以像普通方法一样简单地调用它。对我来说听起来很灵活;)

      不,您不能在静态上下文中使用 $this,但这就是 self 的用途;)

      【讨论】:

        【解决方案4】:

        如果它是一个静态函数,您不必为了使用该方法而实例化该类。

        Class A {
          static function hello($arg)
          {
            echo 'Hello, ' . $arg;
          }
        }
        
        A::hello('world');
        

        VS

        Class A {
          public function hello($arg)
          {
            echo 'Hello, ' . $arg;
          }
        }
        
        $a = new A;
        $a->hello('world');
        

        这里重要的是对象的实例化。实例化对象后,可以对其进行操作,调用方法可能会产生意想不到的结果。如果你的值和函数是在类中静态声明的,那么它们在你调用函数时不能被修改。

        这并不是说您也应该始终使用静态方法。举个例子。

        class My_math {
          static function pi()
          { 
           return 3.14
          }
        }
        
        class My_bakery {
          private var $pie;  
        
          function set_pie($pie)
          {
            $this->pie = $pie;
          }
          function pie()
          {
            echo "I made you a " . $this->pie . "pie";
          }
        }
        

        我已经让 My_Math 返回一个常量值,因为我知道 pi 不会改变。但是在 My_bakery,有时我想要蓝莓派,有时我想要桃子派。

        【讨论】:

        • 你是对的。我没有足够强调实例化。我已经尝试修复它。
        • 我不同意 Pelshof,这就是为什么方法被声明为静态的原因。
        • echo "I made you a " . $pie_type . "pie"; 你为什么要骗我?你让我变成了一个空馅饼类型? :(
        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2015-03-31
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2016-12-09
        • 2014-11-16
        • 1970-01-01
        相关资源
        最近更新 更多