【问题标题】:Why does PHP allow calling non-static methods statically but does not allow calling non-static properties statically?为什么 PHP 允许静态调用非静态方法但不允许静态调用非静态属性?
【发布时间】:2018-08-06 00:25:17
【问题描述】:

为什么 PHP 允许使用类名和各种关键字(例如作为类名占位符的 self、static 和 parent)静态调用非静态方法?


但另一方面它不允许调用非静态属性 静态的?


这里是示例代码 -

<?php

 # PHP Version 7.1.7
 error_reporting(E_ALL);
 ini_set('display_errors', 1);

 class Fruit {
     public $name = 'Fruit';
     public function x() {
         echo "Fruit_x" . "<br>";
     }
 }

 class Orange extends Fruit {

     public $name = 'Orange';
     public function x() {
         echo "Orange_x" . "<br>";
         parent::x();
         self::y();
         static::z();

         // Code Below will throu Uncaught Error: Access to undeclared static property
         // echo parent::$name . "<br>";
         // echo self::$name . "<br>";

     }

     public function y(){
         echo "Y" . "<br>";
     }

     public function z(){
         echo "Z" . "<br>";
     }

 }


 (new Orange)->x(); // No Warnings

 Orange::x();  // However calling like this shows warning as of PHP 5 & 7
 // Docs - http://php.net/manual/en/language.oop5.static.php

?>

You can Run Code in the Browser to see the following Result

PHP Static Keyword Docs

【问题讨论】:

  • 我认为它已被弃用的事实应该给你一些暗示,无论是否允许,你都不应该这样做。
  • 令人惊讶的是,在函数内部它没有给出静态访问非静态方法的警告。这反过来又让人感到困惑和难以解释
  • 因为您实际上并没有静态访问它们。 parent、self 和 static 足够聪明,可以确定您有一个实例,这些是实例方法。当您没有实例时(当您静态调用 x() 时),您会收到警告
  • 但是如果是这样的话,为什么当我回显 parent::$name & self::$name 时它会抛出“未捕获的错误:访问未声明的静态属性”?这些是实例属性

标签: php static static-methods non-static


【解决方案1】:

根据您的评论,我相信您的误解源于您认为parent::self:: 总是用于进行静态调用。

Parent 用于访问任何类型的父方法,而 self 用于始终使用当前类方法。由于方法只能定义一次,PHP 可以推断出这些方法应该如何被调用。

https://3v4l.org/NJOTK 将显示使用继承时$this-&gt;call()self::call()parent::call() 之间的区别示例。 static:: 是允许的,但在功能上等同于 $this-&gt; 实例方法。

相同的行为不会扩展到属性。实例属性不支持相同级别的继承,它们仅在实例化时继承值。您无法访问父级的属性,该实例上仅存在一个属性。因此,始终使用$this-&gt;property 访问非静态属性。

【讨论】:

  • 哦,这就是为什么我可以访问 parent::_construct() 但不能访问 parent::$non_static_var? 您是如何找到并理解所有这些信息的 。我的意思是我不能谷歌它。 无论如何,代码完全按照你说的做,你的答案似乎很正确,但是,你能分享你在哪里找到这个的资源,这样我就可以在我的脑海里把所有这些加在一起,更好地理解
  • 最后一件事当我用类名替换 parent:: 和 self:: 时,结果保持不变。所以这意味着您对 parent:: 和 self:: 所说的类名并不总是用于进行静态调用? PHP 可以推断应该如何调用这些方法。 PHP 扩展/允许方法,但不扩展属性 我对吗? 你从哪里得到所有这些信息,我很困惑
  • 这是使用 PHP 10 多年的数据和知识的集合,您不会在 1 个甚至 2 个地方找到所有这些东西。最好的办法是通读 PHP 的所有 OOP 手册:php.net/manual/en/language.oop5.php。我认为您过于担心不良做法..只是不要指望在没有实例时可以使用非静态方法或属性..
猜你喜欢
  • 2011-12-11
  • 2013-03-20
  • 1970-01-01
  • 1970-01-01
  • 2014-09-08
  • 1970-01-01
  • 2017-02-04
  • 1970-01-01
相关资源
最近更新 更多