(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()
Использование пространств имен: импорт/создание псевдонима имени
(PHP 5 >= 5.3.0)
Возможность ссылаться на внешнее абсолютное имя по псевдониму или импортирование - это важная особенность пространств имен. Это похоже на возможность файловых систем unix создавать символические ссылки на файл или директорию.
Пространства имен PHP поддерживают три вида создания псевдонима имени или импорта: создание псевдонима для имени класса, создание псевдонима для имени интерфейса и для имени пространства имен. Обратите внимание, что импорт функций или констант не поддерживается.
В PHP создание псевдонима имени выполняется с помощью оператора use. Вот пример, показывающий 3 типа импорта:
Пример #1 импорт/создание псевдонима имени с помощью оператора use
<?php
namespace foo;
use My\Full\Classname as Another;
// это тоже самое, что и использование My\Full\NSname как NSname
use My\Full\NSname;
// импортирование глобального класса
use ArrayObject;
$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
?>
PHP дополнительно поддерживает удобное сокращение для задания нескольких операторов use в одной и той же строке
Пример #2 импорт/создание псевдонима имени с помощью оператора use, комбинирование нескольких операторов use
<?php
use My\Full\Classname as Another, My\Full\NSname;
$obj = new Another; // создает объект класса My\Full\Classname
NSname\subns\func(); // вызывает функцию My\Full\NSname\subns\func
?>
Импорт выполняется во время компиляции, и не влияет на имена динамических классов, функций или констант.
Пример #3 Импорт и динамические имена
<?php
use My\Full\Classname as Another, My\Full\NSname;
$obj = new Another; // создает объект класса My\Full\Classname
$a = 'Another';
$obj = new $a; // создает объект класса Another
?>
В дополнение, импорт распространяется только на неполные и полные имена. Абсолютные имена не затрагиваются операцией импорта.
Пример #4 Импортирование и абсолютные имена
<?php
use My\Full\Classname as Another, My\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
?>
Scoping rules for importing
Ключевое слово use должно быть указано в самом начале файла (в глобальной области) или внутри объявления пространства имен. Это необходимо потому, что импорт выполняется во время компиляции, а не во время исполнения, поэтому оно не может быть заключено в блок. Следующий пример показывает недопустимое применение ключевого слова use:
Пример #5 Недопустимое правило импорта
<?php
namespace Languages;
class Greenlandic
{
use Languages\Danish;
...
}
?>
Замечание:
Правила импорта задаются на каждый файл отдельно. Это означает, что присоединяемые файлы НЕ будут наследовать правила импорта из родительского файла.
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.
Importing and aliasing an interface name is also supported.
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 AnimalCanine as Beast;
}
if ($objType == 'bovine') {
use AnimalBovine as Beast;
}
$oBeast = new Beast;
$oBeast->feed();
?>
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;
}
}
?>
