Лекция
Привет, Вы узнаете о том , что такое 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)
Комментарии
Оставить комментарий
Выполнение скриптов на стороне сервера PHP (LAMP) NodeJS (Backend)
Термины: Выполнение скриптов на стороне сервера PHP (LAMP) NodeJS (Backend)