Пространство имен php кратко

Обновлено: 03.07.2024

Ниже приведен пример трех вариантов синтаксиса в реальном коде:

namespace Foo \ Bar \ subnamespace ;

const FOO = 1 ;
function foo () <>
class foo
static function staticmethod () <>
>
?>

namespace Foo \ Bar ;
include 'file1.php' ;

const FOO = 2 ;
function foo () <>
class foo
static function staticmethod () <>
>

/* Неполные имена */
foo (); // определяется как функция Foo\Bar\foo
foo :: staticmethod (); // определяется как класс Foo\Bar\foo с методом staticmethod
echo FOO ; // определяется как константа Foo\Bar\FOO

/* Полные имена */
subnamespace \ foo (); // определяется как функция Foo\Bar\subnamespace\foo
subnamespace \ foo :: staticmethod (); // определяется как класс Foo\Bar\subnamespace\foo
// c методом staticmethod
echo subnamespace \ FOO ; // определяется как константа Foo\Bar\subnamespace\FOO

/* Абсолютные имена */
\ Foo \ Bar \ foo (); // определяется как функция Foo\Bar\foo
\ Foo \ Bar \ foo :: staticmethod (); // определяется как класс Foo\Bar\foo с методом staticmethod
echo \ Foo \ Bar \ FOO ; // определяется как константа Foo\Bar\FOO
?>

Обратите внимание, что для доступа к любым глобальным классам, функциям или константам, может использоваться абсолютное имя, такое как \strlen() , или \Exception, или \INI_ALL.

function strlen () <>
const INI_ALL = 3 ;
class Exception <>

$a = \ strlen ( 'hi' ); // вызывает глобальную функцию strlen
$b = \ INI_ALL ; // получает доступ к глобальной константе INI_ALL
$c = new \ Exception ( 'error' ); // Создает экземпляр глобального класса Exception
?>

(PHP 5 >= 5.3.0, PHP 7, PHP 8)

Что такое пространства имён? В широком смысле - это один из способов инкапсуляции элементов. Такое абстрактное понятие можно увидеть во многих местах. Например, в любой операционной системе директории служат для группировки связанных файлов и выступают в качестве пространства имён для находящихся в них файлов. В качестве конкретного примера файл foo.txt может находиться сразу в обеих директориях: /home/greg и /home/other , но две копии foo.txt не могут существовать в одной директории. Кроме того, для доступа к foo.txt извне директории /home/greg , мы должны добавить имя директории перед именем файла используя разделитель, чтобы получить /home/greg/foo.txt . Этот же принцип распространяется и на пространства имён в программировании.

В PHP пространства имён используются для решения двух проблем, с которыми сталкиваются авторы библиотек и приложений при создании повторно используемых элементов кода, таких как классы и функции:

  1. Конфликт имён между вашим кодом и внутренними классами/функциями/константами PHP или сторонними.
  2. Возможность создавать псевдонимы (или сокращения) для Ну_Очень_Длинных_Имён, чтобы облегчить первую проблему и улучшить читаемость исходного кода.

Пространства имён в PHP предоставляют возможность группировать логически связанные классы, интерфейсы, функции и константы.

namespace my \ name ; // смотрите раздел "Определение пространств имён"
class MyClass <>
function myfunction () <>
const MYCONST = 1 ;

$a = new MyClass ;
$c = new \ my \ name \ MyClass ; // смотрите раздел "Глобальная область видимости"

$a = strlen ( 'hi' ); // смотрите раздел "Использование пространств имён: возврат
// к глобальной функции/константе"

$d = namespace\ MYCONST ; // смотрите раздел "оператор пространства имён и
// константа __NAMESPACE__"
$d = __NAMESPACE__ . '\MYCONST' ;
echo constant ( $d ); // смотрите раздел "Пространства имён и динамические особенности языка"
?>

Замечание: Имена пространств имён регистронезависимы.

Замечание:

Пространства имён PHP или составные имена, начинающиеся с этого слова (например, такие как PHP\Classes ), зарезервированы для нужд языка, их не следует использовать в пользовательском коде.

User Contributed Notes 7 notes

Thought this might help other newbies like me.

Name collisions means:
you create a function named db_connect, and somebody elses code that you use in your file (i.e. an include) has the same function with the same name.

To get around that problem, you rename your function SteveWa_db_connect which makes your code longer and harder to read.

Now you can use namespaces to keep your function name separate from anyone else's function name, and you won't have to make extra_long_named functions to get around the name collision problem.

So a namespace is like a pointer to a file path where you can find the source of the function you are working with

Just a note: namespace (even nested or sub-namespace) cannot be just a number, it must start with a letter.
For example, lets say you want to use namespace for versioning of your packages or versioning of your API:

namespace Mynamespace\1; // Illegal
Instead use this:
namespace Mynamespace\v1; // OK

//Here is the simple use case of namespace. See how we can use same named class with the help of namespace. This is how namespace resolve naming collision.

public $name = 'mobile user' ;
>

$user = new \ Mobile \ User ;
echo $user -> name ;

class User
public static $name = 'tv user' ;
>

echo \ TV \ User :: $name ;

I should point out that namespaces were implemented in PHP to resolve name clashes in userland code. It was never the intention to eventually change the entire language to use namespaces instead of prefixes (ie: change mysqli_connect() to mysqli/connect()) as this would be a huge BC break.

I should also point out that the PSR standards created by the FIG group are *NOT* the official standards for PHP. While there are coding standards for contributing to PHP core, or for creating extensions, there are none for userland developers who are free to adopt whatever standards they choose.

To people coming here by searching about namespaces, know that a consortium has studied about best practices in PHP, in order to allow developers to have common coding standards.

These best practices are called "PHP Standard Recommendations" , also known as PSR.

Actually there are 5 coding standards categories :
PSR-0 : Autoloading Standard , which goal is to make the use of Namespaces easier, in order to convert a namespace into a file path.
PSR-1 : Basic Coding Standard , basically, standards :)
PSR-2 : Coding Style Guide, where to put braces, how to write a class, etc.
PSR-3 : Logger Interface , how to write a standard logger
PSR-4 : Improved Autoloading , to resolve more Namespaces into paths.

The ones I want to point are PSR-0 and PSR-4 : they use namespaces to resolve a FQCN (Fully qualified class name = full namespace + class name) into a file path.
Basic example, you have this directory structure :
./src/Pierstoval/Tools/MyTool.php

The namespacing PSR-0 or PSR-4 standard tells that you can transform this path into a FQCN.
Read the principles of autoload if you need to know what it means, because it's almost mandatory ;) .

// /index.php
include 'autoloader.php' ;
$tool = new Pierstoval / Tools / MyTool ();
?>

// /src/Pierstoval/Tools/MyTool.php
namespace Pierstoval \ Tools ;
class MyTool <>
?>

// /autoloader.php
function loadClass ( $className ) $fileName = '' ;
$namespace = '' ;

// Sets the include path as the "src" directory
$includePath = dirname ( __FILE__ ). DIRECTORY_SEPARATOR . 'src' ;

if ( false !== ( $lastNsPos = strripos ( $className , '\\' ))) $namespace = substr ( $className , 0 , $lastNsPos );
$className = substr ( $className , $lastNsPos + 1 );
$fileName = str_replace ( '\\' , DIRECTORY_SEPARATOR , $namespace ) . DIRECTORY_SEPARATOR ;
>
$fileName .= str_replace ( '_' , DIRECTORY_SEPARATOR , $className ) . '.php' ;
$fullFileName = $includePath . DIRECTORY_SEPARATOR . $fileName ;

if ( file_exists ( $fullFileName )) require $fullFileName ;
> else echo 'Class "' . $className . '" does not exist.' ;
>
>
spl_autoload_register ( 'loadClass' ); // Registers the autoloader
?>

A standardized autoloader will get the class you want to instanciate (MyTool) and get the FQCN, transform it into a file path, and check if the file exists. If it does, it will include(); ?> it, and if you wrote your class correctly, the class will be available within its correct namespace.
Then, if you have the following code :
= new Pierstoval / Tools / MyTool (); ?>
The autoloader will transform the FQCN into this path :
/src/Pierstoval/Tools/MyTool.php

This might be the best practices ever in PHP framework developments, such as Symfony or others.

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

Зачем нужны пространство имен:

Если грубо говоря, то пространство имён нужно для изоляции разных классов друг от друга, как папки в файловой системе для файлов.

Это позволяет избежать конфликтов между разными классами, особенно удобно когда больше нет нормальных имён для методов класса.

В том дело, рано или поздно, всё равно закончится нормальные имена для классов, если вы делаете какой то очень большой проект и пространство имен помогает с этим справится.

Пространство имен в PHP:

Покажу два примера программы, где показывается как работать с пространство имён в PHP.

Если при запуске PHP скрипта будут два класса с одинаковыми именами, то они вступят в конфликт, что приведет к фатальной ошибке. Это на самом деле не очень удобно, так как постоянно приходится следить за уникальностью имен.

Для примера рассмотрим следующую ситуацию: у вас есть сайт, на котором есть пользователи и админ. При этом в папке users хранятся классы для юзеров, а в папке admin - классы для админа.

Пусть и для юзеров, и для админа нужен некий класс Page , отвечающий за какие-то страницы сайта. При этом для юзеров будет свой класс, а для админа - свой. В таком случае нас и поджидает конфликт имен.

Самый простой способ решения этого конфликта - дать отличающиеся имена классам, например, UsersPage и AdminPage . Этот путь, однако, постепенно ведет к появлению очень длинных имен классов.

В PHP существует и другой путь решения проблемы - пространства имен. Суть в следующем: каждый класс может относится к какому-то пространству имен и при этом уникальность имен классов должна соблюдаться только внутри этого пространства.

То есть, для решения нашей проблемы мы можем сделать следующее: отнести один класс Page к какому-нибудь пространству имен, например, Users , а второй класс Page отнести к другому пространству имен, например, Admin .

Синтаксис пространств имен

Чтобы задать классу пространство имен, нужно первой строчкой файла, в котом хранится этот класс написать команду namespace , а после нее через пробел - название этого пространства.

Если класс относится к какому-нибудь пространству имен, то для создания объекта класса нужно будет указать не только имя класса, но и его пространство имен, разделенные обратным слешем. Давайте посмотрим на примере.

Пусть у нас есть класс Page , не относящийся ни к какому пространству имен. Тогда объект этого класса мы создадим следующим образом:

Пусть теперь этот класс принадлежит пространству имен Admin . В этом случае объект этого класса мы будем создавать уже вот таким образом:

Посмотрим на примере

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

Для класса Page из файла /admin/page.php укажем пространство имен Admin :

А для класса Page из файла /users/page.php укажем пространство имен Users :

Давайте теперь в файле /index.php создадим объект одного и второго класса Page :

Пусть у вас есть папка core и папка project . В каждой из папок есть свой класс Controller . Сделайте так, чтобы эти классы принадлежали разным пространствам имен. В файле index.php создайте объекты одного и второго классов.

Подпространства имен

Пусть теперь у нас есть более сложная ситуация: для админа нужно сделать два класса Page - один с данными страницы, а второй - с представлением этих данных. Пусть первый класс находится в файле /admin/data/page.php , а второй - в файле /admin/view/page.php .

Выше мы уже решили, что все классы из папки admin будут относится к пространству имен Admin . Однако, теперь в этом самом пространстве у нас конфликт двух классов. Для решения проблемы можно сделать дополнительные подпространства имен. Например, можно сделать пространство имен Admin , а в нем подпространства Data и View . В таком случае имена этих подпространств просто записываются через обратный слеш - как при задании пространства имен, так и при создании объекта класса.

Здесь следует уточнить, что уровень вложенности подпространств не ограничен (можно создавать под под пространства в подпространствах и так далее).

Итак, давайте доделаем наш описанный выше пример. Для класса Page из файла /admin/data/page.php укажем пространство имен Admin\Data :

Для класса Page из файла /admin/view/page.php укажем пространство имен Admin\View :

Создадим объекты наших классов:

Пусть у вас есть папка modules/cart . Сделайте так, чтобы все классы из этой папки относились к пространству имен Modules\Cart .

Пусть у вас есть папка modules/shop/cart/ . Сделайте так, чтобы все классы из этой папки относились к пространству имен Modules\Shop\Cart .

Некоторые замечания

В примерах выше имена пространств имен совпадают с именами папок, в которых хранятся файлы. Делать так - хорошая практика, но обязательным это не является.

Читайте также: