2016-06-22 64 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路徑不是不好的做法嗎?如果我想改變命名約定呢?仍然,思考和感謝您的答案! –