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.

3
  • possible duplicate of php static function Commented Feb 14, 2013 at 9:17
  • and also: Calling non static method with “::” Commented Feb 14, 2013 at 9:18
  • $UserName is declared as static you need to access it using static:: like static::$UserName Commented Feb 14, 2013 at 9:30

4 Answers 4

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.

Sign up to request clarification or add additional context in comments.

Comments

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".)

1 Comment

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

1 Comment

That will not happen, because parent:: doesn't necessarily mean static context.
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)

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.