4

以下のすべての例は、すべてのファイルが正しい場所に存在するという保証に基づいています。私はこれを三重にチェックしました。

(1) これは、名前空間を使用しない場合に機能します。

$a = "ClassName";
$b = new $a();

これは機能しません:

// 'class not found' error, even though file is there

namespace path\to\here;
$a = "ClassName";
$b = new $a();

これは機能します:

namespace path\to\here;
$a = "path\to\here\ClassName";
$b = new $a();

したがって、変数を使用してクラスをインスタンス化する場合、名前空間宣言は無視されるようです。

いくつかのコードを調べて、すべての変数を名前空間を含めるように変更する必要がないように、(私の最後の例よりも) 良い方法はありますか?

4

2 に答える 2

5

名前空間は常に完全なクラス名の一部です。一部の use ステートメントでは、実行時にクラスのエイリアスのみを作成します。

<?php

use Name\Space\Class;

// actually reads like

use Name\Space\Class as Class;

?>

クラスの前の名前空間宣言は、このクラスがその名前空間に属していることを PHP パーサーに伝えるだけです。インスタンス化のためには、完全なクラス名 (前述の名前空間を含む) を参照する必要があります。

特定の質問に答えるには、いいえ、質問に含まれている最後の例よりも良い方法はありません。二重引用符で囲まれた文字列でこれらの悪いバックスラッシュをエスケープしますが.*

<?php

$foo = "Name\\Space\\Class";
new $foo();

// Of course we can mimic PHP's alias behaviour.

$namespace = "Name\\Space\\";

$foo = "{$namespace}Foo";
$bar = "{$namespace}Bar";

new $foo();
new $bar();

?>

*) 一重引用符で囲まれた文字列を使用する場合、エスケープする必要はありません。

于 2013-10-28T18:27:35.587 に答える
1

クラス名を文字列に格納するときは、現在の名前空間に関連する名前だけでなく、完全なクラス名を格納する必要があります。

<?php
// global namespace
namespace {
    class Outside {}
}

// Foo namespace
namespace Foo {
    class Foo {}

    $class = "Outside";
    new $class; // works, is the same as doing:
    new \Outside; // works too, calling Outside from global namespace.

    $class = "Foo";
    new $class; // won't work; it's the same as doing:
    new \Foo; // trying to call the Foo class in the global namespace, which doesn't exist

    $class  = "Foo\Foo"; // full class name
    $class  = __NAMESPACE__ . "\Foo"; // as pointed in the comments. same as above.
    new $class; // this will work.
    new Foo; // this will work too.
}
于 2013-10-28T18:46:03.827 に答える