Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Overriding class constants vs properties

I would like to better understand why, in the scenario below, there is a difference in the way class constants are inherited vs. instance variables.

<?php class ParentClass {     const TEST = "ONE";     protected $test = "ONE";      public function showTest(){         echo self::TEST;         echo $this->test;     } }  class ChildClass extends ParentClass {     const TEST = "TWO";     protected $test = "TWO";      public function myTest(){         echo self::TEST;         echo $this->test;     } }  $child = new ChildClass(); $child->myTest(); $child->showTest(); 

Output:

TWO TWO ONE TWO 

In the code above, ChildClass does not have a showTest() method, so the ParentClass showTest() method is used by inheritance. The results show that since the method is executing on the ParentClass, the ParentClass version of the TEST constant is being evaluated, whereas because it's evaluating within the ChildClass context via inheritance, the ChildClass member variable $test is being evaluated.

I've read the documentation, but can't seem to see any mention of this nuance. Can anyone shed some light for me?

like image 245
Tom Auger Avatar asked Nov 28 '12 20:11

Tom Auger


People also ask

Can we redefine a constant in PHP?

No, you cannot redefine a constant (except with runkit_constant_redefine), that's why is called CONSTANT.

What is the purpose of class constant?

Class constants can be useful if you need to define some constant data within a class. A class constant is declared inside a class with the const keyword. Class constants are case-sensitive. However, it is recommended to name the constants in all uppercase letters.

Can a class be constant?

It is possible to define constants on a per-class basis remaining the same and unchangeable. The default visibility of class constants is public . Note: Class constants can be redefined by a child class.

How do you call a constant in PHP?

A constant is an identifier (name) for a simple value. The value cannot be changed during the script. A valid constant name starts with a letter or underscore (no $ sign before the constant name). Note: Unlike variables, constants are automatically global across the entire script.


2 Answers

self:: Isn't inheritance-aware and always refers to the class it is being executed in. If you are using php5.3+ you might try static::TEST as static:: is inheritance-aware.

The difference is that static:: uses "late static binding". Find more information here:

http://php.net/manual/en/language.oop5.late-static-bindings.php

Here's a simple test script I wrote:

<?php  class One {     const TEST = "test1";      function test() { echo static::TEST; } } class Two extends One {     const TEST = "test2"; }  $c = new Two();  $c->test(); 

output

test2 
like image 97
David Farrell Avatar answered Sep 20 '22 21:09

David Farrell


In PHP, self refers to the class in which the called method or property is defined. So in your case you're calling self in ChildClass, so it uses the variable from that class. Then you use self in ParentClass, so it wil then refer to the variable in that class.

if you still want the child class to override the const of the parent class, then adjust the following code in your parent class to this:

public function showTest(){     echo static::TEST;     echo $this->test; } 

Note the static keyword. This is uses "late static binding". Now you're parent class will call the const of your child class.

like image 33
w00 Avatar answered Sep 20 '22 21:09

w00