diff --git a/core/Error/Error.php b/core/Error/Error.php
deleted file mode 100644
index 6bc58dbc..00000000
--- a/core/Error/Error.php
+++ /dev/null
@@ -1,371 +0,0 @@
-' . $message . '
PHP:' . $logTrace;
- self::writeErrorLog($messageSave);
- }
- if ($show) {
- self::showError('system', "
$message", $showTrace, 0);
- }
- if ($halt) {
- exit();
- } else {
- return $message;
- }
- }
-
- /**
- * 代码执行过程回溯信息
- *
- * @static
- * @access public
- */
- public static function debugBacktrace()
- {
- $skipFunc[] = 'Error->debugBacktrace';
- $show = $log = '';
- $debugBacktrace = debug_backtrace();
- ksort($debugBacktrace);
- foreach ($debugBacktrace as $k => $error) {
- if (!isset($error['file'])) {
- // 利用反射API来获取方法/函数所在的文件和行数
- try {
- if (isset($error['class'])) {
- $reflection = new ReflectionMethod($error['class'], $error['function']);
- } else {
- $reflection = new ReflectionFunction($error['function']);
- }
- $error['file'] = $reflection->getFileName();
- $error['line'] = $reflection->getStartLine();
- } catch (Exception $e) {
- continue;
- }
- }
- $file = str_replace(SITE_PATH, '', $error['file']);
- $func = isset($error['class']) ? $error['class'] : '';
- $func .= isset($error['type']) ? $error['type'] : '';
- $func .= isset($error['function']) ? $error['function'] : '';
- if (in_array($func, $skipFunc)) {
- break;
- }
- $error['line'] = sprintf('%04d', $error['line']);
- $show .= '[Line: ' . $error['line'] . ']' . $file . '(' . $func . ')';
- $log .= !empty($log) ? ' -> ' : '';
- $log .= $file . ':' . $error['line'];
- }
- return array($show, $log);
- }
-
- /**
- * 异常处理
- *
- * @static
- * @access public
- * @param mixed $exception
- */
- public static function exceptionError($exception)
- {
- if ($exception instanceof DbException) {
- $type = 'db';
- } else {
- $type = 'system';
- }
- if ($type == 'db') {
- $errorMsg = '(' . $exception->getCode() . ') ';
- $errorMsg .= self::sqlClear($exception->getMessage(), $exception->getDbConfig());
- if ($exception->getSql()) {
- $errorMsg .= '';
- $errorMsg .= self::sqlClear($exception->getSql(), $exception->getDbConfig());
- $errorMsg .= '
';
- }
- } else {
- $errorMsg = $exception->getMessage();
- }
- $trace = $exception->getTrace();
- krsort($trace);
- $trace[] = array('file' => $exception->getFile(), 'line' => $exception->getLine(), 'function' => 'break');
- $phpMsg = array();
- foreach ($trace as $error) {
- if (!empty($error['function'])) {
- $fun = '';
- if (!empty($error['class'])) {
- $fun .= $error['class'] . $error['type'];
- }
- $fun .= $error['function'] . '(';
- if (!empty($error['args'])) {
- $mark = '';
- foreach ($error['args'] as $arg) {
- $fun .= $mark;
- if (is_array($arg)) {
- $fun .= 'Array';
- } elseif (is_bool($arg)) {
- $fun .= $arg ? 'true' : 'false';
- } elseif (is_int($arg)) {
- $fun .= (defined('SITE_DEBUG') && SITE_DEBUG) ? $arg : '%d';
- } elseif (is_float($arg)) {
- $fun .= (defined('SITE_DEBUG') && SITE_DEBUG) ? $arg : '%f';
- } else {
- $fun .= (defined('SITE_DEBUG') && SITE_DEBUG) ? '\'' . htmlspecialchars(substr(self::clear($arg), 0, 10)) . (strlen($arg) > 10 ? ' ...' : '') . '\'' : '%s';
- }
- $mark = ', ';
- }
- }
- $fun .= ')';
- $error['function'] = $fun;
- }
- if (!isset($error['line'])) {
- continue;
- }
- $phpMsg[] = array('file' => str_replace(array(SITE_PATH, '\\'), array('', '/'), $error['file']), 'line' => $error['line'], 'function' => $error['function']);
- }
- self::showError($type, $errorMsg, $phpMsg);
- exit();
- }
-
- /**
- * 记录错误日志
- *
- * @static
- * @access public
- * @param string $message
- */
- public static function writeErrorLog($message)
- {
- return false; // 暂时不写入
- $message = self::clear($message);
- $time = time();
- $file = LOG_PATH . '/' . date('Y.m.d') . '_errorlog.php';
- $hash = md5($message);
- $userId = 0;
- $ip = get_client_ip();
- $user = 'User: userId=' . intval($userId) . '; IP=' . $ip . '; RIP:' . $_SERVER['REMOTE_ADDR'];
- $uri = 'Request: ' . htmlspecialchars(self::clear($_SERVER['REQUEST_URI']));
- $message = "\t{$time}\t$message\t$hash\t$user $uri\n";
- // 判断该$message是否在时间间隔$maxtime内已记录过,有,则不用再记录了
- if (is_file($file)) {
- $fp = @fopen($file, 'rb');
- $lastlen = 50000; // 读取最后的 $lastlen 长度字节内容
- $maxtime = 60 * 10; // 时间间隔:10分钟
- $offset = filesize($file) - $lastlen;
- if ($offset > 0) {
- fseek($fp, $offset);
- }
- if ($data = fread($fp, $lastlen)) {
- $array = explode("\n", $data);
- if (is_array($array))
- foreach ($array as $key => $val) {
- $row = explode("\t", $val);
- if ($row[0] != '') {
- continue;
- }
- if ($row[3] == $hash && ($row[1] > $time - $maxtime)) {
- return;
- }
- }
- }
- }
- error_log($message, 3, $file);
- }
-
- /**
- * 清除文本部分字符
- *
- * @param string $message
- */
- public static function clear($message)
- {
- return str_replace(array("\t", "\r", "\n"), " ", $message);
- }
-
- /**
- * sql语句字符清理
- *
- * @static
- * @access public
- * @param string $message
- * @param string $dbConfig
- */
- public static function sqlClear($message, $dbConfig)
- {
- $message = self::clear($message);
- if (!(defined('SITE_DEBUG') && SITE_DEBUG)) {
- $message = str_replace($dbConfig['database'], '***', $message);
- //$message = str_replace($dbConfig['prefix'], '***', $message);
- $message = str_replace(C('DB_PREFIX'), '***', $message);
- }
- $message = htmlspecialchars($message);
- return $message;
- }
-
- /**
- * 显示错误
- *
- * @static
- * @access public
- * @param string $type 错误类型 db,system
- * @param string $errorMsg
- * @param string $phpMsg
- */
- public static function showError($type, $errorMsg, $phpMsg = ''):string
- {
- global $_G;
- ob_end_clean();
- $host = $_SERVER['HTTP_HOST'];
- $title = $type == 'db' ? 'Database' : 'System';
- return <<
-
-
- $host - $title Error
-
-
-
-
-
-
-
$title Error
-
$errorMsg
-EOT;
- if (!empty($phpMsg)) {
- echo '
';
- echo '
PHP Debug
';
- echo '
';
- if (is_array($phpMsg)) {
- echo '| No. | File | Line | Code |
';
- foreach ($phpMsg as $k => $msg) {
- $k++;
- echo '';
- echo '| ' . $k . ' | ';
- echo '' . $msg['file'] . ' | ';
- echo '' . $msg['line'] . ' | ';
- echo '' . $msg['function'] . ' | ';
- echo '
';
- }
- } else {
- echo ' |
';
- }
- echo '
';
- }
- echo <<
-
-
-EOT;
- exit();
- }
-}
-
-/**
- * DB异常类
- *
- * @author blog.snsgou.com
- */
-class DbException extends Exception
-{
- protected $sql;
- protected $dbConfig; // 当前数据库配置信息
-
- public function __construct($message, $code = 0, $sql = '', $dbConfig = array())
- {
- $this->sql = $sql;
- $this->dbConfig = $dbConfig;
- parent::__construct($message, $code);
- }
-
- public function getSql()
- {
- return $this->sql;
- }
-
- public function getDbConfig()
- {
- return $this->dbConfig;
- }
-}
-}
diff --git a/http-server/Constrict/ResponseEmitter.php b/http-server/Constrict/ResponseEmitter.php
index f4d5ed9b..80adcf54 100644
--- a/http-server/Constrict/ResponseEmitter.php
+++ b/http-server/Constrict/ResponseEmitter.php
@@ -3,9 +3,6 @@
namespace Server\Constrict;
use Annotation\Inject;
-use Exception;
-use Kiri\Exception\NotFindClassException;
-use ReflectionException;
use Psr\Http\Message\ResponseInterface;
use Server\RequestInterface;
use Swoole\Server;
@@ -18,43 +15,33 @@ class ResponseEmitter implements Emitter
{
- /**
- * @var \Server\Constrict\DownloadEmitter
- */
- #[Inject(DownloadEmitter::class)]
- public DownloadEmitter $downloadEmitter;
+ /**
+ * @var RequestInterface
+ */
+ #[Inject(RequestInterface::class)]
+ public RequestInterface $request;
- /**
- * @var \Server\RequestInterface
- */
- #[Inject(RequestInterface::class)]
- public RequestInterface $request;
-
-
- /**
- * @param \Swoole\Http\Response|\Swoole\Http2\Response $response
- * @param ResponseInterface|\Server\Message\Response $emitter
- * @throws NotFindClassException
- * @throws ReflectionException
- * @throws Exception
- */
- public function sender(mixed $response, ResponseInterface $emitter): void
- {
- if (!empty($emitter->getHeaders()) && is_array($emitter->getHeaders())) {
- foreach ($emitter->getHeaders() as $name => $values) {
- $response->header($name, implode(';', $values));
- }
- }
- if (!empty($emitter->getCookies()) && is_array($emitter->getCookies())) {
- foreach ($emitter->getCookies() as $name => $cookie) {
- $response->cookie($name, ...$cookie);
- }
- }
- $response->setStatusCode($emitter->getStatusCode());
- $response->header('Server', 'swoole');
- $response->header('Swoole-Version', swoole_version());
- $response->end($emitter->getBody());
- }
+ /**
+ * @param mixed $response
+ * @param \Server\Message\Response|ResponseInterface $emitter
+ */
+ public function sender(mixed $response, ResponseInterface|\Server\Message\Response $emitter): void
+ {
+ if (!empty($emitter->getHeaders()) && is_array($emitter->getHeaders())) {
+ foreach ($emitter->getHeaders() as $name => $values) {
+ $response->header($name, implode(';', $values));
+ }
+ }
+ if (!empty($emitter->getCookies()) && is_array($emitter->getCookies())) {
+ foreach ($emitter->getCookies() as $name => $cookie) {
+ $response->cookie($name, ...$cookie);
+ }
+ }
+ $response->setStatusCode($emitter->getStatusCode());
+ $response->header('Server', 'swoole');
+ $response->header('Swoole-Version', swoole_version());
+ $response->end($emitter->getBody());
+ }
}
diff --git a/http-server/Message/Response.php b/http-server/Message/Response.php
index 91fece63..dffa4605 100644
--- a/http-server/Message/Response.php
+++ b/http-server/Message/Response.php
@@ -4,6 +4,8 @@ namespace Server\Message;
use Exception;
use JetBrains\PhpStorm\Pure;
+use Kiri\Core\Help;
+use Kiri\ToArray;
use Psr\Http\Message\ResponseInterface;
@@ -12,26 +14,26 @@ use Psr\Http\Message\ResponseInterface;
*/
class Response implements ResponseInterface, \Server\ResponseInterface
{
- use Message;
+ use Message;
- public int $statusCode = 200;
+ public int $statusCode = 200;
- public string $reasonPhrase = '';
+ public string $reasonPhrase = '';
- const CONTENT_TYPE_JSON = 'application/json;charset=utf-8';
- const CONTENT_TYPE_HTML = 'text/html;charset=utf-8';
- const CONTENT_TYPE_STREAM = 'octet-stream';
- const CONTENT_TYPE_XML = 'application/xml;charset=utf-8';
+ const CONTENT_TYPE_JSON = 'application/json;charset=utf-8';
+ const CONTENT_TYPE_HTML = 'text/html;charset=utf-8';
+ const CONTENT_TYPE_STREAM = 'octet-stream';
+ const CONTENT_TYPE_XML = 'application/xml;charset=utf-8';
- /**
- *
- */
- #[Pure] public function __construct()
- {
- $this->stream = new Stream('');
- }
+ /**
+ *
+ */
+ #[Pure] public function __construct()
+ {
+ $this->stream = new Stream('');
+ }
/**
@@ -39,77 +41,134 @@ class Response implements ResponseInterface, \Server\ResponseInterface
* @return $this
* @throws Exception
*/
- public function withContentType(string $type): static
- {
- if (!in_array($type, [
- Response::CONTENT_TYPE_HTML, Response::CONTENT_TYPE_JSON,
- Response::CONTENT_TYPE_STREAM, Response::CONTENT_TYPE_XML
- ])) {
- throw new Exception('Wrong content type.');
- }
- return $this->withHeader('Content-Type', $type);
- }
+ public function withContentType(string $type): static
+ {
+ if (!in_array($type, [
+ Response::CONTENT_TYPE_HTML, Response::CONTENT_TYPE_JSON,
+ Response::CONTENT_TYPE_STREAM, Response::CONTENT_TYPE_XML
+ ])) {
+ throw new Exception('Wrong content type.');
+ }
+ return $this->withHeader('Content-Type', $type);
+ }
- /**
- * @return int
- */
- public function getStatusCode(): int
- {
- // TODO: Implement getStatusCode() method.
- return $this->statusCode;
- }
+ /**
+ * @return int
+ */
+ public function getStatusCode(): int
+ {
+ // TODO: Implement getStatusCode() method.
+ return $this->statusCode;
+ }
- /**
- * @param int $code
- * @param string $reasonPhrase
- * @return static
- */
- public function withStatus($code, $reasonPhrase = ''): static
- {
- $this->statusCode = $code;
- $this->reasonPhrase = $reasonPhrase;
- return $this;
- }
+ /**
+ * @param int $code
+ * @param string $reasonPhrase
+ * @return static
+ */
+ public function withStatus($code, $reasonPhrase = ''): static
+ {
+ $this->statusCode = $code;
+ $this->reasonPhrase = $reasonPhrase;
+ return $this;
+ }
- /**
- * @return string
- */
- public function getReasonPhrase(): string
- {
- // TODO: Implement getReasonPhrase() method.
- return $this->reasonPhrase;
- }
+ /**
+ * @return string
+ */
+ public function getReasonPhrase(): string
+ {
+ // TODO: Implement getReasonPhrase() method.
+ return $this->reasonPhrase;
+ }
- /**
- * @param $value
- * @return ResponseInterface
- */
- public function withAccessControlAllowHeaders($value): ResponseInterface
- {
- return $this->withHeader('Access-Control-Allow-Headers', $value);
- }
+ /**
+ * @param $value
+ * @return ResponseInterface
+ */
+ public function withAccessControlAllowHeaders($value): ResponseInterface
+ {
+ return $this->withHeader('Access-Control-Allow-Headers', $value);
+ }
- /**
- * @param $value
- * @return ResponseInterface
- */
- public function withAccessControlRequestMethod($value): ResponseInterface
- {
- return $this->withHeader('Access-Control-Request-Method', $value);
- }
+ /**
+ * @param $value
+ * @return ResponseInterface
+ */
+ public function withAccessControlRequestMethod($value): ResponseInterface
+ {
+ return $this->withHeader('Access-Control-Request-Method', $value);
+ }
- /**
- * @param $value
- * @return ResponseInterface
- */
- public function withAccessControlAllowOrigin($value): ResponseInterface
- {
- return $this->withHeader('Access-Control-Allow-Origin', $value);
- }
+ /**
+ * @param $value
+ * @return ResponseInterface
+ */
+ public function withAccessControlAllowOrigin($value): ResponseInterface
+ {
+ return $this->withHeader('Access-Control-Allow-Origin', $value);
+ }
+
+
+ /**
+ * @param $data
+ * @return ResponseInterface
+ * @throws Exception
+ */
+ public function json($data): ResponseInterface
+ {
+ return $this->withBody(static::parser($data, self::CONTENT_TYPE_JSON))
+ ->withContentType(self::CONTENT_TYPE_JSON);
+ }
+
+
+ /**
+ * @param $data
+ * @return ResponseInterface
+ * @throws Exception
+ */
+ public function html($data): ResponseInterface
+ {
+ return $this->withBody(static::parser($data, self::CONTENT_TYPE_HTML))
+ ->withContentType(self::CONTENT_TYPE_HTML);
+ }
+
+
+ /**
+ * @param $data
+ * @return ResponseInterface
+ * @throws Exception
+ */
+ public function xml($data): ResponseInterface
+ {
+ return $this->withBody(static::parser($data, self::CONTENT_TYPE_XML))
+ ->withContentType(self::CONTENT_TYPE_XML);
+ }
+
+
+ /**
+ * @param $responseData
+ * @param string $contentType
+ * @return Stream
+ * @throws Exception
+ */
+ public static function parser($responseData, $contentType = self::CONTENT_TYPE_JSON): Stream
+ {
+ if (is_object($responseData)) {
+ $responseData = $responseData instanceof ToArray ? $responseData->toArray() : get_object_vars($responseData);
+ }
+ if ($contentType == self::CONTENT_TYPE_JSON) {
+ return new Stream(json_encode($responseData));
+ }
+ if ($contentType == self::CONTENT_TYPE_XML) {
+ return new Stream(Help::toXml($responseData));
+ }
+ return new Stream((string)($responseData));
+ }
}
diff --git a/http-server/Message/Stream.php b/http-server/Message/Stream.php
index 89db7fe2..d0d05b33 100644
--- a/http-server/Message/Stream.php
+++ b/http-server/Message/Stream.php
@@ -143,7 +143,7 @@ class Stream implements StreamInterface
* @param string $string
* @return int
*/
- public function append($string): int
+ public function append(string $string): int
{
$this->body .= $string;
$this->size = strlen($this->body);
diff --git a/http-server/Service/Http.php b/http-server/Service/Http.php
index ca93bc0d..942a58ab 100644
--- a/http-server/Service/Http.php
+++ b/http-server/Service/Http.php
@@ -58,10 +58,11 @@ class Http extends \Server\Abstracts\Http implements OnClose, OnConnect
}
- /**
- * @param $responseData
- * @return \Server\ResponseInterface
- */
+ /**
+ * @param $responseData
+ * @return ResponseInterface
+ * @throws Exception
+ */
private function transferToResponse($responseData): ResponseInterface
{
$interface = $this->response->withStatus(200);