2013-01-11 43 views
0

示例文件1:類,如PHP非字符串參數

namespace A; 

class Foo{ 

} 

文件2:

use A\Foo; 

do_stuff('A\Foo'); // <- need namespace here :(

Foo::someStaticMethod(); // <- namespace not required :D 

有沒有什麼辦法可以傳遞函數參數類的名稱,如常量或什麼的,所以我不需要預先命名空間?

回答

2

更新:)

當我知道,我需要通過一些類四周,串,我用來製作特殊的類常量的類名

namespace Foo\Bar; 
class A { 
    const __NAMESPACE = __NAMESPACE__; 
    const __CLASS = __CLASS__; 
} 

現在,您可以參考類名像

use Foo\Bar\A as Baz; 
echo Baz::__CLASS; 

隨着PHP5.5這將內置

echo Baz::class; 

完全合格的 - 名(FQN)的命名空間始終與命名空間分隔符

do_stuff('\A\Foo'); 

開始,除了(和那唯一的例外)在use -statements,因爲只能出現完整的名稱空間標識符,所以爲了方便您可以在那裏省略它。

但是,一個字符串是一個字符串,並且您將其用作類名稱的位置超出瞭解釋器的範圍,因此它丟失了對前者的引用。在PHP5.5中,您可以編寫Foo::class,但我認爲那不是一個選項;)

+0

我將等待PHP 5。5 :(但恆定的解決方案也不錯:) – thelolcat

1

不,沒有跟蹤調用者,據我所知。您正在調用的函數必須存在於您嘗試傳遞的對象所在的同一名稱空間內。

如果您需要命名空間解析,您可能需要查看debug_backtrace函數。 但是這需要文件路徑被轉換成命名空間分辨率或類似的。

但是,這是可能的:(我看到安德魯回答與同類型的解決方案。)

function doStuff ($obj) 
{ 
    $name = (is_object($obj)) 
     ? (new ReflectionClass(get_class($obj)))->getName() 
     : $obj; 

    // $name will now contain the fully qualified name 
} 


namespace Common; 

class Test 
{} 

$testObj = new Test(); 

// This will work, but requires argument to be 
// fully quialified or an instance of the object. 
\doStuff($testObj); 
\doStuff("\Common\Test"); 
+1

即使跟蹤我沒有看到一種方法來獲取調用範圍的別名。 – KingCrunch

+0

當然,並非所有情況都是可能的,但是如果類存在於給定的命名空間中並且命名空間遵循特定的標準/規則,則這可能可以用於嚴格的使用。即自動加載器爲文件路徑解析中的目錄使用名稱空間,這將允許「命名空間的路徑」轉換。 – Daniel

+1

不知道你說的是什麼,但是當你定義一個'use'語句,然後在一個字符串中使用相關的類名時,它就不再可以被解析了。沒有標準可以幫助你:別名定義在編譯期間被解析,因此它們在運行時不再可用,但字符串,..以及它是一個字符串並保持原樣:D – KingCrunch

1

你可以實例化一個新的對象,然後調用get_class()爲獲得完全合格的名稱類。

use A\Foo; 

$foo = new Foo(); 

do_stuff(get_class($foo)); // get_class($foo) = '\A\Foo' 

這意味着foo的命名空間是僅由使用語句(即更少的代碼維護)定義

+0

只涵蓋了一半有用的用例:通常,當你將一個類名作爲字符串傳遞時,你不需要在這裏有一個對象。額外:當你甚至有一個對象時,你爲什麼需要類名呢?另外提醒一下,可能有構造函數;) – KingCrunch

+0

這個解決方案涵蓋了問題中的用例,這一切都很重要。還有其他用例,那麼這個問題就需要擴展。 – Andrew

+0

你真的假設,'Foo'是空的嗎? :d – KingCrunch