Lecture
A namespace is a set that means a model, an abstract repository, or an environment created for the logical grouping of unique identifiers (that is, names). An identifier defined in a namespace is associated with this space. The same identifier can be independently defined in several spaces. Thus, the value associated with an identifier defined in one namespace may (or may not) have the same (or rather, different) meaning, like the same identifier defined in another space. Namespace-supported languages define rules that indicate to which namespace the identifier (that is, its definition) belongs. Wiki
use
Warning: for some reason, php does not allow the use of the use keyword in blocks of conditions and cycles.
Attention: the namespase keyword must be located at the very beginning of the file immediately after <? 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();
Attention: the use of the scope resolution operator (: :) in php namespaces is not allowed! The only thing for which it is suitable is to refer to static class methods and constants. Initially, they wanted to use it for the namespace, but then, because of the problems that arose, they refused. Therefore, the construction of the form A :: A :: say (); is invalid and will result in an error.
Attention: in order to avoid misunderstanding, it is necessary to escape this symbol when using it in the lines: '\\'
<? 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();
Attention: In order for your classes to load the class name must match the file name!
<?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('dmY 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, starting with version 5.3, gave us a namespace. Since then, there has been a sluggish somewhere, but somewhere there is a heated discussion, how can we use this namespace?
Some frameworks such as Symphony, Laravel, and, of course, Zend have adopted this technology.
All this more or less fit into the MVC scheme. There is only one, probably eternal, discussion, what should be the main marriage couple of the application - Model and Controller?
Some of us are told that the Model should be long and thick and with it a slim and thin Controller. In a word - matriarchy.
Others, on the contrary, believe that the controller should manage and rule everything, so it turns out to be solid, well-fed. And with him a slim, slim Model, whose task comes down to bring-bring. Such is the patriarchy.
So what's better in the MVC scheme? Patriarchy or matriarchy?
Let's look at it from the point of view of building a family unit based on democracy. And let Namespace help us with this.
We don’t like thick, clumsy controllers, which, like an elephant in a china shop, can inadvertently crush the entire application.
We don't like fat models either. Well, who likes them? They must be worthy of the podium!
Let's try using Namespace, as with a good matchmaker, to create a harmonious family.
First, create an application framework. No matter how trite, but let it be a blog.
We have created a basic structure, where:
With index.php, everything is simple:
<?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 */
We define the necessary paths and create an autoloader.
The autoloader loads the necessary classes that are located in the folder hierarchy according to the class namespace. For example, the Blog \ Post \ Services \ View class will be searched in Blog / Post / Services.
And here is the first meeting with Namespace.
When we start index.php, we create an instance of the Blog application, whose class is loaded from Blog / Blog.php.
Let's look at it.
<?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
When creating the Blog class, we embed the Post class in it with Namespace Blog \ Post and the autoloader loads it from Blog / Post / Post.php.
Probably, this class can be called a controller,
<?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
Entity Post includes:
- the structure of the data record itself - Blog \ Post \ Entities \ PostEntity.php
<?php namespace Blog\Post\Entities; class PostEntity { public $id; public $title; public $body; }//end class
- services serving controller requests - Blog \ Post \ Services \ View.php (one of the services, for example)
<?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
- database interaction system - Blog \ Post \ Repositories \ DB.php - this is our thin, elegant Model,
Just bring and bring, and nothing more!
<?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
As a result, we managed to create an application structure, where all components are well connected, and we achieved a clear separation of classes, where each class performs its task. Our controller is thin and powerful at the same time. Model to match him. Perfect family!
And all thanks to Namespace.
I do not argue, in many cases the framework is convenient. But look, does Namespace remind you anything?
A clear division into classes, a strict, and at the same time flexible, fully subordinate to the developer hierarchy of directories and classes.
The absence of such a weighty appendage in the form of hundreds of files and classes in the form of a framework.
Lack of procrustes bed rules for the interaction of classes and components.
The article is inspired by reflections on this topic by Taylor Otwell, author of the Laravel framework, for which he thanks a lot.
Comments
To leave a comment
Running server side scripts using PHP as an example (LAMP)
Terms: Running server side scripts using PHP as an example (LAMP)