2011-11-23 22 views
0

我正在用MVC設計製作一個簡單的PHP應用程序。所有的請求都被髮送到index.php,然後路由到適當的控制器。因爲所有的請求都經過index.php,所以我想在那裏創建一些對象並且能夠全局使用它們,而不管哪個控制器處理請求。即,這些對象是User,ErrorHandlerDatabase類型。在PHP中取消對全局關鍵字的需求

具有全局User類,例如,允許任何控制器檢查用戶是否通過檢查$user->loggedIn(或類似的東西),其中$userindex.php實例登錄。

以下是我在代碼中我描述:

// index.php: 

<?php 
    include('lib/User.php'); 

    $user = new User(); 

    // other stuff that index.php needs to do, perhaps route to FooController 
?> 

// FooController.php: 

<?php 
    class FooController { 
     function __construct() { 
      global $user;   

      if ($user->loggedIn) { 
       // do whatever 
      } 
     } 
    } 
?> 

這只是隨機碼我剛剛輸入了這麼請原諒任何愚蠢的錯誤 - 但我希望你的想法。此代碼將起作用,但global $user;行必須包含在FooController.php內的每個函數中。

這會招人煩的時候每個函數必須有三個global語句,一個用於UserErrorHandlerDatabase。有沒有更好的方式去做這件事,同時保留我的MVC設計?

+0

你可以使用幾種模式來實現這一點。例如,看看Singleton,Multiton和Registry模式。最後一個可能是您替換全局變量的最佳選擇。 – Macmade

+1

爲什麼不將$ user傳遞給控制器​​的構造函數? – CodeZombie

+0

FooController類擴展用戶{...? –

回答

1

我落得這樣做:

class BaseController 
{ 
    public $user, $db, $errors; 

    function __construct() 
    { 
     global $user, $db, $errors; 

     $this->user = $user; 
     $this->db = $db; 
     $this->errors = $errors; 
    } 
} 

每個控制器擴展了BaseController(其中有一些抽象的功能,以及,這僅僅是一個BaseController解決了這一特定問題的例子)。這樣,我只需要使用global一次,然後我可以使用用戶,db和錯誤處理跨每個控制器實例通過簡單地在每個控制器的構造函數調用parent::__construct()然後$this->user提到他們,等

2

你幾乎不需要global。只是不要創建全局變量。

首先。有這樣的事情作爲參數,例如:

function __construct($user) 
{ ... } 

現在,您可以撥打:

$controller = new MyController($user); 

..和你並不需要 '全球性'。

如果您的控制器是管理整個應用程序流的控制器,那更好。在這種情況下,你只需要將它傳遞給幾個類,例如一個數據庫類和一個輸入分析器。如果你不關心這個,你可以讓控制器自己實例化一個數據庫類和解析器。如果您需要支持多種類型的數據庫和多種輸入,則始終可以重構該部分。

然後,可以將這些數據庫設置爲控制器的屬性。每個下一個班級都會知道這個控制器。您可以將控制器實例設置爲全局,或者甚至更好地將其傳遞給其他類的構造函數,因此它們根本不依賴於全局變量。

如果這些類不需要控制器,但只需要一個數據庫,則只能傳遞數據庫類。這將使這些類更加獨立於控制器和任何全局變量,因此您可以在其他應用程序中輕鬆地重用它們,前提是數據庫本身不直接或間接地依賴於控制器。

看看像Kohana這樣的框架。他們很好地解決了這些問題,儘管總有改進的餘地。

+0

您也可以在類public'User;'中設置屬性,然後在您的構造函數$ this-> User = $ user'中設置該屬性。然後在任何你需要用戶類的地方......'$ this-> User'。 – Benjam

+0

是的,這或多或少是我寫的。 – GolezTrol

+1

我不想將$ user,$ database和$ errorhandler(或其他)發送給我製作的每個控制器。這是重點......重點不一定是消除全球變數。它更重要的是必須實例化一次變量,並讓它們在任何控制器中都可訪問,而不必執行其他任何東西(不管是使用'global',檢索singleton實例還是傳遞參數)。 –