2015-03-31 64 views
1

我使用Kohana View_Core衍生作品来实现我的观点。我想在关机时显示缓冲视图或自定义视图,例如Kohana - 在关机时显示缓冲视图或自定义视图

  1. 如果有运行时间=>显示错误页面
  2. 如果没有任何错误执行期间某些错误/异常=>将显示缓冲输出

View

class View 
{ 

private $file = ''; 

private $data = array(); 

private static $global_data = array(); 

public static $view = ''; 

private function __construct($file = FALSE, array $data = array()) 
{ 
    if ($file !== FALSE) 
    { 
     $this->set_filename($file); 
    } 

    if (!empty($data)) 
    { 
     $this->data = $data + $this->data; 
    } 
} 

/** 
* Creates new view object and returns it. 
* 
* @param string filename 
* @param array variables 
* @return object View 
*/ 
public static function factory($file = FALSE, array $data = array()) 
{ 
    return new View($file, $data); 
} 

/** 
* Captures the output that is generated when a view is included. 
* The view data will be extracted to make local variables. This method 
* is static to prevent object scope resolution. 
* 
* @param string filename 
* @param array variables 
* @return string 
*/ 
public static function capture($view_filename, array $view_data) 
{ 
    extract($view_data, EXTR_SKIP); 

    ob_start(); 

    try 
    { 
     require $view_filename; 
    } 
    catch (Exception $error) 
    { 
     $ob_handlers = ob_list_handlers(); 

     if (!empty($ob_handlers)) 
     { 
      ob_end_clean(); 
     } 

     throw $error; 
    } 

    return ob_get_clean(); 
} 

/** 
* Load view file 
* 
* @param string filename 
* @return boolean 
* @return object View 
*/ 
public function set_filename($file) 
{ 
    if (strpos($file, APP_DIR) === FALSE) 
    { 
     $extension = strrpos($file, '.') === FALSE ? '.php' : ''; 

     $path = APP_DIR.DIR_SEP.'system'.DIR_SEP.'views'.DIR_SEP.$file.$extension; 
    } 
    else 
    { 
     $path = $file; 
    } 

    if (!file_exists($path)) 
    { 
     Error::throw_throwable('Unable to find file '.$path); 
    } 

    $this->file = $path; 

    return $this; 
} 

/** 
* Sets a global variable, similar to the set() method. 
* 
* @param string variable name 
* @param mixed variable value 
* @return object View 
*/ 
public static function set_global($key, $value = FALSE) 
{ 
    self::$global_data[$key] = $value; 
} 

/** 
* Assigns a variable by name. 
* 
* @param string variable name or an array of variables 
* @param mixed variable value 
* @return object View 
*/ 
public function set($key, $value = FALSE) 
{ 
    if (is_array($key)) 
    { 
     foreach ($key as $name => $value) 
     { 
      $this->data[$name] = $value; 
     } 
    } 
    else 
    { 
     $this->data[$key] = $value; 
    } 

    return $this; 
} 

/** 
* Renders the view object to a string. 
* 
* @throws exception 
* @param string filename 
* @return string 
*/ 
public function render($file = FALSE) 
{ 
    if ($file !== FALSE) 
    { 
     $this->set_filename($file); 
    } 

    if (empty($this->file)) 
    { 
     Error::throw_throwable('Unable to find file '.$this->file); 
    } 

    $data = array_merge(View::$global_data, $this->data); 

    return View::capture($this->file, $data); 
} 

public function __toString() 
{ 
    try 
    { 
     $result = $this->render(); 

     return $result; 
    } 
    catch (Exception $error) 
    { 
     Error::throw_throwable($error); 
    } 
} 

public function __set($key, $value) 
{ 
    $this->set($key, $value); 
} 

public function __get($key) 
{ 
    return isset($this->data[$key]) ? $this->data[$key] : FALSE; 
} 

} 

用法

$content = View::factory('main/Main') 
      ->set('order', !empty($_SESSION['order']) ? $_SESSION['order'] : FALSE) 
      ->set('order_success', $order_success) 
      ->set('items', $items) 
      ->set('weights', $weights) 
      ->set('ammounts', $ammounts) 
      ->set('prices', $prices) 
      ->set('total_price', $total_price) 
      ->set('validator', FALSE) 
      ; 

$template = $this->get_template(); 

echo $template->set('content', $content); 

以前的代码行是在模板视图中回显一个内容视图。这也应该是我的关机处理程序在必要时回显的结果。有没有一个很好/简单的方法来做到这一点?

回答

1

听起来像你想要的是当出现错误时显示自定义错误页面。我通常在这里做的是扩展Kohana_Kohana_Exception类(如Kohana_Exception)并覆盖public static function handler方法。

这可以让你放入一些代码来检查错误是什么(HTTP_404_Exception或其他),环境是什么(dev/production),并执行你想要的任何行为。

在我的情况下,这样的事情:

// If not production and not an HTTP exception 
if (! ($e instanceof HTTP_Exception) && Kohana::$environment !== Kohana::PRODUCTION) 
{ 
    // Use built in error handler to show stace trace for developers 
    Kohana_Kohana_Exception::handler($e); 
    // ... exit(1); 
} 

// Otherwise 
$injected_routes = array(Route::get('error')); 
echo Request::factory('error-uri', NULL, FALSE, $injected_routes) 
       ->headers(Request::$initial->headers()) 
       ->execute() 
       ->send_headers(TRUE) 
       ->body(); 

在这里,你需要一个名为匹配error-uri,去到另一个错误控制器/动作/视图,你可以用它来使您的自定义错误页error另一条路线。


对于这个工作,你需要有通过传递'errors' => TRUEKohana::init呼叫bootstrap.php启用的错误。

+0

“View_Class”背后的概念似乎是完美的 - 我把它完好无损。但是,我为此编写了一个包装器 - 另一个静态的'View_Class'方法,该方法检查错误数组是否为空。但是,如果您将Kohana框架作为一个整体来使用,这也值得一看。 – sitilge 2015-04-07 09:48:35

+0

使用Kohana进行检查。像魅力一样工作,会尝试重现/重写我自己的课程。 :) – sitilge 2015-04-07 13:07:02