【问题标题】:Kohana - display buffered views or custom view on shutdownKohana - 在关闭时显示缓冲视图或自定义视图
【发布时间】:2015-03-31 08:28:19
【问题描述】:

我使用Kohana View_Core 派生来表达我的观点。我想在关机时显示缓冲视图或自定义视图,例如

  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);

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

【问题讨论】:

    标签: php model-view-controller kohana


    【解决方案1】:

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

    这使您可以输入一些代码来检查错误是什么(HTTP_404_Exception 或其他)环境是什么(开发/生产)并执行您想要的任何行为。

    就我而言,是这样的:

    // 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 的路由,它与 error-uri 匹配,并转到另一个可用于呈现自定义错误页面的错误控制器/操作/视图。


    为此,您需要通过在bootstrap.php 中将'errors' => TRUE 传递给您的Kohana::init 调用来启用错误。

    【讨论】:

    • View_Class 背后的概念似乎很完美——我保持原样。但是,我为此编写了一个包装器 - 另一个静态 View_Class 方法,用于检查错误数组是否为空。但是,如果您将 Kohana 框架作为一个整体使用,这也值得一看。
    • 使用 Kohana 进行了检查。像魅力一样工作,将尝试复制/重写我自己的课程。 :)
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-09-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多