зачем нужно пространство имен в php
Зачем нужно пространство имен в php
(PHP 5 >= 5.3.0, PHP 7, PHP 8)
Ниже приведён пример трёх вариантов синтаксиса в реальном коде:
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
?>
Пример #1 Доступ к глобальным классам, функциям и константам из пространства имён
function strlen () <>
const INI_ALL = 3 ;
class Exception <>
$a = \ strlen ( ‘hi’ ); // вызывает глобальную функцию strlen
$b = \ INI_ALL ; // получает доступ к глобальной константе INI_ALL
$c = new \ Exception ( ‘error’ ); // Создаёт экземпляр глобального класса Exception
?>
Зачем нужно пространство имен в php
(PHP 5 >= 5.3.0, PHP 7, PHP 8)
В PHP пространства имён используются для решения двух проблем, с которыми сталкиваются авторы библиотек и приложений при создании повторно используемых элементов кода, таких как классы и функции:
Пространства имён PHP предоставляют возможность группировать логически связанные классы, интерфейсы, функции и константы.
Пример #1 Пример синтаксиса, использующего пространство имён
namespace my \ name ; // смотрите раздел «Определение пространств имён»
class MyClass <>
function myfunction () <>
const MYCONST = 1 ;
$a = new MyClass ;
$c = new \ my \ name \ MyClass ; // смотрите раздел «Глобальная область видимости»
$a = strlen ( ‘hi’ ); // смотрите раздел «Использование пространств имён: возврат
// к глобальной функции/константе»
Замечание: Имена пространств имён регистронезависимы.
Названия пространств имён PHP и составные названия, начинающиеся с этих (такие как PHP\Classes ), являются зарезервированными для нужд языка и их не следует использовать в пользовательском коде.
User Contributed Notes 6 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
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.
They are visible on this link : http://www.php-fig.org/psr
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
This might be the best practices ever in PHP framework developments, such as Symfony or others.
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.
//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.
php reserve keywords are not allowed as a namespace name.But namespace name «php» can be allowed.
Here are some example:
namespace php;//works
namespace class;//Parse error: syntax error, unexpected ‘class’
namespace const;//Parse error: syntax error, unexpected ‘const’
namespace constant;//works
namespace interface;//Parse error: syntax error, unexpected ‘interface’
namespace function;//Parse error: syntax error, unexpected ‘function’
Зачем нужно пространство имен в php
(PHP 5 >= 5.3.0, PHP 7, PHP 8)
Этот список вопросов разделён на две части: общие вопросы и некоторые особенности реализации, которые полезны для более полного понимания.
Если я не использую пространства имён, следует ли считать что-либо из этого важным?
Нет. Пространства имён не оказывают никакого влияния ни на какой существующий код ни в каком виде или на любой написанный код, который не содержит пространств имён. Вы можете написать такой код, если желаете:
Пример #1 Доступ к глобальным классам вне пространства имён
Это функционально эквивалентно следующему:
Пример #2 Доступ к глобальным классам вне пространства имён
Как мне использовать внутренние или глобальные классы в пространстве имён?
Пример #3 Доступ ко внутренним классам в пространствах имён
namespace foo ;
$a = new \ stdClass ;
$a = \ DirectoryIterator :: CURRENT_AS_FILEINFO ;
// расширение внутреннего или глобального класса
class MyException extends \ Exception <>
?>
Как мне использовать функции классов в пространствах имён или константы в их собственном пространстве имён?
Пример #4 Доступ ко внутренним классам, функциям или константам в пространствах имён
// расширение класса из текущего пространства имён
class Extended extends MyClass <>
// доступ к глобальной функции
$a = \ globalfunc ();
// доступ к глобальной константе
$b = \ INI_ALL ;
?>
Как такое имя как \my\name или \name преобразуется?
Пример #5 Абсолютные имена
Как такое имя, как my\name преобразуется?
Имена, которые содержат обратный слеш, но не начинаются с него, такие как my\name могут быть преобразованы двумя различными способами.
Пример #6 Полные имена
namespace foo ;
use blah \ blah as foo ;
Как неполное имя класса такое как name преобразуется?
Имена классов, которые не содержат обратный слеш, такие как name могут быть преобразованы двумя различными способами.
Если присутствует импортирующее выражение, которое создаёт синоним name другого имени, то применяется этот синоним.
Пример #7 Неполные имена классов
namespace foo ;
use blah \ blah as foo ;
$a = new name (); // создаёт экземпляр класса «foo\name»
foo :: name (); // вызывает статический метод «name» в классе «blah\blah»
?>
Как неполное имя функции или неполное имя константы такое как name преобразуется?
Имена функций или констант, которые не содержат обратного слеша, такие как name могут быть преобразованы двумя различными способами.
Пример #8 Неполные имена функций или констант
namespace foo ;
use blah \ blah as foo ;
Импортируемые имена не должны конфликтовать с классами, определёнными в том же файле.
Следующие комбинации скриптов допустимы:
namespace my \ stuff ;
include ‘file1.php’ ;
include ‘another.php’ ;
use another \ thing as MyClass ;
$a = new MyClass ; // создаёт экземпляр класса «thing» из пространства имён «another»
?>
Вложенные пространства имён недопустимы.
PHP не позволяет вложение пространств имён одно в другое
Динамические имена пространств имён (идентификаторы, взятые в кавычки) должны экранировать символ обратного слеша.
Очень важно представлять это, потому что обратный слеш используется как экранирующий символ внутри строк. Он всегда должен быть продублирован, когда используется внутри строки, иначе появляется риск возникновения неумышленных последствий:
Пример #9 Подводные камни при использовании имени пространства имён внутри строки с двойными кавычками
Ссылаться на неопределённые константы, используя обратный слеш, нельзя. Выводится фатальная ошибка
Пример #10 Неопределённые константы
Невозможно переопределить специальные константы, такие как NULL, TRUE, FALSE, ZEND_THREAD_SAFE или ZEND_DEBUG_BUILD
Любая попытка определить константу пространства имён, которая совпадает с названиями специальных встроенных констант, приведёт к фатальной ошибке.
Пример #11 Неопределённые константы
User Contributed Notes 5 notes
When creating classes or calling static methods from within namespaces using variables, you need to keep in mind that they require the full namespace in order for the appropriate class to be used; you CANNOT use an alias or short name, even if it is called within the same namespace. Neglecting to take this into account can cause your code to use the wrong class, throw a fatal missing class exception, or throw errors or warnings.
In these cases, you can use the magic constant __NAMESPACE__, or specify the full namespace and class name directly. The function class_exists also requires the full namespace and class name, and can be used to ensure that a fatal error won’t be thrown due to missing classes.
namespace Foo ;
class Bar <
public static function test () <
return get_called_class ();
>
>
namespace Foo \ Foo ;
class Bar extends \ Foo \ Bar <
>
var_dump ( Bar :: test () ); // string(11) «Foo\Foo\Bar»
There is a way to define a namespaced constant that is a special, built-in constant, using define function and setting the third parameter case_insensitive to false:
[Editor’s note: that behavior is caused by a bug in PHP 7.0, which has been fixed as of PHP 7.0.7.]
Regarding the entry «Import names cannot conflict with classes defined in the same file».
— I found that since PHP 7.0 this is no longer the case.
In PHP 7.0 you can have a class with a name that matches an imported class (or namespace or both at the same time).
namespace ns1 <
class ns1 <
public static function write () <
echo «ns1\\ns1::write()\n» ;
>
>
>
namespace ns1 \ ns1 <
class ns1c <
public static function write () <
echo «ns1\\ns1\\ns1c::write()\n» ;
>
>
>
namespace ns2 <
use ns1 \ ns1 as ns1 ; // both a class in ns1, and a namespace ns1\ns1
// the next class causes fatal error in php 5.6, not in 7.0
class ns1 <
public static function write () <
echo «ns2\\ns1::write()\n» ;
>
>
ns1 :: write (); // calls imported ns1\ns1::write()
ns1 \ ns1c :: write (); // calls imported ns1\ns1\ns1c::write()
namespace\ ns1 :: write (); // calls ns2\ns1::write()
>
?>
Regarding «Neither functions nor constants can be imported via the use statement.» Actually you can do it in PHP 5.6+:
// importing a function (PHP 5.6+)
use function My \ Full \ functionName ;
// aliasing a function (PHP 5.6+)
use function My \ Full \ functionName as func ;
// importing a constant (PHP 5.6+)
use const My \ Full \ CONSTANT ;
?>
To correct manolachef’s answer: define() ALWAYS defines constants in the GLOBAL namespace.
Зачем нужно пространство имен в php
(PHP 5 >= 5.3.0, PHP 7, PHP 8)
На реализацию пространств имён в PHP повлияли и динамические особенности языка. Преобразуем нижеследующий код для использования пространств имён:
Пример #1 Динамически доступные элементы
Пример #2 Динамически доступные элементы пространства имён
User Contributed Notes 7 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.
When extending a class from another namespace that should instantiate a class from within the current namespace, you need to pass on the namespace.
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
Be careful when using dynamic accessing namespaced elements. If you use double-quote backslashes will be parsed as escape character.
= «\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:
// File1.php
namespace foo ;
// File2.php
$bar = \ foo \ factory ( ‘Bar’ ); // Will try to instantiate \Bar, not \foo\Bar
// File1.php
namespace foo ;
// File2.php
$bar = \ foo \ factory ( ‘Bar’ ); // Will correctly instantiate \foo\Bar
$bar2 = \ foo \ factory ( ‘\anotherfoo\Bar’ ); // Wil correctly instantiate \anotherfoo\Bar
PHP Namespace
Пространство имён (англ. namespace) — некоторое множество, под которым подразумевается модель, абстрактное хранилище или окружение, созданное для логической группировки уникальных идентификаторов (то есть имён). Идентификатор, определенный в пространстве имён, ассоциируется с этим пространством. Один и тот же идентификатор может быть независимо определён в нескольких пространствах. Таким образом, значение, связанное с идентификатором, определённым в одном пространстве имён, может иметь (или не иметь) такое же (а скорее, другое) значение, как и такой же идентификатор, определённый в другом пространстве. Языки с поддержкой пространств имён определяют правила, указывающие, к какому пространству имён принадлежит идентификатор (то есть его определение).wiki
Все ясно? На самом деле все просто. До версии 5.3 в php существовало всего два пространства — глобальное(в котором выполнялся ваш основной код) и локальное(в котором определялись переменные функций).
С версии 5.3 все изменилось. Теперь можно определить свое пространство имен, в котором будут существовать ваши классы методы и т.д.
Надеюсь стало немного понятнее.
Я специально обозвал классы одинаково. Так они определены в разных пространствах, то это два разных класса, несмотря на одинаковые имена. Основной скрипт,-по прежнему, функционирует в глобальном пространстве, здесь ничего не изменилось и в нем, по-прежнему, можно определять классы и функции. Так для чего же тогда нужны пространства? Прежде всего, для уверенности в том, что когда вы подключаете файл, с каким-нибудь фреймворком или библиотекой, ваши классы не переопределят классы фреймворка или наоборот.
Для того, чтобы использовать классы определенные в своем пространстве имен, необходимо в нужном месте(я как правило предпочитаю делать это в начале файла) импортировать определенное вами пространство в глобальное для этого используется ключевое слово
Внимание: по каким-то своим основаниям php не допускает использование ключевого слова use в блоках условий и циклах
возьмем пример с картинок и воплотим его в коде:
Внимание: ключевое слово namespase должно быть расположено в самом начале файла сразу после