<?php namespace Lib; /** * @author:dc * @time 2023/2/13 15:07 * Class App * @package Lib */ class App { /** * @var App */ public static App $instance; /** * 当前日期 * @var string */ private string $date = ''; /** * 当前时间 * @var string */ private string $dateTime = ''; /** * @var Route */ private Route $route; /** * 请求的参数 * @var array */ private array $request = []; /** * TODO:: 如果debug打开,错误时会返回错误消息到前端 * @var bool */ public bool $debug = false; /** * 输出到前端的数据 * @var mixed */ private mixed $data = []; /** * 表单文件 * @var array */ private array $uploadFile = []; /** * 错误 * @var array */ private array $error = []; /** * 前端提交过来的body内容 * @var */ private $bodyRaw = ''; /** * App constructor. */ public function __construct() { register_shutdown_function("\\Lib\\App::end"); $this->date = date('Y-m-d'); $this->dateTime = date('Y-m-d H:i:s'); // 路由 $this->route = new Route(); // 请求参数 TODO::不允许其他类型的请求参数 $this->request = my_filter($_REQUEST,['trim']); // 提交到服务器的body 内容 $this->bodyRaw = file_get_contents("php://input"); $josnBody = $this->getBodyRawJson2Array(); if($josnBody){ $this->request = array_merge($josnBody,$this->request); } // 调试 if(defined('APP_DEBUG')){ $this->debug = boolval(APP_DEBUG); } } /** * @return App * @author:dc * @time 2023/2/13 10:37 */ public static function instance(){ if(empty(static::$instance)){ static::$instance = new App(); } return static::$instance; } /** * 开始运行 * @author:dc * @time 2023/2/13 11:15 */ public static function run() { $app = self::instance(); try { // if ($_SERVER['REQUEST_METHOD'] != 'POST'){ // $app->e('need_post_request'); // } // 取到路由 控制器 $route = $app->route->get(explode('?',$_SERVER['REQUEST_URI'])[0]); if(!$route){ $app->e('route_not_found'); } list($class,$action) = $route; $controller = new $class(); $app->data = $controller->{$action}(); // end 控制器 }catch (\Throwable $exception){ if($exception instanceof Err){ if ($exception->getCode() !== 200){ $app->data = [ 'error_message' => $exception->getMessage(), 'status' => $exception->getCode() ? $exception->getCode() : 500, ]; } }else{ $app->error = [ 'message' => $exception->getMessage(), 'file' => $exception->getFile(), 'line' => $exception->getLine(), 'traceAsString' => $exception->getTraceAsString() ]; // 非 Err 错误类型 $app->data = [ 'error_message' => $app->debug ? $exception->getMessage().PHP_EOL.$exception->getTraceAsString() : __('server_error'), 'status' => $exception->getCode() ? $exception->getCode() : 500, ]; } } } /** * 请求的参数 * @param string $name * @param null $default * @param array|string|null $filter * @return array|false|float|int|mixed|null * @author:dc * @time 2023/2/17 9:37 */ public function request($name='*',$default=null,$filter = null){ $data = []; if($name === '*'){ $data = $this->request; } else if (is_string($name)){ $data = $this->request[$name]??$default; }else if(is_array($name)){ foreach ($this->request as $key=>$value){ if(in_array($key,$name)){ $data[$key] = $value; } } } if($filter){ $data = my_filter($data,$filter); } if($data !== []){ return $data; } return null; } /** * body请求内容 * @return false|string * @author:dc * @time 2024/12/17 9:57 */ public function getBodyRaw(){ return $this->bodyRaw; } /** * json 数据 body里面的 * @return mixed * @author:dc * @time 2024/12/17 9:51 */ public function getBodyRawJson2Array(){ return json_decode($this->bodyRaw,true) ? : []; } /** * 读取数组 * @param string $name * @param array $default * @param null $filter * @return array|float|int|mixed|string[] * @author:dc * @time 2024/8/6 9:36 */ public function requestArr($name='*',array $default = [], $filter = null){ $value = $this->request($name,$default, $filter); if(!is_array($value)){ $value = explode(',',(string) $value); } foreach ($value as $k=>$v){ if($v===''){ unset($value[$k]); } } if(!$value){ return $default; } return $value; } /** * 是否存在 * @param string $name * @return bool * @author:dc * @time 2023/4/15 16:43 */ public function requestHas(string $name):bool { return isset($this->request[$name]); } /** * @param string $key * @return false|UploadFile[] * @author:dc * @time 2023/3/13 15:09 */ public function file($key='file'){ if(!empty($this->uploadFile[$key])){ return $this->uploadFile[$key]; } if(empty($_FILES[$key])){ return false; } if (is_array($_FILES[$key]['error'])){ foreach ($_FILES[$key]['error'] as $k=>$e){ // 成功的才处理 if($e===0){ $this->uploadFile[$key][] = new UploadFile($_FILES[$key]['name'][$k],$_FILES[$key]['tmp_name'][$k]); } } }else if($_FILES[$key]['error']===0){ $this->uploadFile[$key][] = new UploadFile($_FILES[$key]['name'],$_FILES[$key]['tmp_name']); } return $this->uploadFile[$key]??false; } /** * @return string * @author:dc * @time 2023/2/13 11:17 */ public function nowDate():string { return $this->date; } /** * @return string * @author:dc * @time 2023/2/13 11:18 */ public function nowDateTime():string{ return $this->dateTime; } /** * 错误 * @param string|array $message * @param int $status * @throws Err * @author:dc * @time 2023/2/13 10:57 */ public function e($message,$status=400){ if(is_array($message)){ $this->data['error_message'] = __($message[0]); if(is_array($message[1])){ $this->data['error_message'] = sprintf($this->data['error_message'],...$message[1]); }else{ unset($message[0]); $this->data['error_message'] = sprintf($this->data['error_message'],...$message); } }else{ $this->data['error_message'] = __($message); } $this->data['status'] = $status; throw new Err($this->data['error_message'],$status); } /** * 成功消息 * @param $data * @param string $message * @throws Err * @author:dc * @time 2023/2/13 11:03 */ public function _json($data){ $this->data = $data; throw new Err('',200); } /** * @param $data * @param int $http_code * @author:dc * @time 2023/3/27 10:53 */ public static function echo($data, $http_code = 200){ if(php_sapi_name()=='cli'){ return $data; } http_response_code($http_code); if(is_array($data)){ @header("Content-Type:application/json;Charset=UTF-8;"); echo json_encode($data,JSON_UNESCAPED_UNICODE); }else{ @header("Content-Type:text/html;Charset=UTF-8;"); echo $data; } } public function getError(){ return $this->error; } /** * 结束 * @author:dc * @time 2023/2/13 10:54 */ public static function end() { $app = self::instance(); // 记录日志 $last_error = error_get_last(); if($last_error){ logs($last_error); if($last_error == E_ERROR){ $data['error_message'] = $last_error['message']; $data['status'] = 502; if($app->debug){ $data['debug'] = $last_error; } self::echo($data,502); return true; } } if($app->getError()){ logs($app->getError()); } self::echo($app->data); // 日志记录 Log::getInstance()->write(); // header("Content-Type:text/event-stream;Charset=UTF-8;"); // ob_flush(); // ob_clean(); } }