Unable to access class constant from instance using :: scope statement

Today I ran into some strange problem, and even as a software engineer I don’t understand:

It seems you can access the class constant from an instance of an object, for example:

class a { const abc = 1; } $a = new a(); var_dump($a->abc); 

This will output null instead of the expected 1. I was able to do the following:

 class a { const abc = 1; } $a = new a(); var_dump(a::abc); 

But in the context of a subordinate object that does not really know who the parent is, it is very unpleasant for me to do this:

 class a { const abc = 1; } $a = new a(); $c = get_class($a); var_dump($c::abc); 

Is it me, or is it completely stupid, if not, please enlighten me why this works.

EDIT

Another way to do this, but it is not better:

 class a { const abc = 1; } class b { public function getA(){ return new a(); } } $b = new b(); $c = $b->getA(); var_dump($c::abc); 

This last example is more like what I do and worry about ...

+4
source share
5 answers

I found a relatively beautiful and clean way to make my task easier. Here is the solution I applied. This is not necessarily the best, but for my purposes it does exactly what I need.

When creating the __get magic method, I intercept the query for the constant name and instance point, and I use quick reflection to see if this constant exists and return its value.

This allows me to actually use an all in one line template that looks like this:

 class a { const abc = 1; public function __get($key){ $r = new ReflectionObject($this); if($r->hasConstant($key)){ return $r->getConstant($key); } } } class b { public function getA(){ return new a(); } } $b = new b(); var_dump($b->getA()->abc); var_dump($b->getA()->def); 

Although I would like to:

 var_dump($b->getA()::abc); var_dump($b->getA()::def); 

I suppose this might be possible later in 5.4+, given that we finally dereferenced the array, we could probably ask them to add static raffles in the near future.

+9
source

Just use an instance variable with a scope statement:

 $a = new a(); var_dump($a::abc); 

This prints 1 .

+7
source

The PHP documentation indicates that class constants are accessible via SRO ( :: , and not -> .

 <?php class MyClass { const constant = 'constant value'; function showConstant() { echo self::constant . "\n"; } } echo MyClass::constant . "\n"; 
+4
source

As I already mentioned, in php constants they are attached to the class definition, they are static by definition and cannot be accessed with the operator β†’.

If you really want to use it with your coding paradigm, you can try the reflection class in php5.

 class MyClass { const A = "I am A"; } $o = new ReflectionClass( "MyClass" ); echo $o->getconstant("A"); //will print "I am A" 

Also, I think the example in EDIT might not work. I did not run it, but I am not sure that SRO (: :) can be called in anything that is not a reference to the class ..

+2
source

I know this is an old thread, but for people who want to know the best way to do this, look at the PHP function constant () .

With constant () you can just do this:

 $a = new a(); $value = constant(get_class($a)."::abc"); // $value === 1 

it was available since PHP 4 and still works fine in PHP 5.5

+2
source

All Articles