PHP 5.6.0 released

名前空間の使用法: エイリアス/インポート

(PHP 5 >= 5.3.0)

外部の完全修飾名をエイリアスで参照したりインポートしたりする機能は、 名前空間において非常に重要なものです。 これは、Unix 系のファイルシステムでファイルやディレクトリへのシンボリックリンクを作成することに似ています。

PHP の名前空間では、3 通りの方法でエイリアスやインポートをサポートしています。 クラス名のエイリアスを作成する方法、インターフェイス名のエイリアスを作成する方法、 そして名前空間名のエイリアスを作成する方法です。 PHP 5.6 以降では、さらに関数や定数のエイリアスやインポートもサポートします。

PHP でのエイリアス作成には use 演算子を使用します。 ここに、5 種類すべてのインポート方法の例を示します。

例1 use 演算子によるインポート/エイリアス

<?php
namespace foo;
use 
My\Full\Classname as Another;

// これは use My\Full\NSname as NSname と同じです
use My\Full\NSname;

// グローバルクラスをインポートします
use ArrayObject;

// 関数をインポートします (PHP 5.6+)
use function My\Full\functionName;

// 関数のエイリアスを定義します (PHP 5.6+)
use function My\Full\functionName as func;

// 定数をインポートします (PHP 5.6+)
use const My\Full\CONSTANT;

$obj = new namespace\Another// foo\Another クラスのオブジェクトのインスタンスを作成します
$obj = new Another// My\Full\Classname クラスのオブジェクトのインスタンスを作成します
NSname\subns\func(); // My\Full\NSname\subns\func 関数をコールします
$a = new ArrayObject(array(1)); // ArrayObject クラスのオブジェクトのインスタンスを作成します
// "use ArrayObject" がなければ、foo\ArrayObject クラスのオブジェクトのインスタンスを作成することになります
func(); // 関数 My\Full\functionName を呼びます
echo CONSTANT// 定数 My\Full\CONSTANT の値を表示します
?>
名前空間つきの名前 (完全修飾形式の名前空間は区切り文字を含んだ Foo\Bar のようなもので、グローバルな場合は区切り文字を含まない FooBar のようになります) では先頭のバックスラッシュは不要で、推奨されないことに注意しましょう。 インポートする名前は完全修飾形式でなければならず、 現在の名前空間からの相対指定で処理されることはないからです。

PHP では、複数の use 文を同一行に置くための便利なショートカットもサポートしています。

例2 use 演算子によるインポート/エイリアスで、複数の use 文を組み合わせる例

<?php
use My\Full\Classname as AnotherMy\Full\NSname;

$obj = new Another// My\Full\Classname クラスのオブジェクトのインスタンスを作成します
NSname\subns\func(); // My\Full\NSname\subns\func 関数をコールします
?>

インポートはコンパイル時に行われるので、動的なクラス名、関数名や定数名には影響を及ぼしません。

例3 インポートと動的名

<?php
use My\Full\Classname as AnotherMy\Full\NSname;

$obj = new Another// My\Full\Classname クラスのオブジェクトのインスタンスを作成します
$a 'Another';
$obj = new $a;      // Another クラスのオブジェクトのインスタンスを作成します
?>

さらにインポートの影響が及ぶのは非修飾名および修飾名のみです。 完全修飾名は絶対的なものであり、インポートの影響を受けることはありません。

例4 インポートと完全修飾名

<?php
use My\Full\Classname as AnotherMy\Full\NSname;

$obj = new Another// My\Full\Classname クラスのオブジェクトのインスタンスを作成します
$obj = new \Another// Another クラスのオブジェクトのインスタンスを作成します
$obj = new Another\thing// My\Full\Classname\thing クラスのオブジェクトのインスタンスを作成します
$obj = new \Another\thing// Another\thing クラスのオブジェクトのインスタンスを作成します
?>

インポート時のスコープ規則

use キーワードの宣言は、ファイル内の一番外側のスコープ (グローバルスコープ) あるいは名前空間宣言の中で行わなければなりません。 これは、インポートが実行時ではなくコンパイル時に行われるためです。 ブロック内のスコープではインポートできません。 次の例は、use キーワードの間違った使い方を示すものです。

例5 間違ったインポートの例

<?php
namespace Languages;

class 
Greenlandic
{
    use 
Languages\Danish;

    ...
}
?>

注意:

インポート規則はファイル単位のものです。つまり、インクルードされたファイルは インクロード元の親ファイルのインポート規則を 引き継ぎません

add a note add a note

User Contributed Notes 10 notes

up
14
x at d dot a dot r dot k dot REMOVEDOTSANDTHIS dot gray dot org
1 year ago
You are allowed to "use" the same resource multiple times as long as it is imported under a different alias at each invocation.

For example:

<?php
use Lend;
use
Lend\l1;
use
Lend\l1 as l3;
use
Lend\l2;
use
Lend\l1\Keller;
use
Lend\l1\Keller as Stellar;
use
Lend\l1\Keller as Zellar;
use
Lend\l2\Keller as Dellar;

...

?>

In the above example, "Keller", "Stellar", and "Zellar" are all references to "\Lend\l1\Keller", as are "Lend\l1\Keller", "l1\Keller", and "l3\Keller".
up
11
k at webnfo dot com
1 year ago
Note that you can not alias global namespace:

use \ as test;

echo test\strlen('');

won't work.
up
11
c dot 1 at smithies dot org
3 years ago
If you are testing your code at the CLI, note that namespace aliases do not work!

(Before I go on, all the backslashes in this example are changed to percent signs because I cannot get sensible results to display in the posting preview otherwise. Please mentally translate all percent signs henceforth as backslashes.)

Suppose you have a class you want to test in myclass.php:

<?php
namespace my%space;
class
myclass {
// ...
}
?>

and you then go into the CLI to test it. You would like to think that this would work, as you type it line by line:

require 'myclass.php';
use my%space%myclass; // should set 'myclass' as alias for 'my%space%myclass'
$x = new myclass; // FATAL ERROR

I believe that this is because aliases are only resolved at compile time, whereas the CLI simply evaluates statements; so use statements are ineffective in the CLI.

If you put your test code into test.php:
<?php
require 'myclass.php';
use
my%space%myclass;
$x = new myclass;
//...
?>
it will work fine.

I hope this reduces the number of prematurely bald people.
up
6
samuel dot roze at gmail dot com
2 years ago
(All the backslashes in namespaces are slashes because I can't figure out how to post backslashes here.)

You can have the same "use" for a class and a namespace. For example, if you have these files:

<?php
// foo/bar.php
namespace foo;

class
bar
{
    public function
__toString ()
    {
        return
'foo\bar\__toString()';
    }
}
?>

<?php
// foo/bar/MyClass.php
namespace foo/bar;

class
MyClass
{
    public function
__toString ()
    {
        return
'foo\bar\MyClass\__toString()';
    }
}
?>

In another namespace, you can do:
<?php
namespace another;
require_once
'foo/bar.php';
require_once
'foo/bar/MyClass.php';

use
foo/bar;

$bar = new bar();
echo
$bar."\n";

$class = new bar/MyClass();
echo
$class."\n";
?>

And it will makes the following output:
foo\bar\__toString()
foo\bar\MyClass\__toString()
up
2
anon
7 months ago
The <?php use ?> statement does not load the class file. You have to do this with the <?php require ?> statement or by using an autoload function.
up
3
cl
1 year ago
Something that is not immediately obvious, particular with PHP 5.3, is that namespace resolutions within an import are not resolved recursively.  i.e.: if you alias an import and then use that alias in another import then this latter import will not be fully resolved with the former import.

For example:
use \Controllers as C;
use C\First;
use C\Last;

Both the First and Last namespaces are NOT resolved as \Controllers\First or \Controllers\Last as one might intend.
up
1
thinice at gmail.com
3 years ago
Because imports happen at compile time, there's no polymorphism potential by embedding the use keyword in a conditonal.

e.g.:

<?php
if ($objType == 'canine') {
  use
Animal\Canine as Beast;
}
if (
$objType == 'bovine') {
  use
Animal\Bovine as Beast;
}

$oBeast = new Beast;
$oBeast->feed();
?>
up
0
Anonymous
1 year ago
The last example on this page shows a possibly incorrect attempt of aliasing, but it is totally correct to import a trait \Languages\Languages\Danish.
up
-5
Jan Tvrdk
3 years ago
Importing and aliasing an interface name is also supported.
up
-6
nsdhami at live dot jp
4 years ago
The "use" keyword can not be declared inside the function or method. It should be declared as global, after the "namespace" as:

<?php

namespace mydir;

// works perfectly
use mydir/subdir/Class1 as Class1;

function
fun1()
{
   
// Parse error: syntax error, unexpected T_USE
   
use mydir/subdir/Class1 as Class1;
}

class
Class2
{
    public function
fun2()
    {
       
// Parse error: syntax error, unexpected T_USE
       
use mydir/subdir/Class1 as Class1;
    }
}
?>
To Top