改名
This commit is contained in:
@@ -0,0 +1,197 @@
|
||||
<?php
|
||||
|
||||
|
||||
namespace Http\Context;
|
||||
|
||||
use Http\Abstracts\BaseContext;
|
||||
use Swoole\Coroutine;
|
||||
|
||||
/**
|
||||
* Class Context
|
||||
* @package Yoc\http
|
||||
*/
|
||||
class Context extends BaseContext
|
||||
{
|
||||
|
||||
protected static array $_contents = [];
|
||||
|
||||
|
||||
/**
|
||||
* @param $id
|
||||
* @param $context
|
||||
* @param null $coroutineId
|
||||
* @return mixed
|
||||
*/
|
||||
public static function setContext($id, $context, $coroutineId = null): mixed
|
||||
{
|
||||
if (Coroutine::getCid() === -1) {
|
||||
return static::$_contents[$id] = $context;
|
||||
}
|
||||
return Coroutine::getContext($coroutineId)[$id] = $context;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $id
|
||||
* @param int $value
|
||||
* @param null $coroutineId
|
||||
* @return bool|int
|
||||
*/
|
||||
public static function increment($id, int $value = 1, $coroutineId = null): bool|int
|
||||
{
|
||||
if (!isset(Coroutine::getContext($coroutineId)[$id])) {
|
||||
Coroutine::getContext($coroutineId)[$id] = 0;
|
||||
}
|
||||
return Coroutine::getContext($coroutineId)[$id] += $value;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $id
|
||||
* @param int $value
|
||||
* @param null $coroutineId
|
||||
* @return bool|int
|
||||
*/
|
||||
public static function decrement($id, int $value = 1, $coroutineId = null): bool|int
|
||||
{
|
||||
if (!isset(Coroutine::getContext($coroutineId)[$id])) {
|
||||
Coroutine::getContext($coroutineId)[$id] = 0;
|
||||
}
|
||||
return Coroutine::getContext($coroutineId)[$id] -= $value;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $id
|
||||
* @param null $default
|
||||
* @param null $coroutineId
|
||||
* @return mixed
|
||||
*/
|
||||
public static function getContext($id, $default = null, $coroutineId = null): mixed
|
||||
{
|
||||
if (Coroutine::getCid() === -1) {
|
||||
return static::loadByStatic($id, $default);
|
||||
}
|
||||
return static::loadByContext($id, $default, $coroutineId);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param $id
|
||||
* @param null $default
|
||||
* @param null $coroutineId
|
||||
* @return mixed
|
||||
*/
|
||||
private static function loadByContext($id, $default = null, $coroutineId = null): mixed
|
||||
{
|
||||
$data = Coroutine::getContext($coroutineId)[$id] ?? null;
|
||||
if ($data === null) {
|
||||
return $default;
|
||||
}
|
||||
return $data;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param $id
|
||||
* @param null $default
|
||||
* @return mixed
|
||||
*/
|
||||
private static function loadByStatic($id, $default = null): mixed
|
||||
{
|
||||
$data = static::$_contents[$id] ?? null;
|
||||
if ($data === null) {
|
||||
return $default;
|
||||
}
|
||||
return $data;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param null $coroutineId
|
||||
* @return mixed
|
||||
*/
|
||||
public static function getAllContext($coroutineId = null): mixed
|
||||
{
|
||||
if (Coroutine::getCid() === -1) {
|
||||
return Coroutine::getContext($coroutineId) ?? [];
|
||||
} else {
|
||||
return static::$_contents ?? [];
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $id
|
||||
* @param null $coroutineId
|
||||
*/
|
||||
public static function remove(string $id, $coroutineId = null)
|
||||
{
|
||||
if (!static::hasContext($id, $coroutineId)) {
|
||||
return;
|
||||
}
|
||||
if (Coroutine::getCid() === -1) {
|
||||
unset(static::$_contents[$id]);
|
||||
} else {
|
||||
unset(Coroutine::getContext($coroutineId)[$id]);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $id
|
||||
* @param null $key
|
||||
* @param null $coroutineId
|
||||
* @return bool
|
||||
*/
|
||||
public static function hasContext($id, $key = null, $coroutineId = null): bool
|
||||
{
|
||||
if (Coroutine::getCid() === -1) {
|
||||
return static::searchByStatic($id, $key);
|
||||
}
|
||||
return static::searchByCoroutine($id, $key, $coroutineId);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param $id
|
||||
* @param null $key
|
||||
* @return bool
|
||||
*/
|
||||
private static function searchByStatic($id, $key = null): bool
|
||||
{
|
||||
if (!isset(static::$_contents[$id])) {
|
||||
return false;
|
||||
}
|
||||
if (!empty($key) && !isset(static::$_contents[$id][$key])) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param $id
|
||||
* @param null $key
|
||||
* @param null $coroutineId
|
||||
* @return bool
|
||||
*/
|
||||
private static function searchByCoroutine($id, $key = null, $coroutineId = null): bool
|
||||
{
|
||||
if (!isset(Coroutine::getContext($coroutineId)[$id])) {
|
||||
return false;
|
||||
}
|
||||
if ($key !== null) {
|
||||
return isset((Coroutine::getContext($coroutineId)[$id] ?? [])[$key]);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @return bool
|
||||
*/
|
||||
public static function inCoroutine(): bool
|
||||
{
|
||||
return Coroutine::getCid() !== -1;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -0,0 +1,133 @@
|
||||
<?php
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Http\Context;
|
||||
|
||||
use Exception;
|
||||
use Kiri\Kiri;
|
||||
|
||||
/**
|
||||
* Class File
|
||||
*/
|
||||
class File
|
||||
{
|
||||
|
||||
public string $name = '';
|
||||
public mixed $tmp_name = '';
|
||||
public mixed $error = '';
|
||||
public mixed $type = '';
|
||||
public mixed $size = '';
|
||||
|
||||
|
||||
private string $_content = '';
|
||||
|
||||
private string $newName = '';
|
||||
private array $errorInfo = [
|
||||
0 => 'UPLOAD_ERR_OK.',
|
||||
1 => 'The uploaded file exceeds the upload_max_filesize directive in php.ini.',
|
||||
2 => 'The uploaded file exceeds the MAX_FILE_SIZE directive that was specified in the HTML form.',
|
||||
3 => 'The uploaded file was only partially uploaded.',
|
||||
4 => 'No file was uploaded.',
|
||||
6 => 'Missing a temporary folder.',
|
||||
7 => 'Failed to write file to disk.',
|
||||
8 => 'A PHP extension stopped the file upload.'
|
||||
];
|
||||
|
||||
/**
|
||||
* @param string $path
|
||||
* @return bool
|
||||
* @throws Exception
|
||||
*/
|
||||
public function saveTo(string $path): bool
|
||||
{
|
||||
if ($this->hasError()) {
|
||||
throw new Exception($this->getErrorInfo());
|
||||
}
|
||||
|
||||
@move_uploaded_file($this->tmp_name, $path);
|
||||
if (!file_exists($path)) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
* @throws Exception
|
||||
*/
|
||||
public function rename(): string
|
||||
{
|
||||
if (!empty($this->newName)) {
|
||||
return $this->newName;
|
||||
}
|
||||
|
||||
if (!file_exists($this->getTmpPath())) {
|
||||
throw new Exception('(' . $this->name . ')Failed to open stream: No such file or directory');
|
||||
}
|
||||
|
||||
return $this->name;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @return string
|
||||
* @throws Exception
|
||||
*/
|
||||
public function getContent(): string
|
||||
{
|
||||
$open = fopen($this->getTmpPath(), 'r');
|
||||
|
||||
// @move_uploaded_file($this->tmp_name, storage($this->name));
|
||||
|
||||
$limit = 1024000;
|
||||
|
||||
$stat = fstat($open);
|
||||
|
||||
$sleep = $offset = 0;
|
||||
$content = '';
|
||||
while ($file = fread($open, $limit)) {
|
||||
$content .= $file;
|
||||
fseek($open, $offset);
|
||||
if ($sleep > 0) {
|
||||
sleep($sleep);
|
||||
}
|
||||
if ($offset >= $stat['size']) {
|
||||
break;
|
||||
}
|
||||
$offset += $limit;
|
||||
}
|
||||
return $content;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getTmpPath(): string
|
||||
{
|
||||
return $this->tmp_name;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return bool
|
||||
*
|
||||
* check file have error
|
||||
*/
|
||||
public function hasError(): bool
|
||||
{
|
||||
return $this->error !== 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return mixed
|
||||
*
|
||||
* get upload error info
|
||||
*/
|
||||
public function getErrorInfo(): mixed
|
||||
{
|
||||
if (!isset($this->errorInfo[$this->error])) {
|
||||
return 'Unknown upload error.';
|
||||
}
|
||||
return $this->errorInfo[$this->error];
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,51 @@
|
||||
<?php
|
||||
|
||||
namespace Http\Context\Formatter;
|
||||
|
||||
use Exception;
|
||||
use Http\Abstracts\HttpService;
|
||||
use Http\IInterface\IFormatter;
|
||||
use Swoole\Http\Response;
|
||||
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
class FileFormatter extends HttpService implements IFormatter
|
||||
{
|
||||
|
||||
public mixed $data;
|
||||
|
||||
/** @var Response */
|
||||
public Response $status;
|
||||
|
||||
public array $header = [];
|
||||
|
||||
/**
|
||||
* @param $context
|
||||
* @return $this
|
||||
* @throws Exception
|
||||
*/
|
||||
public function send($context): static
|
||||
{
|
||||
$this->data = $context;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return mixed
|
||||
*/
|
||||
public function getData(): mixed
|
||||
{
|
||||
$data = $this->data;
|
||||
$this->clear();
|
||||
return $data;
|
||||
}
|
||||
|
||||
|
||||
public function clear(): void
|
||||
{
|
||||
$this->data = null;
|
||||
unset($this->data);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,62 @@
|
||||
<?php
|
||||
/**
|
||||
* Created by PhpStorm.
|
||||
* User: whwyy
|
||||
* Date: 2018/4/8 0008
|
||||
* Time: 17:51
|
||||
*/
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Http\Context\Formatter;
|
||||
|
||||
|
||||
use Exception;
|
||||
use Http\Abstracts\HttpService;
|
||||
use Kiri\Core\Json;
|
||||
use Swoole\Http\Response;
|
||||
use Http\IInterface\IFormatter;
|
||||
|
||||
/**
|
||||
* Class HtmlFormatter
|
||||
* @package Kiri\Kiri\Http\Formatter
|
||||
*/
|
||||
class HtmlFormatter extends HttpService implements IFormatter
|
||||
{
|
||||
|
||||
public mixed $data;
|
||||
|
||||
/** @var Response */
|
||||
public Response $status;
|
||||
|
||||
public array $header = [];
|
||||
|
||||
/**
|
||||
* @param $context
|
||||
* @return $this
|
||||
* @throws Exception
|
||||
*/
|
||||
public function send($context): static
|
||||
{
|
||||
if (!is_string($context)) {
|
||||
$context = Json::encode($context);
|
||||
}
|
||||
$this->data = $context;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return mixed
|
||||
*/
|
||||
public function getData(): mixed
|
||||
{
|
||||
$data = $this->data;
|
||||
$this->clear();
|
||||
return $data;
|
||||
}
|
||||
|
||||
public function clear(): void
|
||||
{
|
||||
$this->data = null;
|
||||
unset($this->data);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,56 @@
|
||||
<?php
|
||||
/**
|
||||
* Created by PhpStorm.
|
||||
* User: whwyy
|
||||
* Date: 2018/4/8 0008
|
||||
* Time: 17:18
|
||||
*/
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Http\Context\Formatter;
|
||||
|
||||
use Http\Abstracts\HttpService;
|
||||
use Http\IInterface\IFormatter;
|
||||
|
||||
/**
|
||||
* Class JsonFormatter
|
||||
* @package Kiri\Kiri\Http\Formatter
|
||||
*/
|
||||
class JsonFormatter extends HttpService implements IFormatter
|
||||
{
|
||||
public mixed $data;
|
||||
|
||||
public int $status = 200;
|
||||
|
||||
public array $header = [];
|
||||
|
||||
/**
|
||||
* @param $context
|
||||
* @return JsonFormatter
|
||||
*/
|
||||
public function send($context): static
|
||||
{
|
||||
if (!is_string($context)) {
|
||||
$context = json_encode($context);
|
||||
}
|
||||
$this->data = $context;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return mixed
|
||||
*/
|
||||
public function getData(): mixed
|
||||
{
|
||||
$data = $this->data;
|
||||
$this->clear();
|
||||
return $data;
|
||||
}
|
||||
|
||||
|
||||
public function clear(): void
|
||||
{
|
||||
$this->data = null;
|
||||
unset($this->data);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,90 @@
|
||||
<?php
|
||||
/**
|
||||
* Created by PhpStorm.
|
||||
* User: whwyy
|
||||
* Date: 2018/4/8 0008
|
||||
* Time: 17:29
|
||||
*/
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Http\Context\Formatter;
|
||||
|
||||
|
||||
use Exception;
|
||||
use Http\Abstracts\HttpService;
|
||||
use SimpleXMLElement;
|
||||
use Swoole\Http\Response;
|
||||
use Http\IInterface\IFormatter;
|
||||
|
||||
|
||||
/**
|
||||
* Class XmlFormatter
|
||||
* @package Kiri\Kiri\Http\Formatter
|
||||
*/
|
||||
class XmlFormatter extends HttpService implements IFormatter
|
||||
{
|
||||
|
||||
public ?string $data = '';
|
||||
|
||||
/** @var Response */
|
||||
public Response $status;
|
||||
|
||||
public array $header = [];
|
||||
|
||||
/**
|
||||
* @param $context
|
||||
* @return $this
|
||||
* @throws Exception
|
||||
*/
|
||||
public function send($context): static
|
||||
{
|
||||
if (!is_string($context)) {
|
||||
// TODO: Implement send() method.
|
||||
$dom = new SimpleXMLElement('<xml/>');
|
||||
|
||||
$this->toXml($dom, $context);
|
||||
|
||||
$this->data = $dom->saveXML();
|
||||
}
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string|null
|
||||
*/
|
||||
public function getData(): ?string
|
||||
{
|
||||
$data = $this->data;
|
||||
$this->clear();
|
||||
return $data;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param SimpleXMLElement $dom
|
||||
* @param $data
|
||||
*/
|
||||
public function toXml(SimpleXMLElement $dom, $data)
|
||||
{
|
||||
foreach ($data as $key => $val) {
|
||||
if (is_numeric($key)) {
|
||||
$key = 'item' . $key;
|
||||
}
|
||||
if (is_array($val)) {
|
||||
$node = $dom->addChild($key);
|
||||
$this->toXml($node, $val);
|
||||
} else if (is_object($val)) {
|
||||
$val = get_object_vars($val);
|
||||
$node = $dom->addChild($key);
|
||||
$this->toXml($node, $val);
|
||||
} else {
|
||||
$dom->addChild($key, htmlspecialchars((string)$val));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public function clear(): void
|
||||
{
|
||||
$this->data = null;
|
||||
unset($this->data);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,115 @@
|
||||
<?php
|
||||
/**
|
||||
* Created by PhpStorm.
|
||||
* User: admin
|
||||
* Date: 2019-03-18
|
||||
* Time: 14:54
|
||||
*/
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Http\Context;
|
||||
|
||||
/**
|
||||
* Class HttpHeaders
|
||||
* @package Kiri\Kiri\Http
|
||||
*/
|
||||
trait HttpHeaders
|
||||
{
|
||||
|
||||
private array $_headers = [];
|
||||
|
||||
|
||||
/**
|
||||
* @param array $headers
|
||||
*/
|
||||
public function setHeaders(array $headers): void
|
||||
{
|
||||
$this->_headers = $headers;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
public function toArray(): array
|
||||
{
|
||||
return $this->_headers;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $name
|
||||
* @param null $default
|
||||
* @return mixed
|
||||
*/
|
||||
public function getHeader($name, $default = null): mixed
|
||||
{
|
||||
return $this->_headers[$name] ?? $default;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param $name
|
||||
* @param $default
|
||||
* @return mixed
|
||||
*/
|
||||
public function header($name, $default = null): mixed
|
||||
{
|
||||
return $this->getHeader($name, $default);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getContentType(): string
|
||||
{
|
||||
return $this->_headers['content-type'] ?? '';
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @return string|null
|
||||
*/
|
||||
public function getRequestUri(): ?string
|
||||
{
|
||||
return $this->_headers['request_uri'];
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @return string|null
|
||||
*/
|
||||
public function getRequestMethod(): ?string
|
||||
{
|
||||
return $this->_headers['request_method'];
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @return mixed
|
||||
*/
|
||||
public function getAgent(): mixed
|
||||
{
|
||||
return $this->_headers['user-agent'];
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param $name
|
||||
* @return bool
|
||||
*/
|
||||
public function exists($name): bool
|
||||
{
|
||||
return ($this->_headers[$name] ?? null) === null;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
public function getHeaders(): array
|
||||
{
|
||||
return $this->_headers;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,388 @@
|
||||
<?php
|
||||
/**
|
||||
* Created by PhpStorm.
|
||||
* User: admin
|
||||
* Date: 2019-03-18
|
||||
* Time: 14:54
|
||||
*/
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Http\Context;
|
||||
|
||||
use Exception;
|
||||
use Http\Exception\RequestException;
|
||||
use Kiri\Core\Json;
|
||||
use Kiri\Core\Xml;
|
||||
use Kiri\Exception\NotFindClassException;
|
||||
use Kiri\Kiri;
|
||||
use ReflectionException;
|
||||
|
||||
/**
|
||||
* Class HttpParams
|
||||
* @package Kiri\Kiri\Http
|
||||
*/
|
||||
trait HttpParams
|
||||
{
|
||||
|
||||
/** @var array|null */
|
||||
private ?array $_gets = [];
|
||||
|
||||
|
||||
/** @var mixed */
|
||||
private mixed $_posts = [];
|
||||
|
||||
|
||||
/** @var array|null */
|
||||
private ?array $_files = [];
|
||||
|
||||
|
||||
private mixed $_rawContent = '';
|
||||
|
||||
/**
|
||||
* @param array|null $gets
|
||||
*/
|
||||
public function setGets(?array $gets): void
|
||||
{
|
||||
$this->_gets = $gets;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param mixed $posts
|
||||
*/
|
||||
public function setPosts(mixed $posts): void
|
||||
{
|
||||
$this->_posts = $posts;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array|null $files
|
||||
*/
|
||||
public function setFiles(?array $files): void
|
||||
{
|
||||
$this->_files = $files;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param mixed|string $rawContent
|
||||
*/
|
||||
public function setRawContent(mixed $rawContent, string $context_type): void
|
||||
{
|
||||
if (str_contains($context_type, 'json')) {
|
||||
$this->_rawContent = json_decode($rawContent, true);
|
||||
} else if (str_contains($context_type, 'xml')) {
|
||||
$this->_rawContent = Xml::toArray($rawContent);
|
||||
} else {
|
||||
$this->_rawContent = $rawContent;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @return mixed
|
||||
* @throws Exception
|
||||
*/
|
||||
public function getRawContent(): mixed
|
||||
{
|
||||
return $this->_rawContent;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @return int
|
||||
*/
|
||||
public function offset(): int
|
||||
{
|
||||
return ($this->page() - 1) * $this->size();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @return array|null
|
||||
*/
|
||||
public function getBody(): ?array
|
||||
{
|
||||
return $this->_posts;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @return int
|
||||
*/
|
||||
private function page(): int
|
||||
{
|
||||
return (int)$this->query('page', 1);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param $name
|
||||
* @param null $default
|
||||
* @return mixed
|
||||
*/
|
||||
public function query($name = null, $default = null): mixed
|
||||
{
|
||||
if (!empty($name)) {
|
||||
return $this->_gets[$name] ?? $default;
|
||||
}
|
||||
return $this->_gets;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @return int
|
||||
*/
|
||||
public function size(): int
|
||||
{
|
||||
return (int)$this->query('size', 20);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param $name
|
||||
* @param null $defaultValue
|
||||
* @return mixed
|
||||
*/
|
||||
public function post($name, $defaultValue = null): mixed
|
||||
{
|
||||
return $this->_posts[$name] ?? $defaultValue;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $name
|
||||
* @return bool|string
|
||||
* @throws Exception
|
||||
*/
|
||||
public function json($name): bool|string
|
||||
{
|
||||
$data = $this->array($name);
|
||||
if (empty($data)) {
|
||||
return Json::encode([]);
|
||||
} else if (!is_array($data)) {
|
||||
return Json::encode([]);
|
||||
}
|
||||
return Json::encode($data);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
public function gets(): array
|
||||
{
|
||||
return $this->_gets;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
public function params(): array
|
||||
{
|
||||
return array_merge($this->_gets, $this->_posts);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
public function load(): array
|
||||
{
|
||||
return array_merge($this->_files, $this->_gets, $this->_posts);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $name
|
||||
* @param array $defaultValue
|
||||
* @return mixed
|
||||
*/
|
||||
public function array($name, array $defaultValue = []): mixed
|
||||
{
|
||||
return $this->_posts[$name] = $defaultValue;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $name
|
||||
* @return File|null
|
||||
* @throws ReflectionException
|
||||
* @throws NotFindClassException
|
||||
*/
|
||||
public function file($name): File|null
|
||||
{
|
||||
$param = $this->_files[$name] ?? null;
|
||||
if (!empty($param)) {
|
||||
$param['class'] = File::class;
|
||||
return Kiri::createObject($param);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $name
|
||||
* @param bool $isNeed
|
||||
* @return mixed
|
||||
* @throws RequestException
|
||||
*/
|
||||
private function required(string $name, bool $isNeed = false): mixed
|
||||
{
|
||||
$int = $this->_posts[$name] ?? null;
|
||||
if (is_null($int) && $isNeed === true) {
|
||||
throw new RequestException("You need to add request parameter $name");
|
||||
}
|
||||
return $int;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $name
|
||||
* @param bool $isNeed
|
||||
* @param array|int|null $min
|
||||
* @param int|null $max
|
||||
* @return int|null
|
||||
* @throws RequestException
|
||||
*/
|
||||
public function int(string $name, bool $isNeed = FALSE, array|int|null $min = NULL, int|null $max = NULL): ?int
|
||||
{
|
||||
return (int)$this->required($name, $isNeed);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $name
|
||||
* @param bool $isNeed
|
||||
* @param int $round
|
||||
* @return float|null
|
||||
* @throws RequestException
|
||||
*/
|
||||
public function float(string $name, bool $isNeed = FALSE, int $round = 0): ?float
|
||||
{
|
||||
return (float)$this->required($name, $isNeed);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $name
|
||||
* @param bool $isNeed
|
||||
* @param int|array|null $length
|
||||
*
|
||||
* @return string|null
|
||||
* @throws RequestException
|
||||
*/
|
||||
public function string(string $name, bool $isNeed = FALSE, int|array|null $length = NULL): ?string
|
||||
{
|
||||
return (string)$this->required($name, $isNeed);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $name
|
||||
* @param bool $isNeed
|
||||
*
|
||||
* @return string|null
|
||||
* @throws RequestException
|
||||
*/
|
||||
public function email(string $name, bool $isNeed = FALSE): ?string
|
||||
{
|
||||
$email = $this->required($name, $isNeed);
|
||||
if ($email === null) {
|
||||
return null;
|
||||
}
|
||||
if (!preg_match('/^\w+([.-_]\w+)+@\w+(\.\w+)+$/', $email)) {
|
||||
throw new RequestException("Request parameter $name is in the wrong format", 4001);
|
||||
}
|
||||
return $email;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param string $name
|
||||
* @param bool $isNeed
|
||||
*
|
||||
* @return bool
|
||||
* @throws RequestException
|
||||
*/
|
||||
public function bool(string $name, bool $isNeed = FALSE): bool
|
||||
{
|
||||
return (boolean)$this->required($name, $isNeed);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $name
|
||||
* @param int|null $default
|
||||
*
|
||||
* @return int|string|null
|
||||
* @throws RequestException
|
||||
*/
|
||||
public function timestamp(string $name, int|null $default = NULL): null|int|string
|
||||
{
|
||||
$value = $this->required($name, false);
|
||||
if ($value === null) {
|
||||
return $default;
|
||||
}
|
||||
if (!is_numeric($value)) {
|
||||
throw new RequestException('The request param :attribute not is a timestamp value');
|
||||
}
|
||||
if (strlen((string)$value) != 10) {
|
||||
throw new RequestException('The request param :attribute not is a timestamp value');
|
||||
}
|
||||
if (!date('YmdHis', $value)) {
|
||||
throw new RequestException('The request param :attribute format error', 4001);
|
||||
}
|
||||
return $value;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $name
|
||||
* @param string|null $default
|
||||
*
|
||||
* @return string|null
|
||||
* @throws RequestException
|
||||
*/
|
||||
public function datetime(string $name, string $default = NULL): string|null
|
||||
{
|
||||
$value = $this->required($name, false);
|
||||
if ($value === null) {
|
||||
return $default;
|
||||
}
|
||||
$match = '/^\d{4}.*?([1-12]).*([1-31]).*?[0-23].*?[0-59].*?[0-59].*?$/';
|
||||
$match = preg_match($match, $value, $result);
|
||||
if (!$match || $result[0] != $value) {
|
||||
throw new RequestException('The request param :attribute format error', 4001);
|
||||
}
|
||||
return $value;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $name
|
||||
* @param string|null $default
|
||||
*
|
||||
* @return string|null
|
||||
* @throws RequestException
|
||||
*/
|
||||
public function date(string $name, string $default = NULL): string|null
|
||||
{
|
||||
$value = $this->required($name, false);
|
||||
if ($value === null) {
|
||||
return $default;
|
||||
}
|
||||
$match = '/^\d{4}.*?([1-12]).*([1-31])$/';
|
||||
$match = preg_match($match, $value, $result);
|
||||
if (!$match || $result[0] != $value) {
|
||||
throw new RequestException('The request param :attribute format error', 4001);
|
||||
}
|
||||
return $value;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param string $name
|
||||
* @param string|null $default
|
||||
* @return string|null
|
||||
* @throws RequestException
|
||||
*/
|
||||
public function ip(string $name, string $default = NULL): string|null
|
||||
{
|
||||
$value = $this->required($name, false);
|
||||
if ($value == NULL) {
|
||||
return $default;
|
||||
}
|
||||
$match = preg_match('/^\d{1,3}(\.\d{1,3}){3}$/', $value, $result);
|
||||
if (!$match || $result[0] != $value) {
|
||||
throw new RequestException('The request param :attribute format error', 4001);
|
||||
}
|
||||
return $value;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -0,0 +1,430 @@
|
||||
<?php
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Http\Context;
|
||||
|
||||
use Annotation\Inject;
|
||||
use Exception;
|
||||
use Http\Abstracts\HttpService;
|
||||
use Http\IInterface\AuthIdentity;
|
||||
use JetBrains\PhpStorm\Pure;
|
||||
use Server\RequestInterface;
|
||||
use Server\ServerManager;
|
||||
use Kiri\Core\Json;
|
||||
|
||||
defined('REQUEST_OK') or define('REQUEST_OK', 0);
|
||||
defined('REQUEST_FAIL') or define('REQUEST_FAIL', 500);
|
||||
|
||||
/**
|
||||
* Class HttpRequest
|
||||
*
|
||||
* @package Kiri\Kiri\HttpRequest
|
||||
*
|
||||
* @property-read $isPost
|
||||
* @property-read $isGet
|
||||
* @property-read $isOption
|
||||
* @property-read $isDelete
|
||||
* @property-read $isHttp
|
||||
* @property-read $method
|
||||
* @property-read $identity
|
||||
* @property-read $isPackage
|
||||
* @property-read $isReceive
|
||||
*/
|
||||
class Request extends HttpService implements RequestInterface
|
||||
{
|
||||
|
||||
|
||||
use HttpHeaders, HttpParams;
|
||||
|
||||
private array $_explode = [];
|
||||
private string $_uri = '';
|
||||
private int $fd = 0;
|
||||
|
||||
private bool $isCli = FALSE;
|
||||
|
||||
private float $startTime;
|
||||
|
||||
private int $statusCode = 200;
|
||||
|
||||
private int $_clientId = 0;
|
||||
|
||||
/** @var string[] */
|
||||
private array $explode = [];
|
||||
|
||||
const PLATFORM_MAC_OX = 'mac';
|
||||
const PLATFORM_IPHONE = 'iphone';
|
||||
const PLATFORM_ANDROID = 'android';
|
||||
const PLATFORM_WINDOWS = 'windows';
|
||||
|
||||
|
||||
private string $_platform = '';
|
||||
|
||||
|
||||
/**
|
||||
* @var AuthIdentity|null
|
||||
*/
|
||||
private ?AuthIdentity $_grant = null;
|
||||
|
||||
|
||||
/**
|
||||
* @param $id
|
||||
*/
|
||||
public function setClientId($id)
|
||||
{
|
||||
$this->_clientId = $id;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param string $request_uri
|
||||
*/
|
||||
public function setUri(string $request_uri)
|
||||
{
|
||||
$request_uri = array_filter(explode('/', $request_uri));
|
||||
|
||||
$this->_explode = $request_uri;
|
||||
$this->_uri = '/' . implode('/', $request_uri);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array|null
|
||||
* @throws Exception
|
||||
*/
|
||||
public function getConnectInfo(): array|null
|
||||
{
|
||||
$server = ServerManager::getContext()->getServer();
|
||||
|
||||
return $server->getClientInfo($this->getClientId());
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @return mixed
|
||||
*/
|
||||
public function getStartTime(): mixed
|
||||
{
|
||||
return $this->getHeader('request_time_float');
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @return int
|
||||
*/
|
||||
public function getClientId(): int
|
||||
{
|
||||
return $this->_clientId ?? 0;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @return bool
|
||||
*/
|
||||
public function isFavicon(): bool
|
||||
{
|
||||
return $this->getRequestUri() === 'favicon.ico';
|
||||
}
|
||||
|
||||
/**
|
||||
* @return AuthIdentity|null
|
||||
*/
|
||||
public function getIdentity(): ?AuthIdentity
|
||||
{
|
||||
return $this->_grant;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return bool
|
||||
*/
|
||||
public function isHead(): bool
|
||||
{
|
||||
$result = $this->getRequestMethod() == 'HEAD';
|
||||
if ($result) {
|
||||
$this->setStatus(101);
|
||||
} else {
|
||||
$this->setStatus(200);
|
||||
}
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $status
|
||||
* @return mixed
|
||||
*/
|
||||
public function setStatus($status): mixed
|
||||
{
|
||||
return $this->statusCode = $status;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return int
|
||||
*/
|
||||
public function getStatus(): int
|
||||
{
|
||||
return $this->statusCode;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return bool
|
||||
*/
|
||||
public function getIsPackage(): bool
|
||||
{
|
||||
return $this->getRequestMethod() == 'package';
|
||||
}
|
||||
|
||||
/**
|
||||
* @return bool
|
||||
*/
|
||||
public function getIsReceive(): bool
|
||||
{
|
||||
return $this->getRequestMethod() == 'receive';
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param $value
|
||||
*/
|
||||
public function setGrantAuthorization($value)
|
||||
{
|
||||
return $this->_grant = $value;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @return bool
|
||||
*/
|
||||
public function hasGrant(): bool
|
||||
{
|
||||
return $this->_grant !== null;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @return string[]
|
||||
*/
|
||||
public function getExplode(): array
|
||||
{
|
||||
return $this->_explode;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
#[Pure] public function getCurrent(): string
|
||||
{
|
||||
return current($this->explode);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getUri(): string
|
||||
{
|
||||
return $this->_uri;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string|null
|
||||
*/
|
||||
public function getPlatform(): ?string
|
||||
{
|
||||
if (!empty($this->_platform)) {
|
||||
return $this->_platform;
|
||||
}
|
||||
|
||||
$user = $this->getAgent();
|
||||
$match = preg_match('/\(.*\)?/', $user, $output);
|
||||
if (!$match || count($output) < 1) {
|
||||
return $this->_platform = 'unknown';
|
||||
}
|
||||
$output = strtolower(array_shift($output));
|
||||
if (strpos('mac', $output)) {
|
||||
return $this->_platform = 'mac';
|
||||
} else if (strpos('iphone', $output)) {
|
||||
return $this->_platform = 'iphone';
|
||||
} else if (strpos('android', $output)) {
|
||||
return $this->_platform = 'android';
|
||||
} else if (strpos('windows', $output)) {
|
||||
return $this->_platform = 'windows';
|
||||
} else {
|
||||
return $this->_platform = 'unknown';
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @return bool
|
||||
*/
|
||||
public function isIos(): bool
|
||||
{
|
||||
return $this->getPlatform() == static::PLATFORM_IPHONE;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return bool
|
||||
*/
|
||||
public function isAndroid(): bool
|
||||
{
|
||||
return $this->getPlatform() == static::PLATFORM_ANDROID;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return bool
|
||||
*/
|
||||
public function isMacOs(): bool
|
||||
{
|
||||
return $this->getPlatform() == static::PLATFORM_MAC_OX;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return bool
|
||||
*/
|
||||
public function isWindows(): bool
|
||||
{
|
||||
return $this->getPlatform() == static::PLATFORM_WINDOWS;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return bool
|
||||
*/
|
||||
public function getIsPost(): bool
|
||||
{
|
||||
return $this->getRequestMethod() == 'POST';
|
||||
}
|
||||
|
||||
/**
|
||||
* @return bool
|
||||
* @throws Exception
|
||||
*/
|
||||
public function getIsHttp(): bool
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return bool
|
||||
*/
|
||||
public function getIsOption(): bool
|
||||
{
|
||||
return $this->getRequestMethod() == 'OPTIONS';
|
||||
}
|
||||
|
||||
/**
|
||||
* @return bool
|
||||
*/
|
||||
public function getIsGet(): bool
|
||||
{
|
||||
return $this->getRequestMethod() == 'GET';
|
||||
}
|
||||
|
||||
/**
|
||||
* @return bool
|
||||
*/
|
||||
public function getIsDelete(): bool
|
||||
{
|
||||
return $this->getRequestMethod() == 'DELETE';
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*
|
||||
* 获取请求类型
|
||||
*/
|
||||
public function getMethod(): string
|
||||
{
|
||||
$method = $this->getRequestMethod();
|
||||
if (empty($method)) {
|
||||
return 'GET';
|
||||
}
|
||||
return $method;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return bool
|
||||
*/
|
||||
public function getIsCli(): bool
|
||||
{
|
||||
return $this->isCli === TRUE;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param $name
|
||||
* @param $value
|
||||
*
|
||||
* @throws Exception
|
||||
*/
|
||||
public function __set($name, $value)
|
||||
{
|
||||
$method = 'set' . ucfirst($name);
|
||||
if (method_exists($this, $method)) {
|
||||
$this->$method($value);
|
||||
} else {
|
||||
parent::__set($name, $value); // TODO: Change the autogenerated stub
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @return mixed|null
|
||||
*/
|
||||
#[Pure] public function getIp(): string|null
|
||||
{
|
||||
$headers = $this->getHeaders();
|
||||
if (!empty($headers['remoteip'])) return $headers['remoteip'];
|
||||
if (!empty($headers['x-forwarded-for'])) return $headers['x-forwarded-for'];
|
||||
if (!empty($headers['request-ip'])) return $headers['request-ip'];
|
||||
if (!empty($headers['remote_addr'])) return $headers['remote_addr'];
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
#[Pure] public function getRuntime(): string
|
||||
{
|
||||
return sprintf('%.5f', microtime(TRUE) - $this->startTime);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getDebug(): string
|
||||
{
|
||||
$mainstay = sprintf("%.6f", microtime(true)); // 带毫秒的时间戳
|
||||
|
||||
$timestamp = floatval($mainstay); // 时间戳
|
||||
$milliseconds = round(($mainstay - $timestamp) * 1000); // 毫秒
|
||||
|
||||
$datetime = date("Y-m-d H:i:s", (int)$timestamp) . '.' . $milliseconds;
|
||||
|
||||
$tmp = [
|
||||
'[Debug ' . $datetime . '] ',
|
||||
$this->getIp(),
|
||||
$this->getUri(),
|
||||
'`' . $this->getAgent() . '`',
|
||||
$this->getRuntime()
|
||||
];
|
||||
return implode(' ', $tmp);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param $router
|
||||
* @return bool
|
||||
*/
|
||||
public function is($router): bool
|
||||
{
|
||||
return $this->getRequestUri() == $router;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return bool
|
||||
*/
|
||||
public function isNotFound(): bool
|
||||
{
|
||||
return Json::to(404, 'Page ' . $this->getRequestUri() . ' not found.');
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
@@ -0,0 +1,332 @@
|
||||
<?php
|
||||
/**
|
||||
* Created by PhpStorm.
|
||||
* User: whwyy
|
||||
* Date: 2018/4/24 0024
|
||||
* Time: 19:39
|
||||
*/
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Http\Context;
|
||||
|
||||
use Exception;
|
||||
use Http\Abstracts\HttpService;
|
||||
use Http\Context\Formatter\FileFormatter;
|
||||
use Http\Context\Formatter\HtmlFormatter;
|
||||
use Http\Context\Formatter\JsonFormatter;
|
||||
use Http\Context\Formatter\XmlFormatter;
|
||||
use Http\IInterface\IFormatter;
|
||||
use Kiri\Exception\NotFindClassException;
|
||||
use Server\ResponseInterface;
|
||||
use Server\ServerManager;
|
||||
use Swoole\Http\Response as SResponse;
|
||||
|
||||
/**
|
||||
* Class Response
|
||||
* @package Kiri\Kiri\Http
|
||||
*/
|
||||
class Response extends HttpService implements ResponseInterface
|
||||
{
|
||||
|
||||
const JSON = 'json';
|
||||
const XML = 'xml';
|
||||
const HTML = 'html';
|
||||
const FILE = 'file';
|
||||
|
||||
/** @var ?string */
|
||||
private ?string $format = null;
|
||||
|
||||
/** @var int */
|
||||
public int $statusCode = 200;
|
||||
|
||||
public array $headers = [];
|
||||
public array $cookies = [];
|
||||
|
||||
private float $startTime = 0;
|
||||
|
||||
private mixed $endData;
|
||||
|
||||
private array $_clientInfo = [];
|
||||
|
||||
const FORMAT_MAPS = [
|
||||
self::JSON => JsonFormatter::class,
|
||||
self::XML => XmlFormatter::class,
|
||||
self::HTML => HtmlFormatter::class,
|
||||
self::FILE => FileFormatter::class,
|
||||
];
|
||||
|
||||
public int $fd = 0;
|
||||
private int $clientId = 0;
|
||||
private int $reactorId = 0;
|
||||
|
||||
|
||||
/**
|
||||
* @param int $int
|
||||
* @param int $reID
|
||||
*/
|
||||
public function setClientId(int $int, int $reID)
|
||||
{
|
||||
$this->clientId = $int;
|
||||
$this->reactorId = $reID;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param array $clientInfo
|
||||
*/
|
||||
public function setClientInfo(array $clientInfo)
|
||||
{
|
||||
$this->_clientInfo = $clientInfo;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @return mixed
|
||||
*/
|
||||
public function getClientInfo(): mixed
|
||||
{
|
||||
if (!empty($this->_clientInfo)) {
|
||||
return $this->_clientInfo;
|
||||
}
|
||||
$server = ServerManager::getContext()->getServer();
|
||||
return $server->getClientInfo($this->clientId, $this->reactorId);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getFormat(): string
|
||||
{
|
||||
return $this->format;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @return int
|
||||
*/
|
||||
public function getClientId(): int
|
||||
{
|
||||
return $this->clientId;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param $format
|
||||
* @return $this
|
||||
*/
|
||||
public function setFormat($format): static
|
||||
{
|
||||
if (empty($format)) {
|
||||
return $this;
|
||||
}
|
||||
$this->format = $format;
|
||||
return $this;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param $content
|
||||
* @return Response
|
||||
*/
|
||||
public function toHtml($content): static
|
||||
{
|
||||
$this->format = self::HTML;
|
||||
$this->endData = (string)$content;
|
||||
return $this;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param $content
|
||||
* @return Response
|
||||
*/
|
||||
public function toJson($content): static
|
||||
{
|
||||
$this->format = self::JSON;
|
||||
$this->endData = json_encode($content, JSON_UNESCAPED_UNICODE);
|
||||
return $this;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param $content
|
||||
* @return mixed
|
||||
*/
|
||||
public function toXml($content): static
|
||||
{
|
||||
$this->format = self::XML;
|
||||
$this->endData = $content;
|
||||
return $this;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param string $path
|
||||
* @param bool $isChunk
|
||||
* @param int $offset
|
||||
* @param int $limit
|
||||
* @return static
|
||||
* @throws Exception
|
||||
*/
|
||||
public function sendFile(string $path, bool $isChunk = false, int $offset = 0, int $limit = 10240): static
|
||||
{
|
||||
$this->format = self::FILE;
|
||||
if (!file_exists($path)) {
|
||||
throw new Exception('File `' . $path . '` not exists.');
|
||||
}
|
||||
$this->endData = ['path' => $path, 'isChunk' => $isChunk, 'limit' => $limit, 'offset' => $offset];
|
||||
return $this;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param $key
|
||||
* @param $value
|
||||
* @return Response
|
||||
*/
|
||||
public function addHeader($key, $value): static
|
||||
{
|
||||
$this->headers[$key] = $value;
|
||||
return $this;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param $name
|
||||
* @param null $value
|
||||
* @param null $expires
|
||||
* @param null $path
|
||||
* @param null $domain
|
||||
* @param null $secure
|
||||
* @param null $httponly
|
||||
* @param null $samesite
|
||||
* @param null $priority
|
||||
* @return Response
|
||||
*/
|
||||
public function addCookie($name, $value = null, $expires = null, $path = null, $domain = null, $secure = null, $httponly = null, $samesite = null, $priority = null): static
|
||||
{
|
||||
$this->cookies[] = func_get_args();
|
||||
return $this;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param $statusCode
|
||||
* @return Response
|
||||
*/
|
||||
public function setStatusCode($statusCode): static
|
||||
{
|
||||
$this->statusCode = $statusCode;
|
||||
return $this;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getResponseFormat(): string
|
||||
{
|
||||
return match ($this->format) {
|
||||
Response::HTML => 'text/html;charset=utf-8',
|
||||
Response::FILE => 'application/octet-stream',
|
||||
Response::XML => 'application/xml;charset=utf-8',
|
||||
default => 'application/json;charset=utf-8',
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param mixed $data
|
||||
* @param SResponse|null $response
|
||||
* @return Response
|
||||
* @throws Exception
|
||||
*/
|
||||
public function getBuilder(mixed $data, SResponse $response = null): ResponseInterface
|
||||
{
|
||||
if ($response != null) {
|
||||
$this->configure($response);
|
||||
}
|
||||
return $this->setContent($data);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param SResponse $response
|
||||
* @return Response
|
||||
* @throws Exception
|
||||
*/
|
||||
public function configure(SResponse $response): static
|
||||
{
|
||||
$response->setStatusCode($this->statusCode);
|
||||
$response->header('Run-Time', $this->getRuntime());
|
||||
if (!empty($this->headers)) {
|
||||
foreach ($this->headers as $name => $header) {
|
||||
$response->header($name, $header);
|
||||
}
|
||||
}
|
||||
if (!empty($this->cookies)) {
|
||||
foreach ($this->cookies as $header) {
|
||||
$response->setCookie(...$header);
|
||||
}
|
||||
}
|
||||
return $this;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param mixed $content
|
||||
* @return ResponseInterface
|
||||
*/
|
||||
public function setContent(mixed $content): ResponseInterface
|
||||
{
|
||||
$this->endData = $content;
|
||||
return $this;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @return IFormatter
|
||||
* @throws NotFindClassException
|
||||
* @throws \ReflectionException
|
||||
*/
|
||||
public function getContent(): IFormatter
|
||||
{
|
||||
$class = Response::FORMAT_MAPS[$this->format] ?? HtmlFormatter::class;
|
||||
return \di($class)->send($this->endData);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param $url
|
||||
* @param array $param
|
||||
* @return int
|
||||
*/
|
||||
public function redirect($url, array $param = []): mixed
|
||||
{
|
||||
if (!empty($param)) {
|
||||
$url .= '?' . http_build_query($param);
|
||||
}
|
||||
$url = ltrim($url, '/');
|
||||
if (!preg_match('/^http/', $url)) {
|
||||
$url = '/' . $url;
|
||||
}
|
||||
/** @var SResponse $response */
|
||||
$response = Context::getContext('response');
|
||||
if (!empty($response)) {
|
||||
return $response->redirect($url, 302);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @return string
|
||||
* @throws Exception
|
||||
*/
|
||||
public function getRuntime(): string
|
||||
{
|
||||
return sprintf('%.5f', microtime(TRUE) - request()->getStartTime());
|
||||
}
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user