作者 邓超

1

1 <?php 1 <?php
2 2
3 -error_reporting(E_ERROR | E_NOTICE); 3 +error_reporting(E_ERROR | E_NOTICE | E_WARNING);
4 4
5 // 开启4个进程 5 // 开启4个进程
6 define('WORKER_NUM',10); 6 define('WORKER_NUM',10);
@@ -63,15 +63,23 @@ class Home extends Base { @@ -63,15 +63,23 @@ class Home extends Base {
63 * @time 2023/2/18 17:32 63 * @time 2023/2/18 17:32
64 */ 64 */
65 public function send_mail(){ 65 public function send_mail(){
66 - 66 + return print_r(app()->file('files'),true);
67 $email = $this->getEmail(); 67 $email = $this->getEmail();
68 68
69 $formData = Verify::checks([ 69 $formData = Verify::checks([
70 'nickname|'.__('nickname') => ['required','max'=>50], 70 'nickname|'.__('nickname') => ['required','max'=>50],
71 - 'to|'.__('to_email') => ['required','array','email'],  
72 'subject|'.__('subject') => ['required','max'=>150], 71 'subject|'.__('subject') => ['required','max'=>150],
73 'body|'.__('body_email') => ['required'], 72 'body|'.__('body_email') => ['required'],
74 - 'files|'.__('body_email') => ['required'], 73 + 'to|'.__('to_email') => ['required','array|string','email'],
  74 + 'priority|'.__('priority_email') => ['in'=>[1,3,5]],
  75 + 'files|'.__('files_email') => [
  76 + 'file'=>[
  77 + 'ext' => [],
  78 + 'size' => 1024*1024,
  79 + 'mine' => []
  80 + ]
  81 + ],
  82 + 'receipt|'.__('receipt_email') => []
75 ],[ 83 ],[
76 84
77 ]); 85 ]);
@@ -84,7 +92,9 @@ class Home extends Base { @@ -84,7 +92,9 @@ class Home extends Base {
84 $formData['to'], 92 $formData['to'],
85 $formData['subject'], 93 $formData['subject'],
86 $formData['body'], 94 $formData['body'],
87 - $formData['files']??'' 95 + $formData['files']??'',
  96 + $formData['receipt']??'',
  97 + $formData['priority']??3,
88 ); 98 );
89 99
90 if($ret[0]===true) { 100 if($ret[0]===true) {
@@ -39,6 +39,10 @@ return [ @@ -39,6 +39,10 @@ return [
39 'verify_number' => '%s必须是数字', 39 'verify_number' => '%s必须是数字',
40 'verify_reg' => '%s的规则匹配失败', 40 'verify_reg' => '%s的规则匹配失败',
41 'verify_between' => '%s必须在%s和%s之间', 41 'verify_between' => '%s必须在%s和%s之间',
  42 + 'verify_in' => '%s必须在(%s)中',
  43 + 'verify_string' => '%s必须是字符串',
  44 + 'verify_array_or_string' => '%s必须是%s数组或者字符串',
  45 + 'verify_file' => '%s必须文件',
42 46
43 47
44 48
@@ -46,6 +50,10 @@ return [ @@ -46,6 +50,10 @@ return [
46 'to_email' => '收件人', 50 'to_email' => '收件人',
47 'subject' => '邮件标题', 51 'subject' => '邮件标题',
48 'body' => '邮件内容', 52 'body' => '邮件内容',
  53 + 'priority_email' => '是否紧急',
  54 + 'body_email' => '邮件内容',
  55 + 'files_email' => '邮件附件',
  56 + 'receipt_email' => '邮件回执',
49 57
50 58
51 59
@@ -47,13 +47,30 @@ class App { @@ -47,13 +47,30 @@ class App {
47 47
48 /** 48 /**
49 * 输出到前端的数据 49 * 输出到前端的数据
  50 + * @var mixed
  51 + */
  52 + private mixed $data;
  53 +
  54 + /**
  55 + * 表单文件
  56 + * @var array
  57 + */
  58 + private array $uploadFile = [];
  59 +
  60 + /**
  61 + * 错误
50 * @var array 62 * @var array
51 */ 63 */
52 - private array $data = []; 64 + public array $error;
53 65
  66 + /**
  67 + * App constructor.
  68 + */
54 public function __construct() 69 public function __construct()
55 { 70 {
56 71
  72 + register_shutdown_function("\\Lib\\App::end");
  73 +
57 $this->date = date('Y-m-d'); 74 $this->date = date('Y-m-d');
58 $this->dateTime = date('Y-m-d H:i:s'); 75 $this->dateTime = date('Y-m-d H:i:s');
59 76
@@ -102,24 +119,24 @@ class App { @@ -102,24 +119,24 @@ class App {
102 if(!$route){ 119 if(!$route){
103 $app->e('route_not_found'); 120 $app->e('route_not_found');
104 } 121 }
  122 +
105 list($class,$action) = $route; 123 list($class,$action) = $route;
106 $controller = new $class(); 124 $controller = new $class();
107 - $data = $controller->{$action}();  
108 - if($data){  
109 - $app->data = $data;  
110 - } 125 +
  126 + $app->data = $controller->{$action}();
  127 +
111 // end 控制器 128 // end 控制器
112 129
113 130
114 }catch (\Throwable $exception){ 131 }catch (\Throwable $exception){
115 132
116 if(!($exception instanceof Err)){ 133 if(!($exception instanceof Err)){
117 - // 记录日志  
118 - $filename = LOG_PATH.'/'.$app->nowDate().'.log';  
119 - logs(  
120 - $exception->getMessage().PHP_EOL.$exception->getTraceAsString(),  
121 - $filename  
122 - ); 134 + $app->error = [
  135 + 'message' => $exception->getMessage(),
  136 + 'file' => $exception->getFile(),
  137 + 'line' => $exception->getLine(),
  138 + 'traceAsString' => $exception->getTraceAsString()
  139 + ];
123 140
124 // 非 Err 错误类型 141 // 非 Err 错误类型
125 $app->data = [ 142 $app->data = [
@@ -170,6 +187,38 @@ class App { @@ -170,6 +187,38 @@ class App {
170 187
171 188
172 /** 189 /**
  190 + * @param string $key
  191 + * @return false|UploadFile[]
  192 + * @author:dc
  193 + * @time 2023/3/13 15:09
  194 + */
  195 + public function file($key='file'){
  196 + if(!empty($this->uploadFile[$key])){
  197 + return $this->uploadFile[$key];
  198 + }
  199 + if(empty($_FILES[$key])){
  200 + return false;
  201 + }
  202 +
  203 + if (is_array($_FILES[$key]['error'])){
  204 + foreach ($_FILES[$key]['error'] as $k=>$e){
  205 + // 成功的才处理
  206 + if($e===0){
  207 + $this->uploadFile[$key][] = new UploadFile($_FILES[$key]['name'][$k],$_FILES[$key]['tmp_name'][$k]);
  208 + }
  209 + }
  210 + }else if($_FILES[$key]['error']===0){
  211 + $this->uploadFile[$key][] = new UploadFile($_FILES[$key]['name'],$_FILES[$key]['tmp_name']);
  212 + }
  213 +
  214 + return $this->uploadFile[$key]??false;
  215 +
  216 + }
  217 +
  218 +
  219 +
  220 +
  221 + /**
173 * @return string 222 * @return string
174 * @author:dc 223 * @author:dc
175 * @time 2023/2/13 11:17 224 * @time 2023/2/13 11:17
@@ -220,6 +269,20 @@ class App { @@ -220,6 +269,20 @@ class App {
220 } 269 }
221 270
222 271
  272 +
  273 + public static function echo($data, $http_code = 200){
  274 +
  275 + http_response_code($http_code);
  276 +
  277 + if(is_array($data)){
  278 + header("Content-Type:application/json;Charset=UTF-8;");
  279 + echo json_encode($data,JSON_UNESCAPED_UNICODE);
  280 + }else{
  281 + header("Content-Type:text/html;Charset=UTF-8;");
  282 + echo $data;
  283 + }
  284 + }
  285 +
223 /** 286 /**
224 * 结束 287 * 结束
225 * @author:dc 288 * @author:dc
@@ -228,6 +291,7 @@ class App { @@ -228,6 +291,7 @@ class App {
228 public static function end() 291 public static function end()
229 { 292 {
230 // 这里可以做其他事 293 // 这里可以做其他事
  294 + $app = self::instance();
231 295
232 /** 296 /**
233 * 这里写 297 * 这里写
@@ -235,14 +299,31 @@ class App { @@ -235,14 +299,31 @@ class App {
235 299
236 // end code 300 // end code
237 301
238 - header("Content-Type:application/json;Charset=UTF-8;");  
239 -// header("Content-Type:text/html;Charset=UTF-8;");  
240 -// header("Content-Type:text/event-stream;Charset=UTF-8;"); 302 + // 记录日志
  303 + $filename = LOG_PATH.'/'.$app->nowDate().'.log';
  304 + if($last_error = error_get_last()){
  305 + logs(print_r($last_error,true), $filename);
  306 +
  307 + $data['error_message'] = $last_error['message'];
  308 + $data['status'] = 502;
241 309
242 - if(self::instance()->data){  
243 - echo json_encode(self::instance()->data,JSON_UNESCAPED_UNICODE); 310 + self::echo($data,502);
  311 +
  312 + }else{
  313 + if($app->error){
  314 + logs(
  315 + is_string($app->error) ? $app->error : implode(PHP_EOL,$app->error),
  316 + $filename
  317 + );
  318 + }
  319 +
  320 + self::echo($app->data);
244 } 321 }
245 322
  323 +
  324 +
  325 +// header("Content-Type:text/event-stream;Charset=UTF-8;");
  326 +
246 // ob_flush(); 327 // ob_flush();
247 // ob_clean(); 328 // ob_clean();
248 } 329 }
  1 +<?php
  2 +
  3 +namespace Lib;
  4 +
  5 +/**
  6 + * 文件
  7 + * @author:dc
  8 + * @time 2023/3/13 14:34
  9 + * Class UploadFile
  10 + * @package Lib
  11 + */
  12 +class UploadFile
  13 +{
  14 + /**
  15 + * @var string
  16 + */
  17 + public string $name;
  18 +
  19 + /**
  20 + * @var string
  21 + */
  22 + public string $tempFile;
  23 +
  24 + /**
  25 + * @var int
  26 + */
  27 + public int $size;
  28 +
  29 + /**
  30 + * @var string
  31 + */
  32 + public string $mime;
  33 +
  34 + /**
  35 + * @var string
  36 + */
  37 + public string $ext;
  38 +
  39 + /**
  40 + * UploadFile constructor.
  41 + * @param $name
  42 + * @param $tempFile
  43 + */
  44 + public function __construct(string $name, string $tempFile)
  45 + {
  46 + parent::__construct($tempFile);
  47 +
  48 + $this->name = $name;
  49 +
  50 + $this->tempFile = $tempFile;
  51 +
  52 + // kb
  53 + $this->size = (int) (filesize($this->tempFile)/1024);
  54 + // 文件类型
  55 + $this->mime = mime_content_type($this->tempFile);
  56 +
  57 + $ext = explode('.',$name);
  58 + $this->ext = end($ext);
  59 +
  60 + }
  61 +
  62 +
  63 +
  64 +
  65 +}
@@ -115,13 +115,26 @@ class Verify { @@ -115,13 +115,26 @@ class Verify {
115 }else{ 115 }else{
116 $param = [$key[0],$av]; 116 $param = [$key[0],$av];
117 } 117 }
  118 +
  119 + // 特殊验证
  120 + switch ($ak){
  121 + case 'array|string':{
  122 + $ak = 'array_or_string';
  123 + break;
  124 + }
  125 + case 'string|array':{
  126 + $ak = "array_or_string";
  127 + break;
  128 + }
  129 + }
  130 +
118 // 验证规则,不能以下划线开始 131 // 验证规则,不能以下划线开始
119 if(str_starts_with($ak, '_') || !method_exists($verify,$ak)){ 132 if(str_starts_with($ak, '_') || !method_exists($verify,$ak)){
120 throw new Err($ak.':验证规则不存在',600); 133 throw new Err($ak.':验证规则不存在',600);
121 } 134 }
122 if(!$verify->{$ak}(...$param)){ 135 if(!$verify->{$ak}(...$param)){
123 app()->e( 136 app()->e(
124 - $verify->message[$key[0]][$ak]??['verify_'.$ak, [$verify->alias[$key[0]]??$key[0],print_r($av,true)]], 137 + $verify->message[$key[0]][$ak]??['verify_'.$ak, [$verify->alias[$key[0]]??$key[0],is_array($av) ? implode(',',$av) : $av]],
125 600 138 600
126 ); 139 );
127 } 140 }
@@ -143,6 +156,17 @@ class Verify { @@ -143,6 +156,17 @@ class Verify {
143 } 156 }
144 157
145 /** 158 /**
  159 + * 是否存在字段
  160 + * @param $key
  161 + * @return bool
  162 + * @author:dc
  163 + * @time 2023/3/13 14:16
  164 + */
  165 + private function _has($key){
  166 + return isset($this->data[$key]);
  167 + }
  168 +
  169 + /**
146 * 必须 170 * 必须
147 * @param $key 171 * @param $key
148 * @return false 172 * @return false
@@ -163,6 +187,9 @@ class Verify { @@ -163,6 +187,9 @@ class Verify {
163 * @time 2023/3/13 10:11 187 * @time 2023/3/13 10:11
164 */ 188 */
165 public function max($key,$value):bool { 189 public function max($key,$value):bool {
  190 + // 如果字段不存在,则不验证
  191 + if(!$this->_has($key)) return true;
  192 +
166 return mb_strlen($this->_get($key)) <= $value; 193 return mb_strlen($this->_get($key)) <= $value;
167 } 194 }
168 195
@@ -175,6 +202,10 @@ class Verify { @@ -175,6 +202,10 @@ class Verify {
175 * @time 2023/3/13 10:11 202 * @time 2023/3/13 10:11
176 */ 203 */
177 public function min($key,$value):bool { 204 public function min($key,$value):bool {
  205 + // 如果字段不存在,则不验证
  206 + if(!$this->_has($key)) return true;
  207 +
  208 +
178 return mb_strlen($this->_get($key)) >= $value; 209 return mb_strlen($this->_get($key)) >= $value;
179 } 210 }
180 211
@@ -187,8 +218,12 @@ class Verify { @@ -187,8 +218,12 @@ class Verify {
187 * @author:dc 218 * @author:dc
188 * @time 2023/3/13 10:11 219 * @time 2023/3/13 10:11
189 */ 220 */
190 - public function array($key,$value):bool {  
191 - return is_array($value); 221 + public function array($key):bool {
  222 + // 如果字段不存在,则不验证
  223 + if(!$this->_has($key)) return true;
  224 +
  225 +
  226 + return is_array($this->_get($key));
192 } 227 }
193 228
194 229
@@ -201,6 +236,10 @@ class Verify { @@ -201,6 +236,10 @@ class Verify {
201 * @time 2023/3/13 10:15 236 * @time 2023/3/13 10:15
202 */ 237 */
203 public function integer($key,$value):bool { 238 public function integer($key,$value):bool {
  239 + // 如果字段不存在,则不验证
  240 + if(!$this->_has($key)) return true;
  241 +
  242 +
204 return is_integer($value); 243 return is_integer($value);
205 } 244 }
206 245
@@ -214,6 +253,9 @@ class Verify { @@ -214,6 +253,9 @@ class Verify {
214 * @time 2023/3/13 10:16 253 * @time 2023/3/13 10:16
215 */ 254 */
216 public function number($key,$value):bool { 255 public function number($key,$value):bool {
  256 + // 如果字段不存在,则不验证
  257 + if(!$this->_has($key)) return true;
  258 +
217 return is_numeric($value); 259 return is_numeric($value);
218 } 260 }
219 261
@@ -227,6 +269,9 @@ class Verify { @@ -227,6 +269,9 @@ class Verify {
227 * @time 2023/3/13 10:20 269 * @time 2023/3/13 10:20
228 */ 270 */
229 public function reg($key,$value):bool { 271 public function reg($key,$value):bool {
  272 + // 如果字段不存在,则不验证
  273 + if(!$this->_has($key)) return true;
  274 +
230 return (bool) preg_match($value,$this->_get($key)); 275 return (bool) preg_match($value,$this->_get($key));
231 } 276 }
232 277
@@ -240,6 +285,9 @@ class Verify { @@ -240,6 +285,9 @@ class Verify {
240 * @time 2023/3/13 10:31 285 * @time 2023/3/13 10:31
241 */ 286 */
242 public function between($key,$value){ 287 public function between($key,$value){
  288 + // 如果字段不存在,则不验证
  289 + if(!$this->_has($key)) return true;
  290 +
243 $data = $this->_get($key); 291 $data = $this->_get($key);
244 return $data >= $value[0] && $data <= $value[1]; 292 return $data >= $value[0] && $data <= $value[1];
245 } 293 }
@@ -253,6 +301,9 @@ class Verify { @@ -253,6 +301,9 @@ class Verify {
253 * @time 2023/3/13 10:55 301 * @time 2023/3/13 10:55
254 */ 302 */
255 public function email($key){ 303 public function email($key){
  304 + // 如果字段不存在,则不验证
  305 + if(!$this->_has($key)) return true;
  306 +
256 $emails = $this->_get($key); 307 $emails = $this->_get($key);
257 if(is_array($emails)){ 308 if(is_array($emails)){
258 foreach ($emails as $email){ 309 foreach ($emails as $email){
@@ -273,6 +324,9 @@ class Verify { @@ -273,6 +324,9 @@ class Verify {
273 * @time 2023/3/13 11:06 324 * @time 2023/3/13 11:06
274 */ 325 */
275 public function mobile($key){ 326 public function mobile($key){
  327 + // 如果字段不存在,则不验证
  328 + if(!$this->_has($key)) return true;
  329 +
276 $mobiles = $this->_get($key); 330 $mobiles = $this->_get($key);
277 if(is_array($mobiles)){ 331 if(is_array($mobiles)){
278 foreach ($mobiles as $mobile){ 332 foreach ($mobiles as $mobile){
@@ -285,7 +339,57 @@ class Verify { @@ -285,7 +339,57 @@ class Verify {
285 } 339 }
286 } 340 }
287 341
  342 + /**
  343 + * 是否在数组里面
  344 + * @param $key
  345 + * @param $value
  346 + * @return bool
  347 + * @author:dc
  348 + * @time 2023/3/13 11:56
  349 + */
  350 + public function in($key,$value):bool {
  351 + // 如果字段不存在,则不验证
  352 + if(!$this->_has($key)) return true;
  353 +
  354 + return in_array($this->_get($key),$value);
  355 + }
  356 +
  357 + /**
  358 + * 是否是字符串
  359 + * @param $key
  360 + * @return bool
  361 + * @author:dc
  362 + * @time 2023/3/13 13:42
  363 + */
  364 + public function string($key):bool {
  365 + // 如果字段不存在,则不验证
  366 + if(!$this->_has($key)) return true;
288 367
  368 + return is_string($this->_get($key));
  369 + }
  370 +
  371 + /**
  372 + * 数组或者字符串
  373 + * @param $key
  374 + * @return bool
  375 + * @author:dc
  376 + * @time 2023/3/13 14:04
  377 + */
  378 + public function array_or_string($key){
  379 + return $this->array($key) || $this->string($key);
  380 + }
  381 +
  382 +
  383 + /**
  384 + * 文件
  385 + * @param $key
  386 + * @param $value
  387 + * @author:dc
  388 + * @time 2023/3/13 14:27
  389 + */
  390 + public function file($key,$value){
  391 +
  392 + }
289 393
290 394
291 } 395 }
@@ -11,7 +11,5 @@ require_once "../vendor/autoload.php"; @@ -11,7 +11,5 @@ require_once "../vendor/autoload.php";
11 \Lib\App::run(); 11 \Lib\App::run();
12 12
13 13
14 -\Lib\App::end();  
15 -  
16 14
17 15