Пространство имён в php 5.3 и php 6
Пространство имён (namespace/package) знакомо java и c# программистам, теперь доступно и в php. Нужно оно для того, что-бы не писать длинные перефиксы к названиям классов, как сейчас делается в Zend, PEAR и других библиотеках и платформах для совместимости.
Вместо этого классы, функции, интерфейсы (абстрактные классы) и константы могут быть объединены в одно пространство имён. Глобальные переменные в это пространство не входят.
Простой пример
Определяется пространство ключевым словом namespace
//определяем класс в пространстве
namespace MyCMS::Core;
class System{}
Использование этого класса в третьих библиотеках осуществляется ключевым словом use
require_once('mycms/core.php');
use MyCMS::Core::System; //импортируем только заданный класс
$objSystem=new System;
Как вы уже догадались, разделитель :: работает так же как и вызов статических методов, разделяя уровень пространства имён и конкретный класс. Уровень вложённости пространств можно использовать наряду с модульностью библиотеки, например реализовать пространства Database::MySQL::Adapter и Database::Oracle::Adapter.
Новые возможности и новые проблемы
Если в пространстве имён имя класса перезаписывает ранее объявленный глобальный класс или функцию, то к нему по прежнему можно обратится через ::SomeClassName, однако не зная к какой именно реализации программист обращается может вызвать проблемы. Например можно переобъявить стандартные php функции, поменять sin() и cos() местами, что-бы кому-то жизнь мёдом не казалась.
Для отладки существует рабочая константа __NAMESPACE__.
С двоеточием возникает и проблема неоднозначности:
A::B() // вызов функции B из namespace A
A::B() // вызов статичного метода B у класса A
Читайте по теме:
Оригинал
комментарии (78)
По-моему лучше в оригинале прочитать - например тут - http://ilia.ws/files/phpquebec_php53.pdf
Один только вопрос - почему на в блоге PHP? Перенесли бы.
Согласен, вопрос актуальный, но нужно как-то больше конкретики.
Неоднозначности между функцией в неймспейсе и статическим методом, которая приведена в посте, для интерпретатора, на самом деле, не существует - он не позволит вам иметь в пределах одного пространства имет два одинаковых идентификатора. Что же касается удобства для программиста - ну, извиняйте, думать надо как неймспейсы называть это раз....
и два: в чем концептуальная разница между статическим методом и функцией в неймспейсе, а? (-:
А, ну и ещё: в питоне, например, для обращения к методам объектов и к объектам из ругого пространства имён тоже используется одинаковый синтаксис (точка) и ничего, никто пока не умер (-:
http://en.wikipedia.org/wiki/Method_(computer_science)
http://en.wikipedia.org/wiki/Function_(computer_science)
с точки зрения вызывающего в чем разница?
насколько важно мне знать чем концептуально отличаются класс C и неймспейс N в этих примерах:
C::get_instance();
N::get_instance();
как я понимаю, в неймспейсах он не доступен
2. Обращение к статичным параметрам класса (правда с наследием там вроде баги были)
Как я понимаю c namespace такого не проделаешь, хотя выглядит оно одинаково и вероятно реализуется тоже.
2. см. п. 1
Естественно, если я хочу наследоваться, то разница есть и я вынужден буду узнать как оно устроено, однако вопрос стоял не так.
function __autoload($className) {
$fileName = $className.'.class.php';
require PATH_ROOT."classes/".$fileName;
}
Простейший пример.
Ответ на Ваш вопрос - "а куда еще проще?".
Я делаю это приблизительно так:
function __autoload($className) {
$locations = array('forum', 'fun', 'gallery', 'leecher', 'soap', 'common');
$fileName = $className.'.class.php';
foreach ($locations as $path) {
if (file_exists(PORTAL_PATH_ROOT."classes/".$path."/".$fileName)) {
require PATH_ROOT."classes/".$path."/".$fileName;
break;
}
}
}
Вы же можете массив сделать в конфиге или из базы выбирать, в зависимости от того, как храните информацию о модулях.
Мое мнение относится только к коду выше. И никуда больше. Да, я сам использую require, когда мне надо подключить левый код к своему проекту, который не следует API фреймворка, на котором я работаю.
use MyCMS::Core::System; //импортируем только заданный класс
А разве require_once не "импортировало" уже все то, что было в mycms/core.php?
Как я понимаю, new Class() будет на самом деле делать new MyCMS::Core::System::Class()...
Имхо, бесполезная штука — нагляднее использовать полное название неймспейса или хотя бы алиас...
namespase System.Core
{
class MyClass()
{}
}
А в принципе точка как конкатенация строки — бред полный, плюс куда лучше был бы.