Лекция
Привет, Вы узнаете о том , что такое php namespace, Разберем основные их виды и особенности использования. Еще будет много подробных примеров и описаний. Для того чтобы лучше понимать что такое php namespace, mvc , настоятельно рекомендую прочитать все из категории Выполнение скриптов на стороне сервера PHP (LAMP) NodeJS (Backend) .
Пространство имен (англ. namespace) — некоторое множество, под которым подразумевается модель, абстрактное хранилище или окружение, созданное для логической группировки уникальных идентификаторов (то есть имен). Идентификатор, определенный в пространстве имен, ассоциируется с этим пространством. Один и тот же идентификатор может быть независимо определен в нескольких пространствах. Таким образом, значение, связанное с идентификатором, определенным в одном пространстве имен, может иметь (или не иметь) такое же (а скорее, другое) значение, как и такой же идентификатор, определенный в другом пространстве. Языки с поддержкой пространств имен определяют правила, указывающие, к какому пространству имен принадлежит идентификатор (то есть его определение).wiki


use
Внимание: по каким-то своим основаниям php не допускает использование ключевого слова use в блоках условий и циклах
Внимание: ключевое слово namespase должно быть расположено в самом начале файла сразу после <? php
<? php
namespace A
{
class A
{
public static function say()
{
echo 'Я пространство имен А';
}
}
}
<? php
namespace B
{
class A
{
public static function say()
{
echo 'Я пространство имен B';
}
}
}
<? php
namespace A;
class A
{
public static function say()
{
echo 'Я пространство имен А';
}
}
<? php
require_once 'A.php';
require_once 'B.php';
use A\A;
use B\A;
<? php
require_once 'A.php';
require_once 'B.php';
use A\A;
use B\A;
A\A::say();
B\A::say();
Внимание: использование оператора разрешения области видимости (::) в пространствах имен php не допускается! Единственное для чего он годится — это для обращения к статичным методам класса и константам. Вначале хотели использовать для пространства имен именно его, но затем из-за возникших проблем отказались. Поэтому конструкция вида A::A::say(); недопустима и приведет к ошибке.
Внимание: во избежание недоразумений необходимо экранировать данный символ при его использовании в строках: '\\'
<? php
namespace A
{
class A
{
public static function say()
{
echo 'Я пространство имен А';
}
}
}
namespace A\subA
{
class A
{
public static function say()
{
echo 'Я подпространство имен А';
}
}
}
<? php
require_once 'A.php';
require_once 'B.php';
use A\A as A;
use B\A as B;
use A\subA as sub
A::say();
A::say();
sub::say();
Внимание:Для того, чтобы ваши классы загружались имя класса должно совпадать с именем файла!
<?php
namespace yourNameSpace
{
class Autoloader
{
const debug = 1;
public function __construct(){}
public static function autoload($file)
{
$file = str_replace('\\', '/', $file);
$path = $_SERVER['DOCUMENT_ROOT'] . '/classes';
$filepath = $_SERVER['DOCUMENT_ROOT'] . '/classes/' . $file . '.php';
if (file_exists($filepath))
{
if(Autoloader::debug) Autoloader::StPutFile(('подключили ' .$filepath));
require_once($filepath);
}
else
{
$flag = true;
if(Autoloader::debug) Autoloader::StPutFile(('начинаем рекурсивный поиск'));
Autoloader::recursive_autoload($file, $path, &$flag);
}
}
public static function recursive_autoload($file, $path, $flag)
{
if (FALSE !== ($handle = opendir($path)) && $flag)
{
while (FAlSE !== ($dir = readdir($handle)) && $flag)
{
if (strpos($dir, '.') === FALSE)
{
$path2 = $path .'/' . $dir;
$filepath = $path2 . '/' . $file . '.php';
if(Autoloader::debug) Autoloader::StPutFile(('ищем файл <b>' .$file .'</b> in ' .$filepath));
if (file_exists($filepath))
{
if(Autoloader::debug) Autoloader::StPutFile(('подключили ' .$filepath ));
$flag = FALSE;
require_once($filepath);
break;
}
Autoloader::recursive_autoload($file, $path2, &$flag);
}
}
closedir($handle);
}
}
private static function StPutFile($data)
{
$dir = $_SERVER['DOCUMENT_ROOT'] .'/Log/Log.html';
$file = fopen($dir, 'a');
flock($file, LOCK_EX);
fwrite($file, ('║' .$data .'=>' .date('d.m.Y H:i:s') .'<br/>║<br/>' .PHP_EOL));
flock($file, LOCK_UN);
fclose ($file);
}
}
\spl_autoload_register('yourNameSpace\Autoloader::autoload');
}
<? php
require_once 'Autoloader.php';
use Autoloader as Autoloader;
use A\A as A;
use B\A as B;
use A\subA as sub
A::say();
A::say();
sub::say();
<? php
namespace mySpace
{
class test
{
__construct()
{
//конструктор;
}
function sayName($name)
{
echo 'Привет ' . $name;
}
static function sayOther()
{
echo 'статичный вызов';
}
}
}
<? php require_once 'Autoloader.php'; use Autoloader as Autoloader; use mySpace\test as test //можно, например сделать так $class = 'test'; //приведет к вызову конструктора $obj = new $class; $obj->sayName('test'); //а можно так test\sayName('test2'); //или так $obj::sayName('test'); //а можно так test::sayName('test2');
PHP, начиная с версии 5.3, подарил нам пространство имен. С тех пор идет где-то вялое, а где-то бурное обсуждение, как же это пространство имен использовать?
Некоторые фреймворки, такие как Symphony, Laravel, и, конечно же Zend взяли эту технологию на вооружение.
Все это более или менее вписалось в схему MVC. Осталась одна, наверное вечная, дискуссия, какой же должна быть главная брачная пара приложения — Модель и Контроллер?
Одни нам говорят, что Модель должна быть дородной и толстой и при ней стройный и тонкий Контроллер. Одним словом — матриархат.
Другие, наоборот, считают, что Контроллер должен всем управлять и повелевать, поэтому он получается основательный, упитанный. И при нем худенькая, стройненькая Модель, задача которой сводится к подай-принеси. Такой вот патриархат.
Так что же лучше в схеме MVC? Патриархат или матриархат?
Давайте посмотрим на это с точки зрения построения семейной ячейки на основе демократии. И пусть Namespace нам в этом поможет.
Нам не нравятся толстые, неуклюжие Контроллеры, которые, как слон в посудной лавке, по неосторожности могут раздавить все приложение.
Нам не нравятся также толстые Модели. Ну а кому они нравятся? Они должны быть достойны подиума!
Давайте попробуем с помощью Namespace, как с хорошей сватьей, создать гармоничную семью.
Сначала создадим каркас приложения. Как это ни банально, но пусть это будет блог.
Мы создали основну структуру, где:
С index.php все просто:
<?php
use Blog\Blog as Blog;
/*
* main application
*/
define ("APP_PATH", "/home/oleg/www/viper.dev/");
define ("VIEW_PATH", "/home/oleg/www/viper.dev/Blog/Views/");
spl_autoload_register(function ($class) {
require_once str_replace('\\', '/', $class). '.php';
});
$blog = new Blog();
$blog->run();
/*
* end of index.php
*/
Определяем нужные пути и создаем автозагрузчик.
Автозагрузчик загружает необходимые классы, которые расположены в иерархии папок согласно пространству имен класса. Например, класс Blog\Post\Services\View будет разыскиваться в Blog/Post/Services.
А вот и первая встреча с Namespace.
При старте index.php мы создаем экземпляр приложения Blog, класс которого загружается из Blog/Blog.php.
Посмотрим на него.
<?php namespace Blog;
use Blog\Post\Post as Post;
class Blog
{
public $post;
public function __construct()
{
$this->post = new Post();
}
public function run()
{
$this->post->view->all();
}
}//end class Blog
При создании класса Blog мы внедряем в него класс Post с Namespace Blog\Post и автозагрузчик загружает его из Blog/Post/Post.php.
Наверное, этот класс и можно назвать Контроллером,
<?php namespace Blog\Post;
use Blog\Post\Services\View as View;
class Post
{
public $view;
public function __construct()
{
$this->view = new View();
}
}//end class Post
Сущность Post включает в себя:
— структуру самой записи данных — Blog\Post\Entities\PostEntity.php
<?php namespace Blog\Post\Entities;
class PostEntity
{
public $id;
public $title;
public $body;
}//end class
— службы, обслуживающие запросы Контроллера — Blog\Post\Services\View.php (одна из служб, для примера)
<?php namespace Blog\Post\Services;
use Blog\Utility\Contemplate as Contemplate;
use Blog\Post\Repositories\Db as DB;
class View
{
public $db;
public function __construct()
{
$this->db = new DB();
}//end __construct
public function all()
{
$posts = $this->db->survey();
Contemplate::compose(array(
'header' => 'header',
'main' => 'main',
'footer' => 'footer',
),
array(
'posts' => $posts,
'title' => 'Viper site',
));
}
}//end class PostView
— систему взаимодействия с базой данных — Blog\Post\Repositories\DB.php — вот она, наша тонкая, изящная Модель,
Только подай-принеси, и ничего больше!
<?php namespace Blog\Post\Repositories;
use PDO as PDO;
class DB
{
private $dbh;
public function __construct()
{
$user = 'user';
$pass = 'parole';
try
{
$this->dbh = new PDO('mysql:host=localhost;dbname=test', $user, $pass, array(
PDO::ATTR_PERSISTENT => true ));
} catch (PDOException $e) {
echo "Error!: " . $e->getMessage() . "<br/>";
die();
}
}//end __construct
public function survey()
{
$query_view = $this->dbh->prepare('SELECT * from posts');
$query_view->execute();
return $query_view->fetchAll(PDO::FETCH_CLASS, "Blog\Post\Entities\PostEntity");
}//end survey
}//end class Db
В результате нам удалось создать структуру приложения, где все компоненты хорошо связаны, при этом мы добились четкого разделения классов, где каждый класс выполняет свою задачу. Контроллер у нас тонкий и в то же время мощный. Модель под стать ему. Идеальная семья!
И все багодаря Namespace.
Не спорю, во многих случаях удобен фреймворк. Но, посмотрите, Namespace вам ничего не напоминает?
Четкое разделение на классы, строгая, и в тоже время гибкая, полностью подчиненная разработчику иерархия каталогов и классов.
Отсутствие порою такого весомого довеска в виде сотен файлов и классов в виде фреймворка.
Отсутствие прокрустова ложа правил взаимодействия классов и компонентов.
Статья навеяна размышлениями на эту тему Taylor Otwell, автора фреймворка Laravel, за что ему огромное спасибо.
В заключение, эта статья об php namespace подчеркивает важность того что вы тут, расширяете ваше сознание, знания, навыки и умения. Надеюсь, что теперь ты понял что такое php namespace, mvc и для чего все это нужно, а если не понял, или есть замечания, то не стесняйся, пиши или спрашивай в комментариях, с удовольствием отвечу. Для того чтобы глубже понять настоятельно рекомендую изучить всю информацию из категории Выполнение скриптов на стороне сервера PHP (LAMP) NodeJS (Backend)
Комментарии