2012-08-15 43 views
4

我打了一個奇怪的問題,今天,甚至爲PHP工程師,我在這難倒訪問類常量:無法從一個實例使用::範圍操作

這似乎可以從一個對象訪問類常量實例如:

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

這將輸出空而不是預期的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); 

最後這個例子更象是我在做什麼,體驗...

+0

是常數自動'static'? – Matt 2012-08-15 20:36:42

+2

在php中,常量綁定到類定義上,它們根據定義是靜態的,不能使用 - >運算符來訪問。不幸的是,這恰好是野獸的本質。 – raidenace 2012-08-15 20:41:48

+0

您可以使用'self ::'而不是'$ this->'來訪問類常量。在你的情況下,你可以使''a = new A(); var_dump(a :: abc);'' – lev09 2017-07-19 11:28:25

回答

9

我發現了一個相對較好和乾淨的方式,使我的問題更容易生活。這是我應用的解決方案。這不是最好的,但對我的使用來說,它確實是我所需要的。

通過創建一個magic __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); 

Althought我必須喜歡做的事:

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

我想這可能是可能的後來在5.4+考慮到我們finaly有數組解引用,我們可能會要求他們儘快添加靜態解引用。

7

只需使用帶示波器分辨率運算符的實例變量:

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

This prints1

+0

這是PHP 5.3之前的支持嗎? – 2012-08-15 20:37:30

+0

這就是我被迫做的,但它有點難看,我想這樣做,像$ a-> getB():: abc。但它不支持... – 2012-08-15 20:38:39

+6

@arxanas - 從我的測試中,不,你會得到我最喜歡的錯誤信息:'意外的T_PAAMAYIM_NEKUDOTAYIM'。 – nickb 2012-08-15 20:39:19

4

The PHP documentation指示類常量通過SRO(::)而不是->訪問。

<?php 
class MyClass 
{ 
    const constant = 'constant value'; 

    function showConstant() { 
     echo self::constant . "\n"; 
    } 
} 

echo MyClass::constant . "\n"; 
+2

爲什麼你只是粘貼我已經寫過的東西,我知道它應該這樣做,我想要的是找到更好的方法。你真的沒有幫助 – 2012-08-15 20:40:52

+2

@MathieuDumoulin *「是我還是完全愚蠢,如果沒有,請啓發我爲什麼它的工作方式。*」我以爲我啓發了你。 – Matt 2012-08-15 20:41:45

+1

@MathieuDumoulin這就像問「爲什麼我不能使用'='進行比較?」因爲這不是'='用來做什麼的。 – Matt 2012-08-15 20:43:24

2

ike我提到過,在PHP常量綁定到類定義,它們是靜態的定義,不能使用 - >運算符訪問。

如果你真的想用你的編碼範例,你可以嘗試php5中的反射類。

class MyClass 
{ 
    const A = "I am A"; 
} 

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

另外,我覺得在你的編輯例如可能不work..I不運行它,但我不知道如果SRO(::)可以在任何被調用這不是一個類參考..

2

我知道這是一個古老的線程,但對於想要了解最佳方式的人來說,請查看PHP函數constant()

隨着不斷的(),你可以簡單地這樣做:

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

因爲PHP 4本已出售,仍然完全在PHP 5.5

+0

問題是能夠以乾淨的方式訪問不可能的解除引用對象的靜態常量。使用PHP 5.4,您現在可以自動將數組取消返回函數,但仍無法取消引用靜態成員,必須創建一箇中間變量,然後才能調用它。這就是我擔心的問題的全部問題! – 2013-11-05 19:27:41

+0

在所有現實中,似乎問題是從實例化對象訪問常量,至少這是我從閱讀帖子中獲得的。 「 」看起來你可以從一個對象實例訪問一個類常量,例如:「 – Jaimz 2013-11-06 03:07:11

+0

我可能寫錯了,讓我編輯帖子,以確保它不會讓其他人感到困惑 – 2013-11-06 17:50:45