2010-09-23 1 views
0

Можете ли вы помочь мне исправить обработку сообщений об ошибках/ошибках в моем сценарии архитектуры управления?Можете ли вы помочь мне исправить обработку сообщений об ошибках/ошибках в моем сценарии архитектуры управления?

Во-первых, позвольте мне опубликовать фактический сценарий ...

Примечание: некоторые из отступы Кодекса откусил, но я не уверен, как это исправить. Я извиняюсь.

class FrontController extends ActionController { 

//Declaring variable(s) 
private static $instance; 
protected $controller; 

//Class construct method 
public function __construct() {} 

//Starts new instance of this class with a singleton pattern 
public static function getInstance() { 
    if(!self::$instance) { 
     self::$instance = new self(); 
    } 
    return self::$instance; 
} 

public function dispatch($throwExceptions = false) { 

    /* Checks for the GET variables $module and $action, and, if present, 
    * strips them down with a regular expression function with a white 
    * list of allowed characters, removing anything that is not a letter, 
    * number, underscore or hyphen. 
    */ 
    $regex = '/[^-_A-z0-9]+/'; 
    $module = isset($_GET['module']) ? preg_replace($regex, '', $_GET['module']) : 'home'; 
    $action = isset($_GET['action']) ? preg_replace($regex, '', $_GET['action']) : 'frontpage'; 

    /* Generates Actions class filename (example: HomeActions) and path to 
    * that class (example: home/HomeActions.php), checks if $file is a 
    * valid file, and then, if so, requires that file. 
    */ 
    $class = ucfirst($module) . 'Actions'; 
    $file = $this->pageDir . '/' . $module . '/' . $class . '.php'; 

    if (!is_file($file)) { 
     throw new FrontControllerException('Page not found!'); 
    } 

    require_once $file; 

    /* Creates a new instance of the Actions class (example: $controller 
    * = new HomeActions();), and passes the registry variable to the 
    * ActionController class. 
    */ 
    $controller = new $class(); 
    $controller->setRegistry($this->registry); 

    try { 
     //Trys the setModule method in the ActionController class 
     $controller->setModule($module); 

     /* The ActionController dispatchAction method checks if the method 
     * exists, then runs the displayView function in the 
     * ActionController class. 
     */  
     $controller->dispatchAction($action); 
    } 
    catch(Exception $error) { 

     /* An exception has occurred, and will be displayed if 
     * $throwExceptions is set to true. 
     */ 
     if($throwExceptions) { 
      echo $error->errorMessage($error); //Full exception echoed 
     } else { 
      echo $error->errorMessage(null); //Simple error messaged echoed 
     } 
    } 
} 
} 

abstract class ActionController { 

//Declaring variable(s) 
protected $registry; 
protected $module; 
protected $registryItems = array(); 

//Class construct method 
public function __construct(){} 

public function setRegistry($registry) { 

    //Sets the registry object 
    $this->registry = $registry; 

    /* Once the registry is loaded, the controller root directory path is 
    * set from the registry. This path is needed for the controller 
    * classes to work properly. 
    */ 
    $this->setPageDir(); 
} 

//Sets the controller root directory from the value stored in the registry 
public function setPageDir() { 
    $this->pageDir = $this->registry->get('pageDir'); 
} 

//Sets the module 
public function setModule($module) { 
    $this->module = $module; 
} 

//Gets the module 
public function getModule() { 
    return $this->module; 
} 

/* Checks for actionMethod in the Actions class (example: doFrontpage() 
* within home/HomeActions.php) with the method_exists function and, if 
* present, the actionMethod and displayView functions are executed. 
*/ 
public function dispatchAction($action) { 
    $actionMethod = 'do' . ucfirst($action); 
    if (!method_exists($this, $actionMethod)) { 
     throw new FrontControllerException('Page not found!'); 
    } 
    $this->$actionMethod(); 
    $this->displayView($action); 
} 

public function displayView($action) { 
    if (!is_file($this->pageDir . '/' . $this->getModule() . '/' . $action . 'View.php')) { 
     throw new FrontControllerException('Page not found!'); 
    } 

    //Sets $this->actionView to the path of the action View file 
    $this->actionView = $this->pageDir . '/' . $this->getModule() . '/' . $action . 'View.php'; 

    //Sets path of the action View file into the registry 
    $this->registry->set('actionView', $this->actionView); 

    //Includes template file within which the action View file is included 
    require_once $this->pageDir . '/default.tpl'; 
} 
} 

class Registry { 

//Declaring variables 
private $store; 

//Class constructor 
public function __construct() {} 

//Sets registry variable 
public function set($label, $object) { 
    $this->store[$label] = $object; 
} 

//Gets registry variable  
public function get($label) { 
    if(isset($this->store[$label])) { 
     return $this->store[$label]; 
    } 
    return false; 
} 

//Adds outside array of registry values to $this->store array 
public function addRegistryArray($registryItems) { 
    foreach ($registryItems as $key => $value) { 
     $this->set($key, $value); 
    } 
} 

//Returns registry array 
public function getRegistryArray() { 
    return $this->store; 
} 
} 

class FrontControllerException extends Exception { 

public function errorMessage($error) { 

    //If throwExceptions is true, then the full exception is returned. 
    $errorMessage = isset($error) ? $error : $this->getMessage(); 
    return $errorMessage; 
} 
} 

Теперь проблема ... Если я ввожу URL с несуществующим модулем (в следующем примере "Л") ...

http://example.com/index.php?module=BLAH&action=frontpage

... Я получаю не просто сообщение об ошибке «Страница не найдена!» но следующее сообщение об ошибке ...

Fatal error: Uncaught exception 'FrontControllerException' with message 'Page not found!' in /web/example.com/library/php/ControlArchitecture.php:45 Stack trace: #0 /web/example.com/index.php(30): FrontController->dispatch(false) #1 {main} thrown in /web/example.com/library/php/ControlArchitecture.php on line 45

Любые идеи о том, почему я не просто получить «страница не найдена!» сообщение (вместо неперехваченного исключения)? Любые идеи о том, как исправить это поведение?

Еще раз спасибо!

ответ

0

Сообщение об ошибке на самом деле говорит обо всем.

Wether аргумента FrontController->dispatch() методов является true или false исключение будет выброшено в любом случае .. (если есть какая-то магия рамки происходит, пожалуйста, дайте нам знать который рамки вы используете)

Так убедитесь, что вы поймать исключение, когда вы вызываете его:

/* ... */ 

    try { 
    FrontController->dispatch(false); 
    } catch (Exception $ex) { 
    echo "Eception caught: " . $ex.getMessage(); 
    } 

/* ... */ 

Update:

Here вы можете прочитать об исключениях в PHP и о том, как их поймать.

О несуществующей проблеме модуля:

$regex = '/[^-_A-z0-9]+/'; 
$module = isset($_GET['module']) ? preg_replace($regex, '', $_GET['module']) : 'home'; 
$action = isset($_GET['action']) ? preg_replace($regex, '', $_GET['action']) : 'frontpage'; 

$class = ucfirst($module) . 'Actions'; 
$file = $this->pageDir . '/' . $module . '/' . $class . '.php'; 

if (!is_file($file)) { 
    throw new FrontControllerException('Page not found!'); 
} 

В IF-Statement только проверяет, является ли файл модуля (Pattern: ModuleActions.php) в этом случае BLAHActions.php существует или нет. После того, как он исключит исключение, ваш звонок будет отменен, и он не будет не будет be обработан. (Это означает, что он не будет даже продолжать проверять параметр Action)

О несуществующей проблеме действия:

Как того, что я понял из отправленного кода, folowing метод:

public function dispatchAction($action) { 
    $actionMethod = 'do' . ucfirst($action); 
    if (!method_exists($this, $actionMethod)) { 
     throw new FrontControllerException('Page not found!'); 
    } 
    $this->$actionMethod(); 
    $this->displayView($action); 
} 

выполняет вызовы требуемого действия (Pattern: doSomething), в этом случае doFrontPage даже не вызывается, потому что ваш код генерирует исключение заранее.

Вызов несуществующих действий не бросает необработанное исключение, потому что это handled в методе FrontController-> отправка() только после проверки модуля:

try { 
    //Trys the setModule method in the ActionController class 
    $controller->setModule($module); 

    /* The ActionController dispatchAction method checks if the method 
    * exists, then runs the displayView function in the 
    * ActionController class. 
    */  
    $controller->dispatchAction($action); 
} 
catch(Exception $error) { 

    /* An exception has occurred, and will be displayed if 
    * $throwExceptions is set to true. 
    */ 
    if($throwExceptions) { 
     echo $error->errorMessage($error); //Full exception echoed 
    } else { 
     echo $error->errorMessage(null); //Simple error messaged echoed 
    } 
} 
+0

Я не использую рамки. Кроме того, где должен быть помещен ваш пример кода в приведенном выше скрипте? Я не понимаю, что вы делаете в своем примере. Я думаю, что, возможно, я не понимаю, с чего начинать «исключение». И как продолжение, почему я получаю это полное сообщение об ошибке с несуществующим модулем, но не с несуществующим действием или представлением? (Большое спасибо за вашу помощь!) – TroubledGuym

+0

Ответил на ваш следующий вопрос. Надеюсь, это по крайней мере НЕКОТОРЫЙ смысл ... (Здесь довольно поздно ;-)) –