<? phpukraine ДОКУМЕНТАЦІЯ
⌕Пошук по платформі
Документація українською

Переклад офіційної документації українською. Кожен розділ показує стан готовності: недоперекладене позначене відкрито, а не приховане.

МОВА · ЧАСТКОВО частковий переклад, оновлено 29 вересня 2026

Простори імен · PHP Manual

ПЕРЕКЛАД НЕПОВНИЙ

Частину підрозділів ще не перекладено, вони показані англійською нижче в тексті або лишились в оригіналі. Готові фрагменти вже перевірені редактором.

Огляд просторів імен

Що таке простори імен (namespaces)? У найширшому значенні це спосіб інкапсулювати елементи. Абстракцію такого роду видно в багатьох місцях. Наприклад, у будь-якій операційній системі теки групують повʼязані файли й слугують простором імен для файлів усередині. Конкретний приклад: файл foo.txt може існувати і в теці /home/greg, і в /home/other, але дві копії foo.txt не можуть співіснувати в одній теці. До того ж, щоб звернутися до файлу foo.txt ззовні теки /home/greg, доводиться додати перед імʼям файлу назву теки й розділювач, отримавши /home/greg/foo.txt. Той самий принцип поширюється на простори імен у програмуванні.

У світі PHP простори імен розвʼязують дві проблеми, з якими стикаються автори бібліотек і застосунків, коли створюють повторно використовувані елементи коду на кшталт класів чи функцій:

  1. Конфлікти імен між кодом, який ви пишете, і внутрішніми класами/функціями/константами PHP або класами/функціями/константами сторонніх розробників.
  2. Можливість дати псевдонім (або скоротити) Дуже_Довгим_Іменам, придуманим для розвʼязання першої проблеми, що поліпшує читабельність коду.

Простори імен PHP дають спосіб згрупувати повʼязані класи, інтерфейси, функції та константи. Ось приклад синтаксису просторів імен у PHP:

<?php
namespace my\name; // див. розділ «Оголошення просторів імен»

class MyClass {}
function myfunction() {}
const MYCONST = 1;

$a = new MyClass;
print $a::class . "\n";
$c = new \my\name\MyClass; // див. розділ «Глобальний простір»
print $c::class . "\n";

$a = strlen('hi'); // див. розділ «Використання просторів імен: відкат
                   // до глобальної функції/константи»
print $a . "\n";

$d = namespace\MYCONST; // див. розділ «Ключове слово namespace і константа
                        // __NAMESPACE__»
print $d . "\n";
$d = __NAMESPACE__ . '\MYCONST';
echo constant($d); // див. розділ «Простори імен і динамічні можливості мови»

Імена просторів імен нечутливі до регістру.

Імʼя простору імен PHP, а також складені імена, що починаються з нього (як-от PHP\Classes), зарезервовані для внутрішніх потреб мови й не повинні використовуватися в коді користувача.

Оголошення просторів імен

Хоча всередині простору імен може міститися будь-який коректний PHP-код, простори імен впливають лише на такі типи коду: класи (зокрема абстрактні класи, трейти та переліки), інтерфейси, функції та константи.

Простори імен оголошуються ключовим словом namespace. Файл, що містить простір імен, повинен оголосити його на початку файлу перед будь-яким іншим кодом, з одним винятком: ключовим словом declare.

<?php
namespace MyProject;

const CONNECT_OK = 1;
class Connection { /* ... */ }
function connect() { /* ... */ }

Повні імена (тобто імена, що починаються зі зворотного слеша) в оголошеннях просторів імен не дозволені, бо такі конструкції трактуються як відносні вирази простору імен.

Єдина конструкція, дозволена перед оголошенням простору імен, це інструкція declare для визначення кодування вихідного файлу. Крім того, перед оголошенням простору імен не може бути жодного не-PHP коду, включно з зайвими пробілами:

<html>
<?php
namespace MyProject; // фатальна помилка - namespace має бути першою інструкцією в скрипті

До того ж, на відміну від будь-якої іншої конструкції PHP, той самий простір імен можна оголосити в кількох файлах, що дозволяє розкидати його вміст по файловій системі.

Оголошення вкладених просторів імен

Подібно до тек і файлів, простори імен PHP теж дозволяють задавати ієрархію імен. Тобто імʼя простору імен може мати підрівні:

<?php
namespace MyProject\Sub\Level;

const CONNECT_OK = 1;
class Connection { /* ... */ }
function connect() { /* ... */  }

Наведений приклад створює константу MyProject\Sub\Level\CONNECT_OK, клас MyProject\Sub\Level\Connection і функцію MyProject\Sub\Level\connect.

Оголошення кількох просторів імен в одному файлі

Кілька просторів імен можна оголосити і в одному файлі. Для цього є два дозволені синтаксиси.

<?php
namespace MyProject;

const CONNECT_OK = 1;
class Connection { /* ... */ }
function connect() { /* ... */  }

namespace AnotherProject;

const CONNECT_OK = 1;
class Connection { /* ... */ }
function connect() { /* ... */  }

Цей синтаксис не рекомендується для обʼєднання просторів імен в одному файлі. Натомість рекомендовано використовувати альтернативний синтаксис із фігурними дужками.

<?php
namespace MyProject {

const CONNECT_OK = 1;
class Connection { /* ... */ }
function connect() { /* ... */  }
}

namespace AnotherProject {

const CONNECT_OK = 1;
class Connection { /* ... */ }
function connect() { /* ... */  }
}

Обʼєднувати кілька просторів імен в одному файлі як практику програмування наполегливо не радять. Основний сценарій такого підходу - складання кількох PHP-скриптів в один файл.

Щоб поєднати глобальний код без простору імен із кодом у просторі імен, підтримується тільки синтаксис із фігурними дужками. Глобальний код слід огорнути інструкцією namespace без імені:

<?php
namespace MyProject {

const CONNECT_OK = 1;
class Connection {
    public static function start() {
        print __METHOD__ . "\n";
    }
}

function connect() {
    print __FUNCTION__ . "\n";
}
}

namespace { // глобальний код
print strlen("hi") . "\n";
MyProject\connect();
MyProject\Connection::start();
}

Поза дужками простору імен не може бути жодного PHP-коду, крім початкової інструкції declare.

<?php
declare(strict_types=1);
namespace MyProject {

const CONNECT_OK = 1;
class Connection {
    public static function start() {
        print __METHOD__ . "\n";
    }
}

function connect() {
    print __FUNCTION__ . "\n";
}
}

namespace { // глобальний код
print strlen("hi") . "\n";
MyProject\connect();
MyProject\Connection::start();
}

Використання просторів імен: основи

Перш ніж говорити про використання просторів імен, треба розібратися, як PHP визначає, який саме елемент простору імен запитує ваш код. Проста аналогія - файлова система. Є три способи звернутися до файлу у файловій системі:

  1. Відносне імʼя файлу, як-от foo.txt. Воно розгортається в currentdirectory/foo.txt, де currentdirectory - поточна тека. Тож якщо поточна тека /home/foo, імʼя розгортається в /home/foo/foo.txt.
  2. Відносний шлях, як-от subdirectory/foo.txt. Він розгортається в currentdirectory/subdirectory/foo.txt.
  3. Абсолютний шлях, як-от /main/foo.txt. Він розгортається в /main/foo.txt.

Той самий принцип можна застосувати до елементів у просторах імен PHP. Наприклад, до імені класу можна звернутися трьома способами:

  1. Некваліфіковане імʼя, тобто імʼя класу без префікса, як-от $a = new foo(); чи foo::staticmethod();. Якщо поточний простір імен - currentnamespace, воно розгортається в currentnamespace\foo. Якщо код глобальний, без простору імен, воно розгортається в foo.

    Одне застереження: некваліфіковані імена функцій і констант розгорнуться в глобальні функції та константи, якщо функцію або константу в просторі імен не визначено. Подробиці див. у розділі «Використання просторів імен: відкат до глобальної функції/константи».

  2. Кваліфіковане імʼя, тобто імʼя класу з префіксом, як-от $a = new subnamespace\foo(); чи subnamespace\foo::staticmethod();. Якщо поточний простір імен - currentnamespace, воно розгортається в currentnamespace\subnamespace\foo. Якщо код глобальний, без простору імен, воно розгортається в subnamespace\foo.

  3. Повне імʼя, тобто імʼя з префіксом глобального оператора, як-от $a = new \currentnamespace\foo(); чи \currentnamespace\foo::staticmethod();. Воно завжди розгортається буквально в те імʼя, яке вказано в коді, тобто currentnamespace\foo.

Ось приклад усіх трьох видів синтаксису в реальному коді:

file1.php

<?php
namespace Foo\Bar\subnamespace;

const FOO = 1;
function foo() {}
class foo
{
    static function staticmethod() {}
}

file2.php

<?php
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,
                                  // метод 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.

<?php
namespace Foo;

function strlen() {}
const INI_ALL = 3;
class Exception {}

print \strlen('hi') . "\n"; // викликає глобальну функцію strlen
print \INI_ALL . "\n"; // звертається до глобальної константи INI_ALL
$c = new \Exception('error'); // створює екземпляр глобального класу Exception
print $c::class . "\n";

Простори імен і динамічні можливості мови

Реалізація просторів імен у PHP зазнала впливу динамічної природи мови. Тож щоб перетворити код на зразок такого прикладу на код із простором імен:

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 = "namespaced";

/* зауважте: у подвійних лапках треба писати "\\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

Обовʼязково прочитайте примітку про екранування імен просторів імен у рядках.

Ключове слово namespace і магічна константа __NAMESPACE__

PHP підтримує два способи абстрактного доступу до елементів поточного простору імен: магічну константу __NAMESPACE__ і ключове слово namespace.

Значення __NAMESPACE__ - це рядок із іменем поточного простору імен. У глобальному коді без простору імен вона містить порожній рядок.

<?php
namespace MyProject;

echo '"', __NAMESPACE__, '"'; // виводить "MyProject"
<?php
echo '"', __NAMESPACE__, '"'; // виводить ""

Константа __NAMESPACE__ корисна для динамічної побудови імен, наприклад:

<?php
namespace MyProject;

function get($classname)
{
    $a = __NAMESPACE__ . '\\' . $classname;
    return new $a;
}

Ключове слово namespace дозволяє явно запросити елемент із поточного простору імен або вкладеного простору. Для просторів імен воно грає ту саму роль, що оператор self для класів.

<?php
namespace MyProject;

use blah\blah as mine; // див. «Використання просторів імен: псевдоніми та імпорт»

blah\mine(); // викликає функцію MyProject\blah\mine()
namespace\blah\mine(); // викликає функцію MyProject\blah\mine()

namespace\func(); // викликає функцію MyProject\func()
namespace\sub\func(); // викликає функцію MyProject\sub\func()
namespace\cname::method(); // викликає статичний метод "method" класу MyProject\cname
$a = new namespace\sub\cname(); // створює обʼєкт класу MyProject\sub\cname
$b = namespace\CONSTANT; // присвоює $b значення константи MyProject\CONSTANT
<?php

namespace\func(); // викликає функцію func()
namespace\sub\func(); // викликає функцію sub\func()
namespace\cname::method(); // викликає статичний метод "method" класу cname
$a = new namespace\sub\cname(); // створює обʼєкт класу sub\cname
$b = namespace\CONSTANT; // присвоює $b значення константи CONSTANT

Використання просторів імен: псевдоніми та імпорт

Можливість звернутися до зовнішнього повного імені через псевдонім, тобто імпорт, є важливою рисою просторів імен. Це схоже на символічні посилання на файл або теку у файлових системах на базі unix.

PHP уміє давати псевдоніми (імпортувати) константам, функціям, класам, інтерфейсам, трейтам, перелікам і просторам імен.

Псевдоніми створюються оператором use. Ось приклад із усіма 5 видами імпорту:

<?php
namespace foo;
use My\Full\Classname as Another;

// те саме, що use My\Full\NSname as NSname
use My\Full\NSname;

// імпорт глобального класу
use ArrayObject;

// імпорт функції
use function My\Full\functionName;

// псевдонім функції
use function My\Full\functionName as func;

// імпорт константи
use const My\Full\CONSTANT;

$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
func(); // викликає функцію My\Full\functionName
echo CONSTANT; // виводить значення My\Full\CONSTANT

Зверніть увагу: для імен у просторах імен (повних імен, що містять розділювач простору імен, як-от Foo\Bar, на відміну від глобальних імен без нього, як-от FooBar) початковий зворотний слеш не потрібен і не рекомендується, бо імена в імпорті мають бути повними й не обробляються відносно поточного простору імен.

PHP також підтримує зручне скорочення, яке дозволяє записати кілька інструкцій 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

Імпорт виконується під час компіляції, тому на динамічні імена класів, функцій чи констант він не впливає.

<?php
use My\Full\Classname as Another, My\Full\NSname;

$obj = new Another; // створює обʼєкт класу My\Full\Classname
$a = 'Another';
$obj = new $a;      // створює обʼєкт класу Another

Крім того, імпорт впливає тільки на некваліфіковані та кваліфіковані імена. Повні імена абсолютні, і імпорт на них не діє.

<?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

Правила області видимості для імпорту

Ключове слово use має бути оголошене в найзовнішній області видимості файлу (глобальній) або всередині оголошень просторів імен. Причина в тому, що імпорт відбувається під час компіляції, а не виконання, тож він не може мати блокової області видимості. Наступний приклад показує неприпустиме вживання ключового слова use:

<?php
namespace Languages;

function toGreenlandic()
{
    use Languages\Danish;

    // ...
}

Правила імпорту діють у межах файлу, тобто включені файли НЕ успадковують правила імпорту батьківського файлу.

Групові оголошення use

Класи, функції та константи, які імпортуються з одного простору імен, можна згрупувати в одній інструкції use.

<?php

use some\namespace\ClassA;
use some\namespace\ClassB;
use some\namespace\ClassC as C;

use function some\namespace\fn_a;
use function some\namespace\fn_b;
use function some\namespace\fn_c;

use const some\namespace\ConstA;
use const some\namespace\ConstB;
use const some\namespace\ConstC;

// еквівалентно такому груповому оголошенню use
use some\namespace\{ClassA, ClassB, ClassC as C};
use function some\namespace\{fn_a, fn_b, fn_c};
use const some\namespace\{ConstA, ConstB, ConstC};

Глобальний простір

Без оголошення простору імен усі визначення класів і функцій потрапляють у глобальний простір, як це було в PHP до появи просторів імен. Префікс \ перед іменем вказує, що імʼя береться з глобального простору навіть у контексті простору імен.

<?php
namespace A\B\C;

/* Ця функція - A\B\C\fopen */
function fopen() {
     /* ... */
     $f = \fopen(...); // викликає глобальну fopen
     return $f;
}

Використання просторів імен: відкат до глобального простору для функцій і констант

Усередині простору імен, натрапивши на некваліфіковане імʼя в контексті імені класу, функції чи константи, PHP розгортає його з різними пріоритетами. Імена класів завжди розгортаються в поточний простір імен. Тому щоб звернутися до внутрішніх або користувацьких класів без простору імен, треба вживати їхнє повне імʼя:

<?php
namespace A\B\C;
class Exception extends \Exception {}

$a = new Exception('hi'); // $a - обʼєкт класу A\B\C\Exception
var_dump($a::class);
$b = new \Exception('hi'); // $b - обʼєкт класу Exception
var_dump($b::class);

$c = new ArrayObject; // фатальна помилка, клас A\B\C\ArrayObject не знайдено

Для функцій і констант PHP відкотиться до глобальних функцій чи констант, якщо функції або константи в просторі імен не існує.

<?php
namespace A\B\C;

const E_ERROR = 45;
function strlen($str)
{
    return \strlen($str) - 1;
}

echo E_ERROR, "\n"; // виводить "45"
echo INI_ALL, "\n"; // виводить "7" - відкат до глобальної INI_ALL

echo strlen('hi'), "\n"; // виводить "1"
if (is_array('hi')) { // виводить "is not array"
    echo "is array\n";
} else {
    echo "is not array\n";
}

Правила розгортання імен

Для цих правил розгортання важливі такі визначення:

Некваліфіковане імʼя

Ідентифікатор без розділювача простору імен, як-от Foo.

Кваліфіковане імʼя

Ідентифікатор із розділювачем простору імен, як-от Foo\Bar.

Повне імʼя

Ідентифікатор із розділювачем простору імен, що починається з розділювача, як-от \Foo\Bar. Простір імен \Foo також є повним іменем.

Відносне імʼя

Ідентифікатор, що починається з namespace, як-от namespace\Foo\Bar.

Імена розгортаються за такими правилами:

  1. Повні імена завжди розгортаються в імʼя без початкового розділювача простору імен. Наприклад, \A\B розгортається в A\B.
  2. Відносні імена завжди розгортаються в імʼя, де namespace замінено на поточний простір імен. Якщо імʼя вжите в глобальному просторі імен, префікс namespace\ відкидається. Наприклад, namespace\A всередині простору імен X\Y розгортається в X\Y\A. Те саме імʼя в глобальному просторі імен розгортається в A.
  3. Для кваліфікованих імен перший сегмент імені перекладається за поточною таблицею імпорту класів/просторів імен. Наприклад, якщо простір імен A\B\C імпортовано як C, імʼя C\D\E перекладається в A\B\C\D\E.
  4. Для кваліфікованих імен, якщо жодне правило імпорту не підходить, до імені додається поточний простір імен. Наприклад, імʼя C\D\E всередині простору імен A\B розгортається в A\B\C\D\E.
  5. Для некваліфікованих імен імʼя перекладається за поточною таблицею імпорту відповідного типу символів. Тобто імена класів і подібних сутностей перекладаються за таблицею імпорту класів/просторів імен, імена функцій - за таблицею імпорту функцій, а константи - за таблицею імпорту констант. Наприклад, після use A\B\C; вживання на кшталт new C() розгортається в імʼя A\B\C(). Так само після use function A\B\foo; вживання на кшталт foo() розгортається в імʼя A\B\foo.
  6. Для некваліфікованих імен, якщо жодне правило імпорту не підходить, а імʼя посилається на клас або подібний символ, додається поточний простір імен. Наприклад, new C() всередині простору імен A\B розгортається в імʼя A\B\C.
  7. Для некваліфікованих імен, якщо жодне правило імпорту не підходить, імʼя посилається на функцію чи константу, а код перебуває поза глобальним простором імен, імʼя розгортається під час виконання. Якщо код у просторі імен A\B, виклик функції foo() розгортається так:
    1. Шукається функція з поточного простору імен: A\B\foo().
    2. Робиться спроба знайти й викликати глобальну функцію foo().
<?php
namespace A;
use B\D, C\E as F;

// виклики функцій

foo();      // спершу пробує викликати "foo", визначену в просторі імен "A"
            // потім викликає глобальну функцію "foo"

\foo();     // викликає функцію "foo", визначену в глобальній області

my\foo();   // викликає функцію "foo", визначену в просторі імен "A\my"

F();        // спершу пробує викликати "F", визначену в просторі імен "A"
            // потім викликає глобальну функцію "F"

// звернення до класів

new B();    // створює обʼєкт класу "B", визначеного в просторі імен "A"
            // якщо не знайдено, пробує автозавантажити клас "A\B"

new D();    // за правилами імпорту створює обʼєкт класу "D", визначеного в просторі імен "B"
            // якщо не знайдено, пробує автозавантажити клас "B\D"

new F();    // за правилами імпорту створює обʼєкт класу "E", визначеного в просторі імен "C"
            // якщо не знайдено, пробує автозавантажити клас "C\E"

new \B();   // створює обʼєкт класу "B", визначеного в глобальній області
            // якщо не знайдено, пробує автозавантажити клас "B"

new \D();   // створює обʼєкт класу "D", визначеного в глобальній області
            // якщо не знайдено, пробує автозавантажити клас "D"

new \F();   // створює обʼєкт класу "F", визначеного в глобальній області
            // якщо не знайдено, пробує автозавантажити клас "F"

// статичні методи/функції простору імен з іншого простору імен

B\foo();    // викликає функцію "foo" з простору імен "A\B"

B::foo();   // викликає метод "foo" класу "B", визначеного в просторі імен "A"
            // якщо клас "A\B" не знайдено, пробує автозавантажити клас "A\B"

D::foo();   // за правилами імпорту викликає метод "foo" класу "D", визначеного в просторі імен "B"
            // якщо клас "B\D" не знайдено, пробує автозавантажити клас "B\D"

\B\foo();   // викликає функцію "foo" з простору імен "B"

\B::foo();  // викликає метод "foo" класу "B" з глобальної області
            // якщо клас "B" не знайдено, пробує автозавантажити клас "B"

// статичні методи/функції простору імен поточного простору імен

A\B::foo();   // викликає метод "foo" класу "B" з простору імен "A\A"
              // якщо клас "A\A\B" не знайдено, пробує автозавантажити клас "A\A\B"

\A\B::foo();  // викликає метод "foo" класу "B" з простору імен "A"
              // якщо клас "A\B" не знайдено, пробує автозавантажити клас "A\B"

FAQ: що треба знати про простори імен

Цей FAQ поділено на дві частини: поширені питання й деякі деталі реалізації, які корисно розуміти повністю.

Спершу поширені питання.

  1. Якщо я не використовую простори імен, чи маю я звертати на все це увагу?
  2. Як користуватися внутрішніми або глобальними класами всередині простору імен?
  3. Як користуватися класами, функціями чи константами простору імен у цьому ж просторі імен?
  4. Як розгортається імʼя на зразок \my\name чи \name?
  5. Як розгортається імʼя на зразок my\name?
  6. Як розгортається некваліфіковане імʼя класу на зразок name?
  7. Як розгортається некваліфіковане імʼя функції або константи на зразок name?

Є й кілька деталей реалізації просторів імен, які корисно розуміти.

  1. Імена імпорту не повинні конфліктувати з класами, визначеними в тому самому файлі.
  2. Вкладені простори імен не дозволені.
  3. Динамічні імена просторів імен (ідентифікатори в лапках) мають екранувати зворотний слеш.
  4. Невизначені константи, вжиті з будь-яким зворотним слешем, завершуються фатальною помилкою.
  5. Не можна перевизначити спеціальні константи null, true чи false.

Якщо я не використовую простори імен, чи маю я звертати на все це увагу?

Ні. Простори імен жодним чином не впливають ні на наявний код, ні на ще не написаний код, що не містить просторів імен. Ви можете писати такий код, якщо хочете:

<?php
$a = new \stdClass;
print $a::class;

Функціонально це еквівалентно такому:

<?php
$a = new stdClass;
print $a::class;

Як користуватися внутрішніми або глобальними класами всередині простору імен?

<?php
namespace foo;
$a = new \stdClass;
print $a::class . "\n";

function test(?\ArrayObject $parameter_type_example = null) {}

$a = \FilesystemIterator::CURRENT_AS_FILEINFO;
print $a . "\n";

// розширення внутрішнього або глобального класу
class MyException extends \Exception {}
print MyException::class . "\n";

Як користуватися класами, функціями чи константами простору імен у цьому ж просторі імен?

<?php
namespace foo;

class MyClass {}

// використання класу з поточного простору імен як типу параметра
function test(?MyClass $parameter_type_example = null) {}
// інший спосіб використати клас з поточного простору імен як тип параметра
function test2(?\foo\MyClass $parameter_type_example = null) {}

// розширення класу з поточного простору імен
class Extended extends MyClass {}
print Extended::class . "\n";

// звернення до глобальної функції
$a = \strlen("test");
print $a . "\n";

// звернення до глобальної константи
$b = \INI_ALL;
print $b . "\n";

Як розгортається імʼя на зразок \my\name чи \name?

Імена, що починаються з \, завжди розгортаються саме в те, на що вони схожі, тож \my\name насправді є my\name, а \Exception - Exception.

<?php
namespace foo;
$a = new \my\name(); // створює екземпляр класу "my\name"
echo \strlen('hi'); // викликає функцію "strlen"
$a = \INI_ALL; // $a отримує значення константи "INI_ALL"

Як розгортається імʼя на зразок my\name?

Імена, що містять зворотний слеш, але не починаються з нього, як-от my\name, можуть розгортатися двома різними способами.

Якщо є інструкція імпорту, що дає імені my псевдонім іншого імені, цей псевдонім застосовується до my в my\name.

Інакше до my\name додається імʼя поточного простору імен.

<?php
namespace foo;
use blah\blah as foo;

$a = new my\name(); // створює екземпляр класу "foo\my\name"
foo\bar::name(); // викликає статичний метод "name" класу "blah\blah\bar"
my\bar(); // викликає функцію "foo\my\bar"
$a = my\BAR; // присвоює $a значення константи "foo\my\BAR"

Як розгортається некваліфіковане імʼя класу на зразок name?

Імена класів без зворотного слеша, як-от name, можуть розгортатися двома різними способами.

Якщо є інструкція імпорту, що дає імені name псевдонім іншого імені, застосовується псевдонім імпорту.

Інакше до name додається імʼя поточного простору імен.

<?php
namespace foo;
use blah\blah as foo;

$a = new name(); // створює екземпляр класу "foo\name"
foo::name(); // викликає статичний метод "name" класу "blah\blah"

Як розгортається некваліфіковане імʼя функції або константи на зразок name?

Імена функцій чи констант без зворотного слеша, як-от name, можуть розгортатися двома різними способами.

Спочатку до name додається імʼя поточного простору імен.

Нарешті, якщо константи чи функції name в поточному просторі імен не існує, береться глобальна константа або функція name, якщо така є.

<?php
namespace foo;
use blah\blah as foo;

const FOO = 1;

function my() {
    print __FUNCTION__ . "\n";
}
function foo() {
    print __FUNCTION__ . "\n";
}
function sort(&$a)
{
    \sort($a); // викликає глобальну функцію "sort"
    $a = array_flip($a);
    return $a;
}

my(); // викликає "foo\my"
print strlen('hi') . "\n"; // викликає глобальну функцію "strlen", бо "foo\strlen" не існує
$arr = array(1,3,2);
$b = sort($arr); // викликає функцію "foo\sort"
var_dump($b);
foo(); // викликає функцію "foo\foo" - імпорт не застосовується

$a = FOO; // присвоює $a значення константи "foo\FOO" - імпорт не застосовується
print $a;
$b = INI_ALL; // присвоює $b значення глобальної константи "INI_ALL"
print $b;

Не перекладено підрозділи FAQ: «Import names must not conflict with classes defined in the same file», «Nested namespaces are not allowed», «Dynamic namespace names (quoted identifiers) should escape backslash», «Undefined Constants referenced using any backslash die with fatal error», «Cannot override special constants null, true or false».

Стан перекладу

Перекладаємо з офіційної документації, розділ за розділом, і не ховаємо недоперекладене. Помітили неточність у терміні чи реченні: напишіть, виправимо.

48%
Готовності
1
У роботі
15
Ще не перекладено
Глосарій термінів