⬆️ ⬇️

Simple, modern MVC framework for PHP to develop websites from scratch

The purpose of this article is to share experience in writing a simple OOP MVC PHP framework. I also want to provide the community with source code and ask for criticism, approval, comments and support.



Introduction



In the course of the operation of various modern frameworks, I realized that I didn’t understand enough how everything is arranged inside; I do not realize why the developers chose this or that solution; I pay attention only to the current task and do not look "higher, deeper and farther." And, as an option for professional growth, I chose to create my own project.



As practice has shown further: to read, know, hear about something, and to be able to realize it yourself are completely different things. Theorizing can be infinite, but only a real practical task allows you to understand at what level you are. In this connection, “writing your own bicycle” was started. How it turned out - to judge you.



Development process



Development of the framework was carried out as follows: initially there was some simple web application that was being developed, copied, changed structure, acquired new classes and components, etc. A few months ago I had free time, a lot of enthusiasm and decisiveness to finish the framework -serious. " I spent 3-4 weeks together to write this version (working on average 1-3 hours per day, 3-4 days per week).

')

As the standards and requirements were developed, I deliberately overestimated myself, I searched for optimal solutions and rewrote the code many times. So, for example, I changed the work with the configuration 5-6 times (and several times dramatically), routing - 3-4 times. As examples, I took the code from articles, publications, manuals, frameworks (Yii2, CodeIgniter, Zend, Phalcon, Bun), etc.



Requirements analysis



It all starts with an analysis of the requirements and wishes for the final system.



The framework should:





Applied technologies



The list of such decisions directly depends on what you know and what you apply in your real practice. Those. We approach the need for continuous monitoring of new products and changes in IT.



Practices and technologies:





Folder structure



I will give the structure of files and folders in the framework (you can also see the code on GitHub ):



image


Code



There is one single entry point in the application. I cite the code of the index.php file from the root public folder of the web server.



session_start(); $loader = require(__DIR__ . '/../../vendor/autoload.php'); $loader->addPsr4('framework\\', __DIR__ . '/../../system/'); $loader->addPsr4('frontend\\', __DIR__ . '/../'); $loader->addPsr4('common\\', __DIR__ . '/../../common/'); $config = array_merge( require(__DIR__ . '/../config/main.php'), require(__DIR__ . '/../../common/config/main.php') ); $appication = new \framework\core\Application(); $appication->run($config); 


The run method code ($ config) from the \ framework \ core \ Application () class. The required classes of the application are loaded and the corresponding controller is called (in the execute () method).



  /** * * @param array $config */ public function run($config = []) { $this->benchmark = new Benchmark(); $this->environment = Environment::get(); $this->config = new Registry($config); $this->response = new Response(); $this->request = Request::getInstance(); $this->assets = new Asset($this->config->assets); $this->setParams(); $this->router = new Router($this->config->routes); $this->execute(); } 


The code for the execute () method from the \ framework \ core \ Application () class. The required controller has already been selected at this stage, we initialize this controller, handle the headers, and display the content. In case of an error - we throw 404 Not Found .



  public function execute() { $controllerName = $this->router->getControllerName(); try { $controllerClass = '\\' . $this->config->name . '\controllers\\' . $controllerName . 'Controller'; if (class_exists($controllerClass)) { $controller = new $controllerClass; if ($controller instanceof Controller) { $controller->setApplication($this)->run(); } } else { throw new CoreException('Controller "' . $controllerName . '" not exists: ' . Request::getInstance()->server["REQUEST_URI"]); } } catch (CoreException $e) { $e->logError(); $this->response->setHeader("HTTP/1.1 404 Not Found"); $this->router->error404(); $this->execute(); exit(); } foreach ($this->response->getHeaders() as $header) { header($header); } echo $this->response->getContent(); } 


Improvements and future plans



As an adapter to connect to the database, I used PDO . In the course of PDO, I didn’t like it very much - it’s hard to debug queries, I want comfort in using ORM. You can install Eloquent ORM - this is a modern and ready-made solution (used in the Laravel framework), and besides, it is well documented and can be installed from the composer in a few minutes.



I also thought about expanding the basic functionality of the framework: I wanted to add support for modules. Those. so that you can write, for example, a blog as a separate module (with its own controllers, viewers, models, etc.). And then connect this module anywhere in the application.



It is possible to expand the base “gentleman’s” set of classes in the core, complicate the system of logging, error handling, configuration, write a full-fledged demo site with all the functionality, etc.



Conclusion



I will be glad to hear criticism of the code, architecture, initial requirements and other things. Comments will be actively read, I will try to answer questions.



I would also like to implement a project based on this framework. That is to say to test the tool in work. It is clear that the search for customers is not at all to this section, but I would like to hear whether it is possible to start a real project with this decision? Popular out-of-the-box frameworks provide functionality 50-100 times better and bigger, difficult to compete with.



→ GitHub Code

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



All Articles