Php use class with namespace
На реализацию пространств имён в PHP повлияли и динамические особенности языка. Преобразуем нижеследующий код для использования пространств имён:
Пример #1 Динамически доступные элементы
class classname
function __construct ()
echo __METHOD__ , «\n» ;
>
>
function funcname ()
echo __FUNCTION__ , «\n» ;
>
const constname = «global» ;
?php
$a = ‘classname’ ;
$obj = new $a ; // выводит classname::__construct
$b = ‘funcname’ ;
$b (); // выводит funcname
echo constant ( ‘constname’ ), «\n» ; // выводит global
?>
Необходимо использовать абсолютное имя (имя класса с префиксом пространства имён). Обратите внимание, что нет никакой разницы между полным именем и абсолютным внутри динамического имени класса, функции или константы. Начальный обратный слеш не является необходимым.
Пример #2 Динамически доступные элементы пространства имён
namespace namespacename ;
class classname
function __construct ()
echo __METHOD__ , «\n» ;
>
>
function funcname ()
echo __FUNCTION__ , «\n» ;
>
const constname = «namespaced» ;
?php
$a = ‘classname’ ;
$obj = new $a ; // выводит classname::__construct
$b = ‘funcname’ ;
$b (); // выводит funcname
echo constant ( ‘constname’ ), «\n» ; // выводит global
/* обратите внимание, что при использовании двойных кавычек символ обратного слеша должен быть заэкранирован. Например, «\\namespacename\\classname» */
$a = ‘\namespacename\classname’ ;
$obj = new $a ; // выводит namespacename\classname::__construct
$a = ‘namespacename\classname’ ;
$obj = new $a ; // также выводит namespacename\classname::__construct
$b = ‘namespacename\funcname’ ;
$b (); // выводит namespacename\funcname
$b = ‘\namespacename\funcname’ ;
$b (); // также выводит namespacename\funcname
echo constant ( ‘\namespacename\constname’ ), «\n» ; // выводит namespaced
echo constant ( ‘namespacename\constname’ ), «\n» ; // также выводит namespaced
?>
User Contributed Notes 8 notes
When extending a class from another namespace that should instantiate a class from within the current namespace, you need to pass on the namespace.
namespace foo ;
class A public function factory () return new C ;
>
>
class C public function tell () echo «foo» ;
>
>
?>
namespace bar ;
class B extends \ foo \ A <>
class C public function tell () echo «bar» ;
>
>
?>
include «File1.php» ;
include «File2.php» ;
$b = new bar \ B ;
$c = $b -> factory ();
$c -> tell (); // «foo» but you want «bar»
?>
You need to do it like this:
When extending a class from another namespace that should instantiate a class from within the current namespace, you need to pass on the namespace.
namespace foo ;
class A protected $namespace = __NAMESPACE__ ;
public function factory () $c = $this -> namespace . ‘\C’ ;
return new $c ;
>
>
class C public function tell () echo «foo» ;
>
>
?>
namespace bar ;
class B extends \ foo \ A protected $namespace = __NAMESPACE__ ;
>
class C public function tell () echo «bar» ;
>
>
?>
include «File1.php» ;
include «File2.php» ;
$b = new bar \ B ;
$c = $b -> factory ();
$c -> tell (); // «bar»
?>
(it seems that the namespace-backslashes are stripped from the source code in the preview, maybe it works in the main view. If not: fooA was written as \foo\A and barB as bar\B)
Important to know is that you need to use the *fully qualified name* in a dynamic class name. Here is an example that emphasizes the difference between a dynamic class name and a normal class name.
namespace namespacename \ foo ;
class classname
<
function __construct ()
<
echo ‘bar’ ;
>
>
$a = ‘\namespacename\foo\classname’ ; // Works, is fully qualified name
$b = ‘namespacename\foo\classname’ ; // Works, is treated as it was with a prefixed «\»
$c = ‘foo\classname’ ; // Will not work, it should be the fully qualified name
// Use dynamic class name
new $a ; // bar
new $b ; // bar
new $c ; // [500]: / — Uncaught Error: Class ‘foo\classname’ not found in
// Use normal class name
new \ namespacename \ foo \ classname ; // bar
new namespacename \ foo \ classname ; // [500]: / — Uncaught Error: Class ‘namespacename\foo\namespacename\foo\classname’ not found
new foo \ classname ; // [500]: / — Uncaught Error: Class ‘namespacename\foo\foo\classname’ not found
Be careful when using dynamic accessing namespaced elements. If you use double-quote backslashes will be parsed as escape character.
$a = «\namespacename\classname» ; //Invalid use and Fatal error.
$a = «\\namespacename\\classname» ; //Valid use.
$a = ‘\namespacename\classname’ ; //Valid use.
?>
Please be aware of FQCN (Full Qualified Class Name) point.
Many people will have troubles with this:
function factory ( $class ) <
return new $class ;
>
// File2.php
$bar = \ foo \ factory ( ‘Bar’ ); // Will try to instantiate \Bar, not \foo\Bar
?>
To fix that, and also incorporate a 2 step namespace resolution, you can check for \ as first char of $class, and if not present, build manually the FQCN:
function factory ( $class ) <
if ( $class [ 0 ] != ‘\\’ ) <
echo ‘->’ ;
$class = ‘\\’ . __NAMESPACE__ . ‘\\’ . $class ;
>
// File2.php
$bar = \ foo \ factory ( ‘Bar’ ); // Will correctly instantiate \foo\Bar
$bar2 = \ foo \ factory ( ‘\anotherfoo\Bar’ ); // Wil correctly instantiate \anotherfoo\Bar
Case you are trying call a static method that’s the way to go:
class myClass
public static function myMethod ()
return «You did it!\n» ;
>
>
$foo = «myClass» ;
$bar = «myMethod» ;
echo $foo :: $bar (); // prints «You did it!»;
?>
It might make it more clear if said this way:
One must note that when using a dynamic class name, function name or constant name, the «current namespace», as in http://www.php.net/manual/en/language.namespaces.basics.php is global namespace.
One situation that dynamic class names are used is in ‘factory’ pattern. Thus, add the desired namespace of your target class before the variable name.
namespaced.php
// namespaced.php
namespace Mypackage ;
class Foo public function factory ( $name , $global = FALSE )
if ( $global )
$class = $name ;
else
$class = ‘Mypackage\\’ . $name ;
return new $class ;
>
>
class A function __construct ()
echo __METHOD__ . «
\n» ;
>
>
class B function __construct ()
echo __METHOD__ . «
\n» ;
>
>
?>
global.php
// global.php
class A function __construct ()
echo __METHOD__ ;
>
>
?>
index.php
// index.php
namespace Mypackage ;
include( ‘namespaced.php’ );
include( ‘global.php’ );
$a = $foo -> factory ( ‘A’ ); // Mypackage\A::__construct
$b = $foo -> factory ( ‘B’ ); // Mypackage\B::__construct
$a2 = $foo -> factory ( ‘A’ , TRUE ); // A::__construct
$b2 = $foo -> factory ( ‘B’ , TRUE ); // Will produce : Fatal error: Class ‘B’ not found in . namespaced.php on line .
?>
as noted by guilhermeblanco at php dot net,
public function create ( $class ) return new $class ();
>
>
$foofact = new fact ();
$bar = $foofact -> create ( ‘bar’ ); // attempts to create \bar
// even though foofact and
// bar reside in \foo
//single or double quotes with single or double backslash in dynamic namespace class.
namespace Country_Name class Mexico function __construct ()echo __METHOD__ , «
» ;
>
>
$a = ‘Country_Name\Mexico’ ; //Country_Name\Mexico::__construct
$a = «Country_Name\Mexico» ;
//Country_Name\Mexico::__construct
$a = ‘\Country_Name\Mexico’ ;
//Country_Name\Mexico::__construct
$a = «\Country_Name\Mexico» ;
//Country_Name\Mexico::__construct
$a = «\\Country_Name\\Mexico» ;
//Country_Name\Mexico::__construct
$o = new $a ;
/* if your namespace name or class name start with lowercase n then you should be alart about the use of single or double quotes with backslash */
namespace name_of_country class Japan function __construct ()
echo __METHOD__ , «
» ;
>
$a = ‘name_of_country\Japan’ ;
//name_of_country\Japan::__construct
$a = «name_of_country\Japan» ;
//name_of_country\Japan::__construct
$a = ‘\name_of_country\Japan’ ;
//name_of_country\Japan::__construct
//$a = «\name_of_country\Japan»;
//Fatal error: Uncaught Error: Class ‘ ame_of_country\Japan’ not found
//In this statement «\name_of_country\Japan» means -first letter n with «\ == new line(«\n). for fix it we can use double back slash or single quotes with single backslash.
$a = «\\name_of_country\\Japan» ;
//name_of_country\Japan::__construct
$o = new $a ;
>
namespace Country_Name class name function __construct ()echo __METHOD__ , «
» ;
>
>
$a = ‘Country_Name\name’ ;
//Country_Name\Norway::__construct
$a = «Country_Name\name» ;
//Country_Name\Norway::__construct
$a = ‘\Country_Name\name’ ;
//Country_Name\Norway::__construct
//$a = «\Country_Name\name»;
//Fatal error: Uncaught Error: Class ‘\Country_Name ame’ not found
//In this statement «\Country_Name\name» at class name’s first letter n with «\ == new line(«\n). for fix it we can use double back slash or single quotes with single backslash
$a = «\\Country_Name\\name» ;
//Country_Name\name::__construct
$o = new $a ;
//»\n == new line are case insensitive so «\N could not affected
- Пространства имён
- Обзор пространств имён
- Определение пространств имён
- Определение подпространств имён
- Описание нескольких пространств имён в одном файле
- Использование пространства имён: основы
- Пространства имён и динамические особенности языка
- Ключевое слово namespace и константа __NAMESPACE__
- Использование пространств имён: импорт/создание псевдонима имени
- Глобальное пространство
- Использование пространств имён: переход к глобальной функции/константе
- Правила разрешения имён
- Часто задаваемые вопросы (FAQ): вещи, которые вам необходимо знать о пространствах имён
Php use class with namespace
- Relative file name like foo.txt . This resolves to currentdirectory/foo.txt where currentdirectory is the directory currently occupied. So if the current directory is /home/foo , the name resolves to /home/foo/foo.txt .
- Relative path name like subdirectory/foo.txt . This resolves to currentdirectory/subdirectory/foo.txt .
- Absolute path name like /main/foo.txt . This resolves to /main/foo.txt .
- Unqualified name, or an unprefixed class name like $a = new foo(); or foo::staticmethod(); . If the current namespace is currentnamespace , this resolves to currentnamespace\foo . If the code is global, non-namespaced code, this resolves to foo . One caveat: unqualified names for functions and constants will resolve to global functions and constants if the namespaced function or constant is not defined. See Using namespaces: fallback to global function/constant for details.
- Qualified name, or a prefixed class name like $a = new subnamespace\foo(); or subnamespace\foo::staticmethod(); . If the current namespace is currentnamespace , this resolves to currentnamespace\subnamespace\foo . If the code is global, non-namespaced code, this resolves to subnamespace\foo .
- Fully qualified name, or a prefixed name with global prefix operator like $a = new \currentnamespace\foo(); or \currentnamespace\foo::staticmethod(); . This always resolves to the literal name specified in the code, currentnamespace\foo .
Here is an example of the three kinds of syntax in actual code:
namespace Foo \ Bar \ subnamespace ;
?php
const FOO = 1 ;
function foo () <>
class foo
static function staticmethod () <>
>
?>namespace Foo \ Bar ;
include ‘file1.php’ ;?php
const FOO = 2 ;
function foo () <>
class foo
static function staticmethod () <>
>/* Unqualified name */
foo (); // resolves to function Foo\Bar\foo
foo :: staticmethod (); // resolves to class Foo\Bar\foo, method staticmethod
echo FOO ; // resolves to constant Foo\Bar\FOO/* Qualified name */
subnamespace \ foo (); // resolves to function Foo\Bar\subnamespace\foo
subnamespace \ foo :: staticmethod (); // resolves to class Foo\Bar\subnamespace\foo,
// method staticmethod
echo subnamespace \ FOO ; // resolves to constant Foo\Bar\subnamespace\FOO/* Fully qualified name */
\ Foo \ Bar \ foo (); // resolves to function Foo\Bar\foo
\ Foo \ Bar \ foo :: staticmethod (); // resolves to class Foo\Bar\foo, method staticmethod
echo \ Foo \ Bar \ FOO ; // resolves to constant Foo\Bar\FOO
?>Note that to access any global class, function or constant, a fully qualified name can be used, such as \strlen() or \Exception or \INI_ALL .
Example #1 Accessing global classes, functions and constants from within a namespace
function strlen () <>
const INI_ALL = 3 ;
class Exception <>$a = \ strlen ( ‘hi’ ); // calls global function strlen
$b = \ INI_ALL ; // accesses global constant INI_ALL
$c = new \ Exception ( ‘error’ ); // instantiates global class Exception
?>