Невозможно получить доступ к константе класса из экземпляра с помощью оператора :: scope

Сегодня я столкнулся с какой-то странной проблемой, и даже в качестве инженера-программиста, я в тупике:

Кажется, вы можете получить доступ к константе класса из экземпляра объекта, например:

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

Это приведет к выводу null вместо ожидаемого 1. Я смог сделать следующее:

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

Но в контексте субобъекта, который на самом деле не знает, кто именно является родителем, мне очень неприятно это делать:

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

Это я или это совершенно глупо, если нет, пожалуйста, просветите меня, почему это так работает.

РЕДАКТИРОВАТЬ

Другой способ сделать это, но это не лучше:

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

Этот последний пример больше похож на то, что я делаю и переживаю …

Solutions Collecting From Web of "Невозможно получить доступ к константе класса из экземпляра с помощью оператора :: scope"

Я нашел относительно красивый и чистый способ облегчить мне задачу. Вот решение, которое я применил. Это не обязательно лучшее, но для моих целей оно делает именно то, что мне нужно.

Создав волшебный метод __get, я перехватываю запрос имени константы и точки экземпляра, и я использую быстрое отражение, чтобы увидеть, существует ли эта константа и вернуть ее значение.

Это позволяет мне фактически использовать все в одной строке шаблон, который выглядит так:

 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); 

Хотя мне бы хотелось сделать:

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

Я предполагаю, что это может быть возможно позже в 5.4+, учитывая, что мы окончательно разыменовали массив, мы, вероятно, могли бы попросить их добавить статическое разыменование в ближайшее время.

Просто используйте переменную экземпляра с оператором разрешения области:

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

Это печатает 1 .

Документация PHP указывает, что к константам класса доступны через SRO ( :: а не -> .

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

Как я уже упоминал, в php-константах привязаны к определению класса, они статичны по определению и не могут быть доступны с помощью оператора ->.

Если вы действительно хотите использовать его с вашей парадигмой кодирования, вы можете попробовать класс отражения в php5.

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

Кроме того, я думаю, что пример в вашем EDIT может не работать. Я не запускал его, но я не уверен, что SRO (: 🙂 можно вызвать во всем, что не является ссылкой на класс.

Я знаю, что это старый поток, но для людей, которые хотят знать лучший способ сделать это, посмотрите на функцию PHP constant () .

С константой () вы можете просто сделать это:

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

это было доступно с PHP 4 и по-прежнему отлично работает в PHP 5.5