downloads | documentation | faq | getting help | mailing lists | licenses | wiki | reporting bugs | php.net sites | links | conferences | my php.net

search for in the

Ключевое слово namespace и константа __NAMESPACE__> <Использование пространства имен: основы
[edit] Last updated: Fri, 25 May 2012

view this page in

Пространства имен и динамические особенности языка

(PHP 5 >= 5.3.0)

На реализацию пространств имен в PHP повлияли и динамические особенности языка. Преобразуем нижеследующий код для использования пространств имен:

Пример #1 Динамически доступные элементы

example1.php:

<?php
class classname
{
    function 
__construct()
    {
        echo 
__METHOD__,"\n";
    }
}
function 
funcname()
{
    echo 
__FUNCTION__,"\n";
}
const 
constname "global";

$a 'classname';
$obj = new $a// выводит classname::__construct
$b 'funcname';
$b(); // выводит funcname
echo constant('constname'), "\n"// выводит global
?>
Необходимо использовать абсолютное имя (имя класса с префиксом пространства имен). Обратите внимание, что нет никакой разницы между полным именем и абсолютным внутри динамического имени класса, функции или константы. Начальный обратный слэш не является необходимым.

Пример #2 Динамически доступные элементы пространства имен

<?php
namespace namespacename;
class 
classname
{
    function 
__construct()
    {
        echo 
__METHOD__,"\n";
    }
}
function 
funcname()
{
    echo 
__FUNCTION__,"\n";
}
const 
constname "namespaced";

include 
'example1.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
?>

Обязательно прочитайте примечание об экранировании имен пространства имен в строках.



add a note add a note User Contributed Notes Пространства имен и динамические особенности языка
Alexander Kirk 06-Jul-2011 12:57
When extending a class from another namespace that should instantiate a class from within the current namespace, you need to pass on the namespace.

<?php // File1.php
namespace foo;
class
A {
    public function
factory() {
        return new
C;
    }
}
class
C {
    public function
tell() {
        echo
"foo";
    }
}
?>

<?php // File2.php
namespace bar;
class
B extends fooA {}
class
C {
    public function
tell() {
        echo
"bar";
    }
}
?>

<?php
include "File1.php";
include
"File2.php";
$b = new barB;
$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.

<?php // File1.php
namespace foo;
class
A {
    protected
$namespace = __NAMESPACE__;
    public function
factory() {
       
$c = $this->namespace . '\C';
        return new
$c;
    }
}
class
C {
    public function
tell() {
        echo
"foo";
    }
}
?>

<?php // File2.php
namespace bar;
class
B extends fooA {
    protected
$namespace = __NAMESPACE__;
}
class
C {
    public function
tell() {
        echo
"bar";
    }
}
?>

<?php
include "File1.php";
include
"File2.php";
$b = new barB;
$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)
scott at intothewild dot ca 07-Aug-2009 03:33
as noted by guilhermeblanco at php dot net,

<?php

 
// fact.php

 
namespace foo;

  class
fact {

    public function
create($class) {
      return new
$class();
    }
  }

?>

<?php

 
// bar.php

 
namespace foo;

  class
bar {
  ...
  }

?>

<?php

 
// index.php
 
 
namespace foo;

  include(
'fact.php');
 
 
$foofact = new fact();
 
$bar = $foofact->create('bar'); // attempts to create \bar
                                  // even though foofact and
                                  // bar reside in \foo

?>
guilhermeblanco at php dot net 16-Jun-2009 12:04
Please be aware of FQCN (Full Qualified Class Name) point.
Many people will have troubles with this:

<?php

// File1.php
namespace foo;

class
Bar { ... }

function
factory($class) {
    return new
$class;
}

// File2.php
$bar = foofactory('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:

<?php

// File1.php
namespace foo;

function
factory($class) {
    if (
$class[0] != '\\') {
        echo
'->';
        
$class = '\\' . __NAMESPACE__ . '\\' . $class;
    }

    return new
$class();
}

// File2.php
$bar = foofactory('Bar'); // Will correctly instantiate \foo\Bar

$bar2 = foofactory('\anotherfoo\Bar'); // Wil correctly instantiate \anotherfoo\Bar

?>

 
show source | credits | stats | sitemap | contact | advertising | mirror sites