PHPでクラスと名前空間をインポートする:主要なバックスラッシュはどのような違いをもたらしますか?
-
27-10-2019 - |
質問
これら2つの違いは何ですか:
use Exception;
use \Exception;
またはそれら:
use Foo\Bar;
use \Foo\Bar;
マニュアル 言う:
NameSpaced名(Foobarなどのグローバル名とは対照的にFoo barなどの名前空間セパレーターを含む完全に適格な名前空間名を含む)の場合、主要なバックスラッシュは不要であり、輸入名は完全に資格がある必要があるため、許可されていないことに注意してください。現在の名前空間に対して処理されません。
しかし、私はこれを本当に理解していません。上記のバリエーションのすべてが機能するため、つまり、間違いなく「許可されていません」。
調べてください zend_do_use
そのことを示した is_global
(セット、先頭のバックスラッシュがある場合)は、次の場合の警告にのみ使用されます。
namespace {
use Exception;
}
「コンパウンド名「例外」を含む使用ステートメントには効果がありません」と言っています。 (同じことをしていますが use \Exception
効果はほとんどありませんが、警告をかけません。)
だから:私は何かが足りないのですか?実際に違いはありますか?
解決
マニュアルは、バックスラッシュを指定します 不要, 、これは当然のことながら、それでも意味が同等であることを使用していることを意味します。しかし、あなたが指摘したように、マニュアルはそれが許可されていないと思われる、それは間違っていると言っています。
ただし、マニュアルには他にも厄介なことがあります。彼らはこれを宣伝します:
// importing a global class
use \ArrayObject;
インポート名が現在の名前空間に対して処理されていないことが事実である場合、 use \ArrayObject
と use ArrayObject
同じ意味が必要です。他に何ができるか use ArrayObject
グローバルなもの以外を参照してください?実際には、エンジンはグローバルなものをインポートします。
また、このようなバグがあります:http://bugs.php.net/bug.php?id=49143
基準がどうあるべきかについて混乱があると思います。
あなたの質問に答えるために:違いはありません。しかし、もし私がエンジン開発者であったなら、非リーディング・スラッシュの基準を信じる人でもあるなら、誰かが書いたケースを考慮する必要はありません use \Exception;
. 。これはおそらくそうだったと思います。
他のヒント
実際、現時点で名前スペースのインポートに際に先頭のバックスラッシュを使用することに違いはありません。 PHPマニュアル 変更されました:
NameSpaced名(Foobarなどのグローバル名とは対照的にFoo barなどの名前空間セパレーターを含む完全に適格な名前空間名を含む)の場合、主要なバックスラッシュは不要であり、 お勧めしません, 、インポート名は完全に資格があり、現在の名前空間に対して処理されていないためです。
したがって、今では、先頭のバックスラッシュを使用することをお勧めしますが、過去に許可されていないという情報はありません。
だから現時点で:
use Exception;
use \Exception;
これらの2行は同じように機能しますが、最初の行を使用する必要があります。
通常、リーディングバックスラッシュは、識別子が絶対的であることを定義します。失われた場合、通訳者は、相対識別子であると想定しています。
これは絶対識別子です:
$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;
しかし、で namespace
と use
ステートメントのみの絶対識別子(完全資格のある名前)のみが許可されています。ここで省略してもかまいません。の namespace
, 、リードバックスラッシュを設定することさえ許可されていません。
PHPがさまざまな名前空間宣言を解決する方法の詳細については、 名前空間ルールマニュアル.
私たちが持っているとは言いません
namespace MyNamespace
use Exception;
use \Exception;
次に、最初の使用は実際にクラスmynamespace 例外をインポートし、2番目の使用はメインクラス例外です。
だからあなたはようなものを持つことができます
namespace MyNamespace;
class Exception extends \Exception{ }
そして、私はできます
throw new \Exception('Exception from global namespace');
throw new \MyNamespace\Exception('Exception from MyNamespace');
主要なバックスラッシュは、グローバルネームスペースを意味します。名前空間の範囲にある場合は、それを使用してグローバルネームスペースに到達する必要があります。例えば:
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();
}
リードバックスラッシュを使用すると、絶対的なパスがあり、それがなければ相対的なパスが得られました。