2016-11-03 53 views
1

我發現,通過使用::class,我可以得到一個命名空間類的完全合格的類名:PHP動態確定完全合格的類名

namespace NameSpace { 
    class Foo { } 
    echo Foo::class; 
} 
// echoes 'NameSpace\Foo' 

但我不能想出一個辦法做到這與一個可變的類名稱。試圖對待class關鍵字就像一個靜態屬性似乎不工作:

namespace NameSpace { 
    class Foo { } 
    $className = 'Foo'; 
    echo $className::class; 
} 
// Parse error: syntax error, unexpected 'class' 

有誰知道它有可能得到完全合格的類名動態就像我試圖?


我希望能夠從目前的命名空間與外班要做到這一點:

namespace ReallyLongHardToWriteNameSpace { 
    class Foo { } 
} 
namespace NameSpace { 
    use ReallyLongHardToWriteNameSpace\Foo; 
    class Bar { } 

    echo Foo::class; // echoes 'ReallyLongHardToWriteNameSpace\Foo' 
    echo Bar::class; // echoes 'NameSpace\Bar' 

    foreach (['Foo', 'Bar'] as $className) { 
     echo $className::class; // Parse error: syntax error, unexpected 'class' 
    } 
} 

回答

0

好吧,我想出了另一種解決方案。即使這是有些不同。

namespace NameSpace; 
class Foo { 
    public static function getFullName() { 
     return __CLASS__; 
    } 
} 

print Foo::getFullName(); // Prints NameSpace\Foo 

只要創建一個具有getFullName()作爲方法的抽象類,並從它繼承你希望能夠重返全名的所有類。


最簡單的計算策略(我差點忘了)是使用get_class()的

$className = get_class($yourClassObject); // returns NameSpace\Foo 

您也可以嘗試使用的eval()這一點。

$className = 'NameSpace\Foo::class'; 
eval('$fullName = ' . $className); 
print $fullName; // returns NameSpace\Foo 

即使壽,這可能不是你想要什麼,但你應該看看反思庫。它非常方便用於這種事情。

// Lets say you have an object of your class 
$object = new ReflectionObject($yourObject); 
$name = $object->getName(); // will return NameSpace\Foo 

// You can also give the class name to it 
$class = new ReflectionClass('Foo'); 
$name = $class->getName(); // also returns NameSpace\Foo 

here瞭解更多信息 還有一些類方法,屬性等

+0

'get_class'和'ReflectionClass'都需要你已經知道完全合格的類名作爲它們的參數,這違背了目的...... – thanksd

+0

見我的編輯表示,它在最高層 –

0

您可以使用get_class與類的一個實例:

<?php 
namespace NS { 
    class Foo { } 
    $className = "\\NS\\Foo"; 
    echo get_class(new $className); 
} 
// prints NS\Foo 

請注意,以創建一個我不得不在字符串中使用FQN的類的實例,所以它可能根本沒用。

+0

是它失敗目的是已經擁有完全合格的類名作爲輸入 – thanksd

0

您可以使用__NAMESPACE__來獲取當前命名空間,然後將其前置到包含類名的字符串中。

namespace NS { 
    class Foo { 
    } 
    $className = 'Foo'; 
    echo __NAMESPACE__ . '\\' . $className; 
} 
+0

如果我總是試圖獲取當前命名空間中的類的完全限定類名,而不是使用其他命名空間中的類(這就是我試圖做,我會更新我的問題) – thanksd

+0

那麼它將永遠不會工作。如果你在命名空間NS1中有一個名爲'Foo'的類,而在命名空間NS2中有另一個名爲'Foo'的類,那麼除非你有一個對象的實例,否則無法確定哪個是哪個 - 你可以直接調用'get_class()'。 –

+0

但是在這種情況下,你會得到'無法聲明類NS2 \ Foo'錯誤。我只是在名稱空間範圍內討論類,或者已經用'use'導入的類。 – thanksd