2

Why does PHP allow calling non-static method statically using Class Names and by the various keywords such as self, static & parent which are placeholders for Class Names?


But on the other hand it does not allow calling non-static properties statically?


Here is the sample code -

<?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

Expected Result

PHP Static Keyword Docs

Phil
  • 157,677
  • 23
  • 242
  • 245
  • 1
    I think the fact that it is deprecated should give you some hints that you shouldn't be doing it regardless if it's allowed. – Devon Bessemer Aug 06 '18 at 00:29
  • 1
    Surprisingly when inside the function it did not give a warning for statically accessing a non-static method. This in return makes it confusing and difficult to interpret – Mohammad Daud Ibrahim Aug 06 '18 at 00:35
  • Because you aren't actually accessing them statically. parent, self, and static are smart enough to determine that you have an instance and these are instance methods. You are getting the warnings when you don't have an instance (when you call x() statically) – Devon Bessemer Aug 06 '18 at 00:39
  • But If that's the case then why it throws " Uncaught Error: Access to undeclared static property " when I echo parent::$name & self::$name ? these are instance properties – Mohammad Daud Ibrahim Aug 06 '18 at 00:51

1 Answers1

3

Based on your comment, I believe your misunderstanding comes from the fact that you think parent:: and self:: are always used for making static calls.

Parent is used for accessing a parent method of any type and self is used to always use the current class method. Since methods can only be defined once, PHP can infer how these methods should be called.

https://3v4l.org/NJOTK will show an example of the difference between $this->call(), self::call(), and parent::call() when using inheritance. static:: is allowed but functionally equivalent to $this-> for instance methods.

The same behavior does not extend to properties. Instance properties do not support the same level of inheritance, they only inherit values on instantiation. You cannot access a parent's property, only one property exists on that instance. Therefore, non-static properties are always accessed using $this->property.

Devon Bessemer
  • 34,461
  • 9
  • 69
  • 95
  • Oh so that is why I can access parent::_construct() but not parent::$non_static_var? **How did you found and understood all this information** . I mean I couldn't google it. **Anyways The code does exactly as you say, your answer seem pretty correct but,** can you please share the resource of where you found this so that I can add all these up all together in my mind and understand better – Mohammad Daud Ibrahim Aug 06 '18 at 09:09
  • One last thing when I substitute class names for parent:: and self:: the result remains the same. SO this means class names as you said for parent:: and self:: are not always used for making static calls ? PHP can infer how these methods should be called. PHP extends/allows methods but does not extend to properties Am i Right ? **Where did you get all these info i am baffled** – Mohammad Daud Ibrahim Aug 06 '18 at 09:40
  • 1
    This is an aggregation of data and knowledge from working with PHP for 10+ years, you'll not find all this stuff in 1 or even 2 places. Your best bet is to read through all of PHP's OOP manual: http://php.net/manual/en/language.oop5.php. I think you're overly concerned about a bad practice.. Just don't expect non-static methods or properties to be available when you don't have an instance.. – Devon Bessemer Aug 06 '18 at 12:45