50

これら2つの違いは何ですか:

use Exception;
use \Exception;

またはそれら:

use Foo\Bar;
use \Foo\Bar;

マニュアルには次のように書かれています。

名前空間名(FooBarなどのグローバル名ではなくFoo \ Barなどの名前空間区切り文字を含む完全修飾名前空間名)の場合、インポート名は完全修飾である必要があるため、先頭の円記号は不要であり、許可されないことに注意してください。現在の名前空間に関連して処理されません。

しかし、上記のすべてのバリアントが機能するため、これは本当に理解できません。つまり、「許可されていない」ことは間違いありません。

調べてみるzend_do_useと、is_global(先頭に円記号がある場合に設定)は、次の場合の警告にのみ使用されます。

namespace {
    use Exception;
}

これは、「非複合名'Exception'のuseステートメントは効果がない」ことを示しています。(と同じuse \Exceptionことをしても効果はほとんどありませんが、警告はスローされません。)

だから:私は何かが欠けていますか?実際に違いはありますか?

4

5 に答える 5

37

マニュアルでは、バックスラッシュは不要であると指定されています。これは、当然、バックスラッシュを使用しても意味が同等であることを意味します。しかし、ご指摘のとおり、マニュアルには許可されていないとのことで、これは誤りです。

ただし、マニュアルには他にも問題があります。彼らはこれを宣伝します:

// importing a global class
use \ArrayObject;

インポート名が現在の名前空間に対して処理されないことが事実である場合、use \ArrayObjectおよびuse ArrayObjectは同じ意味を持つ必要があります。グローバルなもの以外に他に何をuse ArrayObject参照できますか?実際には、エンジンはグローバルエンジンをインポートします。

また、次のようなバグがある場合: http: //bugs.php.net/bug.php?id=49143

基準がどうあるべきかについて混乱があると思います。

あなたの質問に答えるために:違いはありません。ただし、私がスラッシュなしの標準を信じていたエンジン開発者であれば、誰かが書いたケースを考慮する必要はありませんuse \Exception;。おそらくそうだったと思います。

于 2011-02-02T20:08:22.973 に答える
15

実際、現時点では名前空間のインポートに先頭の円記号を使用することに違いはなく、PHPマニュアルの情報も変更されています。

名前空間名(FooBarなどのグローバル名ではなくFoo \ Barなどの名前空間区切り文字を含む完全修飾名前空間名)の場合、インポート名は完全修飾である必要があるため、先頭の円記号は不要であり、推奨されません。現在の名前空間に関連して処理されません。

したがって、現在、先頭の円記号を使用することは推奨されていないという本当の情報がありますが、過去に許可されていなかったという情報はありません。

したがって、現時点では:

use Exception;
use \Exception;

これらの2行は同じように機能しますが、最初の行を使用する必要があります。

于 2014-07-07T10:47:42.213 に答える
6

通常、先頭の円記号は、識別子が絶対であることを定義します。欠落している場合、インタプリタはそれが相対識別子であると想定します。

これは絶対識別子です。

$x = new \Name\Space\To\Class();

先頭にスラッシュがないため、これは相対識別子です。これは、現在の名前空間に関連しています。

namespace Name\Space;
$x = new To\Class;

これは相対識別子でもあります。この場合、use最後の部分(エイリアス)はクラスの最初の部分と同じであるため、ステートメントに対して解決されます。

namespace Other\Name\Space;
use Name\Space;
$x = new Space\To\Class;

ただし、inステートメントnamespaceuseステートメントでは絶対識別子(完全修飾名)のみが許可されているため、ここでは省略してもかまいません。ではnamespace、先頭の円記号を設定することも許可されていません。

PHPがさまざまな名前空間宣言を解決する方法の詳細については、名前空間ルールのマニュアルを参照してください。

于 2011-02-02T20:40:42.483 に答える
-2

先頭の円記号は、グローバル名前空間を意味します。名前空間のスコープ内にいる場合は、それを使用してグローバル名前空間に到達する必要があります。例えば:

namespace A
{
    class A
    {
        public function __construct()
        {
            echo('namespace: A<br />');
        }
    }
}

namespace B\A
{
    class A
    {
        public function __construct()
        {
            echo('namespace: B\\A<br />');
        }
    }
}

namespace B
{
    class B
    {
        public function __construct()
        {
            new \A\A(); // namespace: A
            new A\A(); // namespace: B\A
        }
    }
    new B();
}

先頭の円記号を使用すると絶対パスを取得し、それを使用しない場合は相対パスを取得します。

于 2011-02-08T08:41:21.743 に答える
-3

私たちが持っているとは言わない

namespace MyNamespace
use Exception;
use \Exception;

次に、最初の使用は実際にクラスMyNamespace \ Exceptionをインポートし、2番目の使用はメインクラス\Exceptionのみをインポートします

だからあなたは次のようなものを持つことができます

namespace MyNamespace;
class Exception extends \Exception{ }

そして私はできます

throw new \Exception('Exception from global namespace');
throw new \MyNamespace\Exception('Exception from MyNamespace');
于 2011-01-31T10:08:04.883 に答える