4

I have Protected Variable UserId in Parent Class.i Am going to extend the variable in my child class as shown below

class Main
{
  protected $UserId          = "151";
  protected static $UserName = "Madhavan";      

  protected function SampleMethod()
  {
    print "This is Sample Method";
  } 
}


class SubMain extends Main
{   
  function __construct()
  {    
    print parent::SampleMethod();

    print "User Id is ".$this->UserId."<br/>";          
    print parent::$UserName;
    print "User Id is ".parent::$UserId."<br/>";            
  }
}

When I Use $this->UserId Its printing fine.But when I use Parent::$UserId its displaying error

Fatal error: Access to undeclared static property: Main::$UserName

Why it is not showing for the function which i Accessed by parent::SampleMethod() as the function is not static.

ArrayOutOfBound
  • 2,614
  • 5
  • 20
  • 26
  • possible duplicate of [php static function](http://stackoverflow.com/questions/902909/php-static-function) – Alp Feb 14 '13 at 09:17
  • and also: [Calling non static method with “::”](http://stackoverflow.com/questions/3754786/calling-non-static-method-with) – Alp Feb 14 '13 at 09:18
  • `$UserName` is declared as static you need to access it using `static::` like `static::$UserName` – afarazit Feb 14 '13 at 09:30

4 Answers4

3

The scope resolution operator :: sometimes behaves in a non-obvious manner. When applied to constants or variables it always resolves in a static manner.

However, when applied to functions, the execution context of the callee depends on the execution context of the caller code; the context is not changed.

For instance, this works fine without any warnings:

class Test
{
  private $a = 123;

  public function __construct()
  {
    Test::test();
    self::test();
  }

  public function test()
  {
    echo $this->a;
  }
}

new Test();

The call self::test() and Test::test() both run in a non-static manner, because __construct() is called non-statically and you're referencing the same class.

To reference any instance variable, such as $a in the above example, the use of $this-> is required.

Ja͢ck
  • 170,779
  • 38
  • 263
  • 309
1

This is because functions are overridable (thus older versions of the same name co-exist) while properties are not (declarations simply overwrite each other, and properties should not be re-declared in descendant classes). You always access THE ONLY instance of a property with $this-> if it isn't static, and self:: if it is static. (If a property was declared in multiple ancestor classes, still only one data-field exists, so you cannot reference any "others" or "previous ones".)

Levente Pánczél
  • 1,895
  • 2
  • 14
  • 16
  • You can also think of it as follows: all names (functions and properties) that ascendant classes declare are accumulated in a class. You can use any of them just as if they had been declared in this class. There's only one exception: when you want to access previous versions where they are already hidden by a redeclaration of that name. In these cases you can use static calling to name the class that contains the previous version that you want to use. ```parent``` is simply a shortcut to name the direct ancestor because this is the most common usecase. – Levente Pánczél Feb 14 '13 at 09:26
0

if E_STRICT is not activated you won't get an error, else you will get something like this:

Strict Standards: Non-static method parent::SampleMethod() should not be called statically in...

yacon
  • 1,112
  • 1
  • 10
  • 17
0

Instead of using parent, You can access it with self::$UserName attribute (where it was defined) with the self keyword. If You want to reach its value in the child class (because overriding it) it is accessible via final::$UserName (called late static binding)

VuesomeDev
  • 4,095
  • 2
  • 34
  • 44