2014-02-19 43 views
1

我正在尋找一種方法來要求方法(b)在另一個方法(a)內運行?我不能使用構造,因爲我想在方法(a)中設置函數的參數。如果沒有執行所需的方法(b),我也不希望方法(a)運行。要求運行方法或停止當前方法

例子:

class baseController { 
protected function _require($blah) { 
    # Required code 
} 
} 

class controller extends baseController { 
public function allmethods() { 
    $this->_require('blah') 
    # CODE 
} 
public function fail() { 
    # CODE WITHOUT _require() NOT RUN 
} 
} 

我知道我可以在需要的方法(b)設置一個變量,然後檢查,看是否該變量的方法(一),但這需要我輸入是真的檢查每種方法(a)。我想知道是否有辦法在默認情況下這樣做,所以我不必在每個方法中插入代碼(a)檢查是否運行_require()。

+0

你可以做一個堆棧跟蹤,但它可能更容易做你在說什麼你不想做的事 - 把它包在一個方便的功能... ? –

+0

是的,我想不出有什麼辦法可以解決這個問題,但是在每種方法中添加一個支票是沒有意義的,因爲對於我或者其他開發控制器的人來說,這應該是一種失敗保險,必須進行編碼,那麼它不是一個很大的故障安全。 – Devon

回答

0

因此,我無法找到我想要的確切解決方案,但我對此的處理方式可能有助於未來的其他人。

欲瞭解更多信息,我想這樣做的主要原因是,應用程序可以通過設置訪問ID(參考我的腳本$page)確定用戶是否有權訪問該頁面。雖然我可以根據操作名稱設置訪問級別,但會根據不同的模塊,控制器等產生很多冗餘和衝突。

我如何去改變我的路由器,而不是直接調用操作,我將它設置爲通過執行函數調用該操作。

路由器

try { 
    $controller = new $controllerName; 
    $controller->execute($actionName); 
} 
catch (Exception $e) { 
    ... 
} 

然後在我的baseController(這是由每個控制器擴展)我加的execute(),也是一個的checkAccess如果用戶有訪問,因爲這隻會返回true或false根據。這指的是另一個類(訪問)在訪問級別諮詢數據庫。

baseController

final public function execute($action) { 
    $actionMethod = '_action'.$action; 
    $accessMethod = '_access'.$action; 
    if (!method_exists($this, $actionMethod)) { 
     throw new Exception('Action method not defined.'); 
    } 
    if (!method_exists($this, $accessMethod)) { 
     throw new Exception('Access method not defined.'); 
    } 
    $page = $this->$accessMethod(); 
    if (strtolower($page) != 'public' and !Access::check($page)) { 
     throw new Exception("Access denied for action $action."); 
    } 
    $this->$actionMethod(); 
} 

final public function checkAccess($action) { 
    $actionMethod = '_action'.$action; 
    $accessMethod = '_access'.$action; 
    if (!method_exists($this, $actionMethod) or !method_exists($this, $accessMethod)) { 
     return false; 
    } 

    $page = $this->$accessMethod; 
    if (strtolower($page) == 'public' or Access::check($page)) { 
     return true; 
    } 
    else { 
     return false; 
    } 
} 

最後,現在我可以設置在控制器(動作/接入)兩種不同的保護方法。如果缺少任何一個,execute()會拋出相關異常並停止運行。

示例控制器

class Controller extends baseController { 
    protected function _accessTest() { 
    return 'access_page_id'; 
    } 
    protected function _actionTest() { 
    ...code here... 
    } 
} 
0

也許像「模板方法」模式。

用接口方法創建一個基地。

然後在基類將調用派生類中的實現來實現

version:class baseController { 
    protected function _require($blah) { 
    # Required code 
    } 
    public function oneOfAllMethods() { 
    $this->_require($blah) 
    $this->_oneOfAllMethods() 
    } 
    function _oneOfAllMethods() { 
    $this->fail() 
    } 
    public function fail() { 
    #some code for failure 
    } 

} 

class controller extends baseController { 
    public function _allmethods() { 
    #already called $this->_require('blah') 
    # CODE 
    } 

} 

這樣,你可以調用需要()方法之前或之後派生類的代碼。 通過我不知道PHP所以,對於語法錯誤

1

技術上不能的方式進行道歉,你所描述的,但是你可以用任何控制器爲代理對象/裝飾,像這樣的方式:

class ControllerWrapper 
{ 
    private $controller; 

    public function __construct(baseController $controller) 
    { 
     $this->controller = $controller; 
    } 

    public function __call($method, array $arguments) 
    { 
     $this->controller->_require('blah'); 
     return call_user_func_array([$this->controller, $method], $arguments); 
    } 
} 

$wrapper = new ControllerWrapper($controller); 
$wrapper->allmethods(); 

然後專門用這個包裝來做一切事情;它將確保_require()方法被調用。這種方法的

兩個缺點:

  1. 你有超過獲取傳遞的_require()參數難以控制。
  2. 你不會有任何代碼完成的好處,一些編輯將提供。

我想最好的辦法是有東西拋出異常,如果_require()還沒有被調用。

+0

感謝您的建議。你的答案與我最終做的事情類似,我將很快發佈在這裏,供其他人蔘考。 – Devon

相關問題