2016-04-05 14 views
1

thisthisのような質問がありましたが、名前空間を既に持っていてクラスがエイリアス化されている場合は、名前空間:別名ネームスペースの文字列名から新しいクラスインスタンスを作成

<?php 
namespace my\project; 

require 'vendor/autoload.php'; 

//Example aliased classes, more may be defined elsewhere 
use League\OAuth2\Client\Provider\Google; 
use Stevenmaguire\OAuth2\Client\Provider\Microsoft; 

//This is mapped from a submitted form value 
$provider = 'Google'; 

$g = new $provider; 

これはPHP Fatal error: Class 'Google' not foundをスローします。これらの質問では、__NAMESPACE__という接頭辞を付ける必要がありますが、問題はこれらのクラスがmy\project名前空間にないために存在しないため、どちらも機能しないということです。クラス名はmy\project\Googleです。

この特定のコードのダンプ修正は、すべての名前空間とクラス名を格納するために配列を使用することですが、事前にすべてのクラス名がわからないとうまくいかない場合があります。

同じ理由でエイリアスクラスの反射オブジェクトを作成できないため、これを解決するためにリフレクションを使用する方法がわかりません。new \ReflectionClass($provider);は同じエラーをスローします。

エイリアスクラス名の名前空間を動的に取得するにはどうすればよいですか?

+0

「リーグ\ OAuth2 \ Client \ Provider \ GoogleをGoogleとして試してみよう」 – Xorifelse

+0

@ Xorifelse、それは私が持っているものと同じです – Synchro

答えて

0

名前空間は、異なるコンテキストで同じ名前を使用できるように導入されているため、答えは「いいえ、不可能です。

クラス\League\OAuth2\Client\Provider\Googleと別のクラス\League\OAuth1\Client\Provider\Googleを使用できます。この場合、どのクラスをインスタンス化するかはどのように決定できますか?

あなただけのユニークなクラス名があることを知っていると仮定すると、あなたはこのコードを使用することができます:

$provider = 'Google'; 
$found = False; 
foreach(get_declared_classes() as $class) 
{ 
    if(preg_match("~(.*\\\)?($provider)$~", $class)) 
    { 
     $found = $class; 
     break; 
    } 
} 

if($found) 
{ 
    $g = new '\\'.$found; 
} 
else 
{ 
    echo "No '$provider' class found"; 
} 

demo with DateTime class

をしかし、このルーチンはあなたのアイデア「を使用することの唯一の単純化ですすべての名前空間とクラス名を格納するための配列 "となります。なぜなら、上記のコードでも、宣言されたクラスをすべて知っていなければ、望ましくない結果が得られるからです。

+0

ありがとう。さらに自動化されたクラスはまだ 'get_declared_classes'リストにはなく、' use'ステートメントを持っていてもクラスの存在を暗示するわけではありません。インスタンス化しようとすると問題になります。 – Synchro

+0

もし私があなたがチャンスを持っていないと思うautoloadを使用する:どのようにあなたは何をしたいのですか? – fusion3k

+0

オートロードメソッドを表示できますか?多分それに隠された解決策があります... – fusion3k

1

あなたは、単に使用する必要があります。

$provider = 'League\OAuth2\Client\Provider\Google'; 

は、他の解決策はありません、クラス名変数は、完全修飾クラス名を含める必要があります。エイリアスは文字列クラス名には適用されません。また、イントロスペクションはあなたにも役立ちません。

+0

はい、これは明らかです。しかし、クラスファイルがロードされている場合、OPは自分の完全な名前を取得できます。あなたの明快さ/簡潔さのために+1 – fusion3k

+0

そして、 "(しよう)"というのは、アプローチがむしろ...最適ではない理由です。 :)明示的に、そのクラスの完全な(適格な)名前、期間で名前を付けます。 – deceze

関連する問題