MyTetra Share
Делитесь знаниями!
Пространства имен в PHP 5.3 - Пространства имен и динамические особенности языка
26.03.2017
20:02
Текстовые метки: php, php5, пространство имен, переменная, константа, класс, функция
Раздел: Компьютер - Программирование - Язык PHP

На реализацию пространств имен в PHP повлияли и динамические особенности языка. В 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"
?>


Пример обращения к элементам внутри текущего пространства имен:


<?php

namespace namespacename;


class classname

{

function __construct()

{

echo __METHOD__,"\n";

}

}


function funcname()

{

echo __FUNCTION__,"\n";

}


const constname = "namespaceconstvalue";



$obj = new classname; // выводит "namespacename\classname::__construct"


funcname(); // выводит "namespacename\funcname"


// echo constant('constname'), "\n"; // Будет ошибка. Функция constant() ищет имя 'constname'

// в глобальном пространстве имен. Потому что при

// задании имени через строку контекст теряется.

// В нашем случае constname определено в пространстве

// namespacename, поэтому обращение должно быть

// по строке 'namespacename\constname'

echo constant('namespacename\constname'), "\n"; // выводит "namespaceconstvalue"

echo constname,"\n"; // Простое обращение, тоже выводит "namespaceconstvalue"

?>


Для доступа к элементу внутри пространства имен динамически, то есть через строку, содержащуюся в переменной, необходимо использовать абсолютное имя (имя класса с префиксом пространства имен). Это происходит из-за того, что при использовании динамического обращения (по строке), теряется текущий контекст.

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

<?php

namespace namespacename;


class classname

{

    function __construct()

    {

        echo __METHOD__,"\n";

    }

}


function funcname()

{

    echo __FUNCTION__,"\n";

}


const constname = "namespaceconstvalue";


include 'example1.php'; // Включение файла с элементами в глобальном пространстве имен



// Обращение к именам в текущем пространстве имен

$obj = new classname; // выводит "namespacename\classname::__construct"

funcname(); // выводит "namespacename\funcname"

echo constname, "\n"; // выводит "namespaceconstvalue"



// Следующий код выводит элементы из глобального пространства имен,

// причем обращение идет динамически через имя, содержащееся в переменной.

// Данное обращение очень похоже на предыдущее, но результат - имена из глобального пространства

$a = 'classname';

$obj = new $a; // выводит "classname::__construct"


$b = 'funcname';

$b(); // выводит "funcname"


echo constant('constname'), "\n"; // выводит "global"



// Чтобы динамически обратиться к имени в определенном пространстве имен,

// нужно указать это пространстов имен

$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"; // выводит namespaceconstvalue

echo constant('namespacename\constname'), "\n"; // также выводит namespaceconstvalue

?>


Обратите внимание, что нет никакой разницы между полным именем и абсолютным внутри динамического имени класса, функции или константы. Другими словами, начальный обратный слэш не является необходимым.


Внимание!

При использовании двойных кавычек символ обратного слэша должен быть заэкранирован.
Например:

"\\namespacename\\classname"

В коде это не было показано, т. к. использовались апострофы.

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


Так же в этом разделе:
 
MyTetra Share v.0.52
Яндекс индекс цитирования