Сегодня я столкнулся с какой-то странной проблемой, и даже в качестве инженера-программиста, я в тупике:
Кажется, вы можете получить доступ к константе класса из экземпляра объекта, например:
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);
Этот последний пример больше похож на то, что я делаю и переживаю …
Я нашел относительно красивый и чистый способ облегчить мне задачу. Вот решение, которое я применил. Это не обязательно лучшее, но для моих целей оно делает именно то, что мне нужно.
Создав волшебный метод __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