Ejemplo n.º 1
0
 /**
  * 执行sql并返回结果或结果对象
  *
  * @param string $sql
  * @param mixed $bind
  * @access public
  * @return Onion\Storage\DB\IResult
  */
 public function execute($sql, $bind = null)
 {
     if ($bind === null) {
         $bind = array();
     }
     if (!is_array($bind)) {
         $bind = array_slice(func_get_args(), 1);
     }
     try {
         $this->connect();
         $sth = $sql instanceof \PDOStatement ? $sql : $this->dbh->prepare($sql);
         if ($sth === false) {
             return false;
         }
         if (!$sth->execute($bind)) {
             return false;
         }
     } catch (\PDOException $ex) {
         $error = new StorageError($ex->getMessage(), $ex->errorInfo[1], $ex, array('sql' => (string) $sql, 'bind' => $bind, 'native_code' => $ex->errorInfo[0]));
         fire_event($this, EXECUTE_EXCEPTION_EVENT, $error);
         throw $error;
     }
     fire_event($this, EXECUTE_EVENT, array($sql, $bind));
     if (DEBUG) {
         $log = 'Execute SQL: ' . $sql;
         if ($bind) {
             $log .= ' with ' . json_encode($bind);
         }
         \Onion\logger('storage')->debug($log);
     }
     $sth->setFetchMode(\PDO::FETCH_ASSOC);
     return $sth;
 }
Ejemplo n.º 2
0
function __on_exception($exception, $terminate = true)
{
    try {
        \Onion\logger()->exception($exception, 8);
    } catch (\Exception $ex) {
    }
    $code = $exception instanceof HttpError ? $exception->getCode() : 500;
    if (PHP_SAPI == 'cli') {
        if (!$terminate) {
            return array($code, array());
        }
        echo $exception;
        die(1);
    }
    $header = $exception instanceof HttpError ? $exception->getHeader() : array(Response::httpStatus(500));
    if (DEBUG) {
        $message = strip_tags($exception->getMessage());
        if (strpos($message, "\n") !== false) {
            $lines = explode("\n", $message);
            $message = $lines[0];
        }
        $header[] = 'X-Exception-Message: ' . $message;
        $header[] = 'X-Exception-Code: ' . $exception->getCode();
        foreach (explode("\n", $exception->getTraceAsString()) as $index => $line) {
            $header[] = sprintf('X-Exception-Trace-%d: %s', $index, $line);
        }
    }
    if ($terminate && !headers_sent()) {
        foreach ($header as $h) {
            header($h);
        }
    }
    return array($code, $header);
}
Ejemplo n.º 3
0
 /**
  * 分发请求到对应的controller
  * 执行并返回结果
  *
  * @param string $url
  * @param array $params
  * @access public
  * @return mixed
  */
 public function dispatch($url, array $params = array())
 {
     if (DEBUG) {
         $logger = \Onion\logger('mvc');
     }
     $url = strtolower(rtrim($url, '/'));
     if (DEBUG) {
         $logger->info('Request url:' . req()->requestUri());
     }
     list($class, $args) = $this->match($url);
     if (DEBUG) {
         $logger->debug('Dispatch url to controller: ' . $class);
     }
     if (!$class || !class_exists($class)) {
         throw HttpError::page_not_found(array('controller' => $class));
     }
     if ($params) {
         $args = array_merge($args, $params);
     }
     fire_event($this, BEFORE_DISPATCH_EVENT, array($url, $class, $args));
     $controller = new $class();
     if (method_exists($controller, '__before_run')) {
         // 如果__before_run返回了内容,就直接完成动作
         // 可以在这里进行某些阻断操作
         // 正常的内容不应该通过这里输出
         if ($resp = call_user_func_array(array($controller, '__before_run'), $args)) {
             return $resp instanceof Response ? $resp : resp()->setBody($resp);
         }
     }
     $request = req();
     $method = $request->method();
     // head方法除了不输出数据之外,和get方法没有区别
     if ($method == 'HEAD') {
         $method = 'GET';
     }
     if (DEBUG) {
         $log = 'Call controller [' . $class . '] method [' . $method . ']';
         if ($args) {
             $log .= ' with ' . json_encode($args);
         }
         $logger->info($log);
     }
     // 执行controller动作并返回结果
     // 不检查method是否存在,用is_callable()
     // 保留__call()重载方法的方式
     if (!is_callable(array($controller, $method))) {
         throw HttpError::method_not_allowed(array('url' => $url, 'class' => $class));
     }
     $resp = call_user_func_array(array($controller, $method), $args);
     // 这里有机会对输出结果进行进一步处理
     if (method_exists($controller, '__after_run')) {
         $controller->__after_run($resp);
     }
     fire_event($this, AFTER_DISPATCH_EVENT, array($url, $class, $args, $resp));
     return $resp instanceof Response ? $resp : resp()->setBody($resp);
 }