2016-06-22 60 views
0

背景从头开始的PHP层次结构MVC设计?

我在过去几个月里一直在研究各种教程,目前正在尝试理解PHP框架。

我正在做这件事的方法之一是试图从头开始设计我自己的非常简单的MVC框架。

我想重新考虑一个应用程序(我已经使用意大利面程序PHP构建过)。此应用程序具有教师前端和管理员后端。

我想单独的担忧,并有网址的这样

http://example.com/{module}/{controller}/{method}/{param-1}/{param-2} 

现在MVC框架我已经拼凑了这一点不处理路由的“模块”(我道歉,如果这不是正确的术语),只有控制器/方法/参数。

所以我已经从应用程序逻辑和/ app /文件夹中分开了public_html,我指定了两个文件夹,我的默认“学习模块”和“管理模块”,以便目录树看起来像这样:

enter image description here

显然这种设计模式是“H”MVC?

我的解决方案

我基本上是利用如果检查is_dir();功能,如果有一个“模块”目录(如“管理员”),然后取消设置第一URL数组元素$url[0]和重新索引阵列至0 ...然后我改变根据URL控制器路径...代码应该更清楚...

<?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)); 
     } 
    } 
} 

这个迄今似乎是为我工作,但.... 。

问题

我不确定这是否是此问题的首选解决方案。调用is_dir()检查每个页面请求会减慢我的应用程序?

您将如何设计解决方案或者我完全误解了这个问题?

非常感谢您的时间和考虑!

+1

'STAT()'是一个 “昂贵” 的系统调用,而这正是'is_dir()'它仅仅是一个包装。但考虑到几乎所有的框架都使用.htaccess文件,这需要apache执行目录及其内容的“stat”以查看文件是否存在,请检查permissiosn等。您可能会很幸运并获得结果来自stat缓存。 –

+0

感谢您的评论马克,很高兴知道和我的一部分更多的研究...问候! –

回答

1

根据我的经验,我经常使用.htaccess文件将任何请求重定向到一个只有index.php文件,这两个文件都放在public_html文件夹中。 .htaccess文件的如下内容(Apache服务器应该是启用了mod_rewrite):

<IfModule mod_rewrite.c> 
RewriteEngine On 
RewriteBase/
RewriteRule ^index\.php$ - [L] 
RewriteCond %{REQUEST_FILENAME} !-f 
RewriteCond %{REQUEST_FILENAME} !-d 
RewriteRule . /index.php [L] 
</IfModule> 

然后,在index.php文件可以解析请求的URL,定义CONFIGS,公共变量,路径等。并包含必要的其他php文件。 一个例子:

require(dirname(__FILE__) . '/your_routing.php'); 
require(dirname(__FILE__) . '/your_configs.php'); 
require(dirname(__FILE__) . '/admin/yourfile.php'); 
... 
+0

这是一个有趣的想法,然而,像这样静态定义URL路径不是不好的做法吗?如果我想改变命名约定呢?仍然,思考和感谢您的答案! –