hazel1919 Posted June 22, 2016 Share Posted June 22, 2016 Hi everyone,I have been working through various tutorials over the past couple of months and am currently trying understand PHP frameworks. One of the ways I am doing this is by trying to design my own very simple MVC framework from scratch.I am trying to re-factor an application (which I have already built using spaghetti procedural PHP). This application has a front end for teachers and a back-end for the administrators. I would like to separate concerns and have URL's like this http://example.com/{module}/{controller}/{method}/{param-1}/{param-2} Now the MVC framework I have cobbled together up to this point does not handle routing for 'modules' (I apologise if this is not the correct terminology), only the controller/method/params. So I have separated the public_html from the app logic and inside of the /app/ folder I have specified two folders, my default "learn module" and the "admin module" so that the directory tree looks like this: Apparently this design pattern is a "H"MVC?My SolutionI am basically making use if the is_dir(); function to check if there is a "module" directory (such as "admin") and then unsetting the first URL array element $url[0] and reindexing the array to 0... then I am changing the controller path according to the URL... the code should be clearer... <?php class App { protected $_module = 'learn'; // default module --> learn protected $_controller = 'home'; // default controller --> home protected $_method = 'index'; // default method --> index protected $_params = []; // default paramatars --> empty array public function __construct() { $url = $this->parseUrl(); // returns the url array // Checks if $url[0] is a module else it is a controller if (!empty($url) && is_dir('../app/' . $url[0])) { $this->_module = $url[0]; // if it is a model then assign it unset($url[0]); if (!empty($url[1]) && file_exists('../app/' . $this->_module . '/controllers/' . $url[1] . '.php')) { $this->_controller = $url[1]; // if $url[1] is also set, it must be a controller unset($url[1]); $url = array_values($url); // reset the array to zero, we are left with {method}{param}{etc..} } // if $url[0] is not a module then it might be a controller... } else if (!empty($url[0]) && file_exists('../app/' . $this->_module . '/controllers/' . $url[0] . '.php')) { $this->controller = $url[0]; // if it is a controller then assign it unset($url[0]); $url = array_values($url); // reset the array to zero } // else if url is empty default {module}{controller}{method} is loaded // default is ../app/learn/home/index.php require_once '../app/' . $this->_module . '/controllers/' . $this->_controller . '.php'; $this->_controller = new $this->_controller; // if there are methods left in the array if (isset($url[0])) { // and the methods are legit if (method_exists($this->_controller, $url[0])) { // sets the method that we will be using $this->_method = $url[0]; unset($url[0]); } // else nothing is set } // if there is anything else left in $url then it is a parameter $this->_params = $url ? array_values($url) : []; // calling everything call_user_func_array([$this->_controller, $this->_method], $this->_params); } public function parseUrl() { // checks if there is a url to work with if (isset($_GET['url'])) { // explodes the url by the '/' and returns an array of url 'elements' return $url = EXPLODE('/', filter_var(rtrim($_GET['url'], '/'), FILTER_SANITIZE_URL)); } } } this so far appears to be working for me, but.....QuestionI am not sure if this is the preferred solution to this issue. Is calling the is_dir() check for every page request going slow down my app? How would you engineer a solution or have I completely misunderstood the issue?Many thanks in advance for your time and consideration!!Hazel, Quote Link to comment https://forums.phpfreaks.com/topic/301377-php-hierarchical-mvc-design-from-scratch/ Share on other sites More sharing options...
Jacques1 Posted June 22, 2016 Share Posted June 22, 2016 (edited) Binding the modules to physical folders isn't really a good idea, because it makes the architecture very inflexible. What if I want a large number of similar modules that share a lot of functionalities? It may not make sense to duplicate the entire folder structure for each one of them. What if I want virtual URLs that don't map to any physical classes at all? It think what you're looking for is a router which processes the URL and maps it to an arbitrary action. This allows you to separate the URL structure from the actual backend structure. It also solves the problem at hand, because instead of making PHP search the folder structure on every request, you register your modules and controllers once. Edited June 22, 2016 by Jacques1 1 Quote Link to comment https://forums.phpfreaks.com/topic/301377-php-hierarchical-mvc-design-from-scratch/#findComment-1533904 Share on other sites More sharing options...
gizmola Posted June 22, 2016 Share Posted June 22, 2016 I agree with Jacques. I was going to suggest you take a look at Symfony's routing component as an example: http://symfony.com/doc/current/create_framework/routing.html Quote Link to comment https://forums.phpfreaks.com/topic/301377-php-hierarchical-mvc-design-from-scratch/#findComment-1533909 Share on other sites More sharing options...
hazel1919 Posted June 23, 2016 Author Share Posted June 23, 2016 Thanks for your kind replies... models needing to be used across the entire application is a good point. Perhaps an improvement to the folder structure is separating the models into one usable folder like this... I will build the framework out and see if it works, I will know if I am repeating any code that I need to make adjustments. This is for my education so it cant hurt! @gizmola, thanks for the link, that is some fantastic documentation and I have been going through the tutorial today... unfortunately there are just too many black boxes which I just don't understand (either why they exist or how to use them), otherwise I would love to jump straight into symfony or laravel and start taking advantage of the genius of the community. That is why I have to learn the basics of MVC/routing/design patterns first. I just cant learn the "how to" without the "why" in the first place. Best regards, Jaques. Quote Link to comment https://forums.phpfreaks.com/topic/301377-php-hierarchical-mvc-design-from-scratch/#findComment-1533950 Share on other sites More sharing options...
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.