📜 ⬆️ ⬇️

Namespace support in PHP 5.3. Examples of work on ImageCMS

The last five years in the history of PHP have been impressive. This programming language develops much faster in the field of web programming - the PHP 5.4 release has most of the functions required in working with a modern web language. Providing namespace support is one of them. The opportunity is not new (php 5.3), but we used it in our work for the first time. Own practical experience and eager to share.

Using namespace solves the problem of conflict, which quite often bothers the authors of modules and libraries. The namespace allows two files with the same name to exist (as long as they are located in different directories), and also contributes to the readability of the code due to aliases. The word namespace is used to indicate the source of a position within the current namespace or namespace.

Regarding the importance of the namespace specifically for ImageCMS, third-party module developers are now able to create stand-alone modules. After all, the question of the convenience of writing modules can never and should not be completely closed. But to some extent, these or other tasks can be solved.

A few words about what prompted us to this decision.


The ImageCMS script runs on CodeIgniter. The framework suggested that we mix our libraries into " / application / libraries " and connect to the module using a Loader class. This restriction forced us to write manuals for installing my module with an explanation of where to place the files in order to ensure that the module works. And if there is already a file with that name? Or the class name? It was necessary to take care of this.
')
We contacted IRC asking if codeigniter.com/irc namespace support was planned for the near future. The answer was not provided. The same situation was waiting for us on the Changelog page - not a hint that a step in this direction will be made soon. Only on the forum, some of the developments are laid out by users and one commit at https://github.com , which makes it possible to inherit "CI_Controller" (for some reason, they missed CI_Model).

The pleasant fact that we switched to PHP PHP 5.3 on May 25 gave us the opportunity to write these few lines ourselves in order to implement namespace support.

Examples of implementing namespace in the system ImageCMS


The example below is far from the last for the release of the system. It will be rewritten, tested and optimized more than once, but the presented prototype provides an opportunity to see one of the options for implementing namespace support in a PHP project.

Add initialization to the pre_controller hook point

\application\config\hooks.php: $hook['pre_controller'][] = array( 'class' => '', 'function' => 'modules_namespaces_initialize', 'filename' => 'namespaceses.php', 'filepath' => 'third_party/' ); 


But, actually, the initialization itself

 \application\third_party\namespaceses.php: <?php if (!defined('BASEPATH')) exit('No direct script access allowed'); function modules_namespaces_initialize() { if (!defined('PHP_VERSION_ID') || PHP_VERSION_ID < 50300) die('Namespaces requires PHP 5.3 or higher'); spl_autoload_register('modules_namespaces_autoload', false); } function modules_namespaces_autoload($name) { if (strpos($class_name, "\\")) { if (file_exists($file = 'application/modules/' . strtolower(str_replace('\\', DS, $name)) . EXT)) require $file; } } 

Now we have the ability to respond to the connection of classes through the namespace.

To demonstrate the principle of working with the namespace, we give an example of a simple module that pulls a list of users from the database.

Module controller

 \application\modules\feedback\feedback.php: <?php use Feedback\Getuserlist as Getuserlist; if (!defined('BASEPATH')) exit('No direct script access allowed'); class Feedback extends \MY_Controller { public function __construct() { parent::__construct(); } public function index() { $users = Getuserlist::getUsers(); $this->template->add_array(array('users', $users)); $this->display_tpl('feedback'); } } 


Next we need the file getuserlist.php with the class Getuserlist

 <?php namespace Feedback; if (!defined('BASEPATH')) exit('No direct script access allowed'); class Getuserlist extends \MY_Controller { function __construct() { parent::__construct(); } public function getUsers() { return $this->db->get('users')->result(); } } 


Such an approach to the design of classes, many consider unsuccessful. I want to separate the work with the database. So we need to rewrite the getUsers () method so that it transfers work to the model database, thereby abstracting from the process of pulling information.

The new method now looks like this:

 public function getUsers() { return Model::getUsers(); } 


well, add the alias "Model":

 use Feedback\Model as Model, 


We describe the model for working with the database:

 <?php namespace Feedback; if (!defined('BASEPATH')) exit('No direct script access allowed'); class Model extends \CI_Model { function __construct() { parent::__construct(); } public function getUsers() { return $this->db->get('users')->result(); } } 


Now we have a class whose logic is closed to the “Getuserlist” handler, which means that developing and maintaining the code becomes easier.

Result - the module written by you can be easily packaged in one folder and laid out in the extension store with a minimum of installation costs by the end user. The opportunities for the proper construction of the hierarchy of classes and architectural structures are revealed.
We hope our article will help developers solve a similar problem. If there are comments, questions or suggestions - wait in the comments.

Related Links:
http://www.php.net - namespaces
Codeigniter
ImageCMS

Source: https://habr.com/ru/post/148733/


All Articles