PHP5 namespaces
01-07-2011
Често в PHP се налага да се записват дълги имена на класове, функции и константи, за да се избегне дублиране на имената на класове/функции/константи.В PHP5 (php5.3) влиза новата функция за превключване на различни междинни слоеве, чрез който да се избегнат дублираните обекти и да се използват по-кратки имена.Функцията се използва за по-големи framework-ове, като Zend Framework.Преди това, са използвали имена на функциите с 10-20-30 символа в името, което е много неудобно (от нета - Zend_Search_Lucene_Analysis_Analyzer_Common_Text_CaseInsensitive), същото се среща и в Wordpress.Namespace се ползва точно за това.Да можете да използвате едни и същи имена, без да се дублират и да можете да превключвате между тях.

Използването на Namespace става с ключовата дума namespace, която трябва да се запише в самото начало на файла (изключение прави функцията declare, която може да се сложи и преди namespace), иначе ще даде грешка.Запомнете, че namespace работи само за класове, функции и констати.Не работи за var, public, private, protected променливи.


<?php

Namespace Proekt01;

class Welcome
{
const foo = true;

function bar()
{
return 'baz';
}
}

?>


Като за началото, примера е безполезен, но като обектите станат повече, става по-сложно и се налага да се ползват други нови имена.Смятам, че чрез примери се учи най-лесно и като видите при различни опити резултатите, ще вникнете в тях и ще разберете за какво става въпрос.


<?php

Namespace Proekt01;

class Welcome
{
const foo = false;

function bar()
{
return 'baz01';
}
}

Namespace Proekt02;

class Welcome
{
const foo = false;

function bar()
{
return 'baz02';
}
}

echo Proekt01\Welcome::bar(); // Fatal error: Class 'Proekt02\Proekt01\Welcome' not found

echo Welcome::bar(); // baz02

echo "<br />";

echo \Welcome::bar(); // Fatal error: Class 'Welcome' not found

echo \Proekt01\Welcome::bar(); // baz01

echo "<br />";

echo namespace\Welcome::bar(); // baz02

echo "<br />";

echo __NAMESPACE__; // Proekt02

?>


Последния път, когато сме заявили namespace (в случая Proekt02), той автоматично става настоящия namespace.Когато извикваме клас ние ползваме (за static) Welcome::bar(), като в namespace се ползва \Името_на_namespace\Welcome::bar();.Ключовата дума namespace (без да въвеждаме име) връща името на настоящия namespace (namespace\Foo::bar() == Proekt02\Foo::bar()).Namespace се опитва да намери дадения обект в заявката (Proekt02\Foo\Bar например) и ако не го намери, се опитва да го намери в "главния namespace".Когато искате да ползвате дадена функция/обект/константа от друг namespace в функция, която вече има сложен namespace, треябва да сложите \ преди името на функцията.Пример за PHP PDO и namespace;

Namespace MyDBAL;

class DBAL
{
function dbQuery($sql, $fetchMode = \PDO::FETCH_ASSOC)
{
$dbQuery = \PDO::query($sql);
$dbQuery->setFetchMode($fetchMode);
return $dbQuery;
}
}


Могат да се записват и под-имена на namespace-овете и да си именувате под раздели за всеки проект.


<?php

Namespace Proekt\Sub01; // И така до колкото ви трябва \Proekt\Sub1\Sub2\Sub3;

class Welcome {}

?>


Когато сте си заявили всичките namespace-ове в кода, можете да превключвате през тях, чрез ключовата дума use, вместо да пишете цялото име по няколко пъти.

Файл libraries.php

Namespace Proekt\Sub01;

class Welcome
{
const foo = false;

function bar()
{
return 'baz01';
}
}

Namespace Proekt\Sub02;

class Welcome
{
const foo = false;

function bar()
{
return 'baz02';
}
}


Файл index.php

include('/libraries.php');

use Proekt\Sub01;

echo Sub01\Welcome::bar(); // baz01


Ето още един пример за използване, чрез присвояване.


<?php

Namespace Proekt01;

class Welcome
{
const foo = false;

function bar()
{
return 'baz01';
}
}

Namespace Proekt02;

class Welcome
{
const foo = false;

function bar()
{
return 'baz02';
}
}

use Proekt01\Welcome as P01;
use Proekt02\Welcome as P02;

echo P01::bar(); // baz01

echo "<br />";

echo P02::bar(); // baz02

echo "<br />";

echo bar(); // Fatal error: Call to undefined function Proekt02\bar()

echo \bar(); // Fatal error: Call to undefined function bar()

?>


Чрез namespace, можете да промените дори и основна функция в php.


Namespace Proekt03;

function strlen($string)
{
return \strlen($string)-1; // чрез \ пред функцията се извиква глобалната/главната функция strlen.
}

$str = 'Моят проект';
echo \strlen($str); // Глобалната функция, 11
echo "<br />";
echo namespace\strlen($str); // Нашата функция, 10


За още по-детайлна информация на английски можете да погледнете в php.net http://www.php.net/manual/en/language.namespaces.php

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






/ Трябва да сте регистриран за да напишете коментар /