仰望星辰工作室

better-staridc-MNBT

better-staridc-MNBT/ MPHX/function.php 20.8 KB · 477 行 原始文件
Z zfhsh first commit 2 天前
1<?php
2function mnbt_ip_in_cidr($ip, $cidr)
3{
4 if (strpos($cidr, '/') === false) return hash_equals($cidr, $ip);
5 list($network, $prefix) = explode('/', $cidr, 2);
6 $ipBin = @inet_pton($ip);
7 $networkBin = @inet_pton($network);
8 if ($ipBin === false || $networkBin === false || strlen($ipBin) !== strlen($networkBin)) return false;
9 $prefix = (int)$prefix;
10 $max = strlen($ipBin) * 8;
11 if ($prefix < 0 || $prefix > $max) return false;
12 $bytes = intdiv($prefix, 8);
13 $bits = $prefix % 8;
14 if ($bytes > 0 && substr($ipBin, 0, $bytes) !== substr($networkBin, 0, $bytes)) return false;
15 if ($bits === 0) return true;
16 $mask = (0xFF << (8 - $bits)) & 0xFF;
17 return (ord($ipBin[$bytes]) & $mask) === (ord($networkBin[$bytes]) & $mask);
18}
19function mnbt_request_from_trusted_proxy()
20{
21 $remote = isset($_SERVER['REMOTE_ADDR']) ? trim((string)$_SERVER['REMOTE_ADDR']) : '';
22 $trusted = getenv('MNBT_TRUSTED_PROXIES');
23 if ($remote === '' || $trusted === false || trim($trusted) === '') return false;
24 foreach (explode(',', $trusted) as $proxy) {
25 $proxy = trim($proxy);
26 if ($proxy !== '' && mnbt_ip_in_cidr($remote, $proxy)) return true;
27 }
28 return false;
29}
30function mnbt_request_is_secure()
31{
32 if (!empty($_SERVER['HTTPS']) && strtolower((string)$_SERVER['HTTPS']) !== 'off') return true;
33 if (isset($_SERVER['SERVER_PORT']) && (int)$_SERVER['SERVER_PORT'] === 443) return true;
34 if (!mnbt_request_from_trusted_proxy()) return false;
35 $proto = isset($_SERVER['HTTP_X_FORWARDED_PROTO']) ? strtolower(trim(explode(',', (string)$_SERVER['HTTP_X_FORWARDED_PROTO'])[0])) : '';
36 return $proto === 'https';
37}
38function mnbt_set_cookie($name, $value, $expires = 0, $httpOnly = true, $sameSite = 'Lax', $path = '/')
39{
40 $options = ['expires' => (int)$expires, 'path' => $path, 'secure' => mnbt_request_is_secure(), 'httponly' => (bool)$httpOnly, 'samesite' => $sameSite];
41 if (PHP_VERSION_ID >= 70300) return setcookie($name, $value, $options);
42 return setcookie($name, $value, (int)$expires, $path . '; samesite=' . $sameSite, '', $options['secure'], $options['httponly']);
43}
44function mnbt_set_auth_cookie($name, $value, $expires)
45{
46 $deleteAt = time() - 604800;
47 foreach (['/admin', '/user', '/app_plugins/user_info', '/app_plugins/user_info/lib'] as $legacyPath) mnbt_set_cookie($name, '', $deleteAt, true, 'Lax', $legacyPath);
48 return mnbt_set_cookie($name, $value, $expires, true, 'Lax', '/');
49}
50function mnbt_rotate_login_session()
51{
52 if (session_status() === PHP_SESSION_ACTIVE) session_regenerate_id(true);
53 mnbt_csrf_token(true);
54}
55function mnbt_csrf_token($rotate = false)
56{
57 if ($rotate || empty($_SESSION['mnbt_csrf_token']) || !is_string($_SESSION['mnbt_csrf_token'])) {
58 try { $_SESSION['mnbt_csrf_token'] = bin2hex(random_bytes(32)); } catch (Throwable $e) { $_SESSION['mnbt_csrf_token'] = hash('sha256', uniqid((string)mt_rand(), true) . session_id()); }
59 }
60 $token = $_SESSION['mnbt_csrf_token'];
61 if (!headers_sent() && (!isset($_COOKIE['MNBT_CSRF_TOKEN']) || !hash_equals((string)$_COOKIE['MNBT_CSRF_TOKEN'], $token))) {
62 mnbt_set_cookie('MNBT_CSRF_TOKEN', $token, 0, false, 'Lax');
63 $_COOKIE['MNBT_CSRF_TOKEN'] = $token;
64 }
65 return $token;
66}
67function mnbt_csrf_request_token()
68{
69 foreach (['HTTP_X_CSRF_TOKEN', 'HTTP_X_XSRF_TOKEN'] as $header) if (!empty($_SERVER[$header])) return (string)$_SERVER[$header];
70 foreach (['_csrf', 'csrf_token', '_token'] as $key) if (isset($_POST[$key]) && is_string($_POST[$key])) return $_POST[$key];
71 // 双提交 Cookie 兜底:页面未注入 meta 时前端可从 MNBT_CSRF_TOKEN 读取并回传
72 if (isset($_COOKIE['MNBT_CSRF_TOKEN']) && is_string($_COOKIE['MNBT_CSRF_TOKEN']) && $_COOKIE['MNBT_CSRF_TOKEN'] !== '') return $_COOKIE['MNBT_CSRF_TOKEN'];
73 return '';
74}
75function mnbt_csrf_verify($token = null)
76{
77 $expected = isset($_SESSION['mnbt_csrf_token']) && is_string($_SESSION['mnbt_csrf_token']) ? $_SESSION['mnbt_csrf_token'] : '';
78 if ($expected === '') return false;
79 $actual = $token === null ? mnbt_csrf_request_token() : (string)$token;
80 if ($actual !== '' && hash_equals($expected, $actual)) return true;
81 // header/post 携带旧 token 不匹配时,回退校验双提交 cookie,覆盖旧页面/轮换后的场景
82 if (isset($_COOKIE['MNBT_CSRF_TOKEN']) && is_string($_COOKIE['MNBT_CSRF_TOKEN']) && $_COOKIE['MNBT_CSRF_TOKEN'] !== '') {
83 return hash_equals($expected, $_COOKIE['MNBT_CSRF_TOKEN']);
84 }
85 return false;
86}
87function mnbt_csrf_is_safe_method($method = null)
88{
89 $method = strtoupper($method === null ? ($_SERVER['REQUEST_METHOD'] ?? 'GET') : (string)$method);
90 return in_array($method, ['GET', 'HEAD', 'OPTIONS'], true);
91}
92function mnbt_csrf_enabled()
93{
94 if (defined('MNBT_CSRF_ENABLED')) return (bool)MNBT_CSRF_ENABLED;
95 $env = getenv('MNBT_CSRF_ENABLED');
96 if ($env !== false && trim($env) !== '') return !in_array(strtolower(trim($env)), ['0', 'false', 'off', 'no'], true);
97 return true;
98}
99function mnbt_csrf_fail()
100{
101 $expected = isset($_SESSION['mnbt_csrf_token']) && is_string($_SESSION['mnbt_csrf_token']) ? $_SESSION['mnbt_csrf_token'] : '';
102 $provided = mnbt_csrf_request_token();
103 $source = '';
104 foreach (['HTTP_X_CSRF_TOKEN', 'HTTP_X_XSRF_TOKEN'] as $h) if (!empty($_SERVER[$h])) { $source = 'header'; break; }
105 if ($source === '') foreach (['_csrf', 'csrf_token', '_token'] as $k) if (isset($_POST[$k]) && is_string($_POST[$k])) { $source = 'post'; break; }
106 if ($source === '' && isset($_COOKIE['MNBT_CSRF_TOKEN']) && $_COOKIE['MNBT_CSRF_TOKEN'] !== '') $source = 'cookie';
107 error_log(sprintf('[MNBT CSRF] fail path=%s method=%s has_session_token=%d provided_len=%d source=%s has_cookie=%d ip=%s',
108 $_SERVER['REQUEST_URI'] ?? '', $_SERVER['REQUEST_METHOD'] ?? '', $expected !== '' ? 1 : 0,
109 strlen($provided), $source, isset($_COOKIE['MNBT_CSRF_TOKEN']) ? 1 : 0, $_SERVER['REMOTE_ADDR'] ?? ''));
110 http_response_code(419);
111 @header('Content-Type: application/json; charset=UTF-8');
112 if (function_exists('json_exit_error')) json_exit_error('CSRF 验证失败,请刷新页面后重试');
113 if (function_exists('json_exit')) json_exit('CSRF 验证失败,请刷新页面后重试');
114 exit('{"success":false,"code":"CSRF 验证失败,请刷新页面后重试","msg":"CSRF 验证失败,请刷新页面后重试","redirect":null}');
115}
116function mnbt_csrf_validate_request($exempt = false)
117{
118 if ($exempt || !mnbt_csrf_enabled() || mnbt_csrf_is_safe_method()) return true;
119 if (!mnbt_csrf_verify()) mnbt_csrf_fail();
120 return true;
121}
122function mnbt_csrf_field()
123{
124 return '<input type="hidden" name="_csrf" value="' . htmlspecialchars(mnbt_csrf_token(), ENT_QUOTES, 'UTF-8') . '">';
125}
126function mnbt_csrf_head()
127{
128 $token = htmlspecialchars(mnbt_csrf_token(), ENT_QUOTES, 'UTF-8');
129 return '<meta name="csrf-token" content="' . $token . '"><script>(function(){var m=document.querySelector(\'meta[name="csrf-token"]\'),t=m&&m.content?m.content:(function(){try{var c=document.cookie.split(\'; \'),i;for(i=0;i<c.length;i++){var q=c[i].indexOf(\'=\');if(q>-1&&c[i].slice(0,q)===\'MNBT_CSRF_TOKEN\')return decodeURIComponent(c[i].slice(q+1))}}catch(e){}return \'\'})();if(!t)return;var s=function(u){try{return new URL(u,location.href).origin===location.origin}catch(e){return false}},v=function(x){return !/^(GET|HEAD|OPTIONS)$/i.test(x||"GET")};document.addEventListener("submit",function(e){var f=e.target;if(f&&v(f.method)&&s(f.action||location.href)&&!f.querySelector(\'input[name="_csrf"]\')){var i=document.createElement("input");i.type="hidden";i.name="_csrf";i.value=t;f.appendChild(i)}},true);var o=XMLHttpRequest.prototype.open,a=XMLHttpRequest.prototype.send;XMLHttpRequest.prototype.open=function(method,url){this.__mnbtCsrf=v(method)&&s(url);return o.apply(this,arguments)};XMLHttpRequest.prototype.send=function(){if(this.__mnbtCsrf)this.setRequestHeader("X-CSRF-Token",t);return a.apply(this,arguments)};if(window.fetch){var f=window.fetch;window.fetch=function(input,init){init=init||{};var u=typeof input==="string"?input:input.url,method=init.method||(typeof input!=="string"&&input.method)||"GET";if(v(method)&&s(u)){init.headers=new Headers(init.headers||(typeof input!=="string"?input.headers:void 0));init.headers.set("X-CSRF-Token",t)}return f.call(this,input,init)}}if(window.jQuery)jQuery.ajaxPrefilter(function(options,original,xhr){if(v(options.type)&&s(options.url))xhr.setRequestHeader("X-CSRF-Token",t)})})();</script>';
130}
131function mnbt_csrf_inject_html($html)
132{
133 if (!is_string($html) || $html === '') return $html;
134 if (!preg_match('/\A\s*(?:<!doctype\s+html\b[^>]*>\s*)?<html\b[^>]*>/i', $html)) return $html;
135 if (!preg_match('/<head\b[^>]*>[\s\S]*<\/head\s*>/i', $html)) return $html;
136 if (preg_match('/<meta\b[^>]*\bname\s*=\s*(["\'])csrf-token\1/i', $html)) return $html;
137 return preg_replace('/<\/head\s*>/i', mnbt_csrf_head() . '</head>', $html, 1);
138}
139function curl_get($url)
140{
141$ch=curl_init($url);
142curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
143curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false);
144curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
145curl_setopt($ch, CURLOPT_USERAGENT, 'Mozilla/5.0 (Linux; U; Android 4.4.1; zh-cn; R815T Build/JOP40D) AppleWebKit/533.1 (KHTML, like Gecko)Version/4.0 MQQBrowser/4.5 Mobile Safari/533.1');
146curl_setopt($ch, CURLOPT_TIMEOUT, 10);
147$content=curl_exec($ch);
148curl_close($ch);
149return($content);
150}
151function daddslashes($string, $force = 0, $strip = FALSE) {
152 !defined('MAGIC_QUOTES_GPC') && define('MAGIC_QUOTES_GPC', false);
153 if(!MAGIC_QUOTES_GPC || $force) {
154 if(is_array($string)) {
155 foreach($string as $key => $val) {
156 $string[$key] = daddslashes($val, $force, $strip);
157 }
158 } else {
159 $string = addslashes($strip ? stripslashes($string) : $string);
160 }
161 }
162 return $string;
163}
164function authcode($string, $operation = 'DECODE', $key = '', $expiry = 0) {
165 $ckey_length = 4;
166 $key = md5($key ? $key : ENCRYPT_KEY);
167 $keya = md5(substr($key, 0, 16));
168 $keyb = md5(substr($key, 16, 16));
169 $keyc = $ckey_length ? ($operation == 'DECODE' ? substr($string, 0, $ckey_length): substr(md5(microtime()), -$ckey_length)) : '';
170 $cryptkey = $keya.md5($keya.$keyc);
171 $key_length = strlen($cryptkey);
172 $string = $operation == 'DECODE' ? base64_decode(substr($string, $ckey_length)) : sprintf('%010d', $expiry ? $expiry + time() : 0).substr(md5($string.$keyb), 0, 16).$string;
173 $string_length = strlen($string);
174 $result = '';
175 $box = range(0, 255);
176 $rndkey = array();
177 for($i = 0; $i <= 255; $i++) {
178 $rndkey[$i] = ord($cryptkey[$i % $key_length]);
179 }
180 for($j = $i = 0; $i < 256; $i++) {
181 $j = ($j + $box[$i] + $rndkey[$i]) % 256;
182 $tmp = $box[$i];
183 $box[$i] = $box[$j];
184 $box[$j] = $tmp;
185 }
186 for($a = $j = $i = 0; $i < $string_length; $i++) {
187 $a = ($a + 1) % 256;
188 $j = ($j + $box[$a]) % 256;
189 $tmp = $box[$a];
190 $box[$a] = $box[$j];
191 $box[$j] = $tmp;
192 $result .= chr(ord($string[$i]) ^ ($box[($box[$a] + $box[$j]) % 256]));
193 }
194 if($operation == 'DECODE') {
195 if((substr($result, 0, 10) == 0 || substr($result, 0, 10) - time() > 0) && substr($result, 10, 16) == substr(md5(substr($result, 26).$keyb), 0, 16)) {
196 return substr($result, 26);
197 } else {
198 return '';
199 }
200 } else {
201 return $keyc.str_replace('=', '', base64_encode($result));
202 }
203}
204function showmsg($content = '未知的异常',$type = 4,$back = false)
205{
206switch($type)
207{
208case 1:
209 $panel="success";
210break;
211case 2:
212 $panel="info";
213break;
214case 3:
215 $panel="warning";
216break;
217case 4:
218 $panel="danger";
219break;
220}
221
222echo '<div class="panel panel-'.$panel.'">
223 <div class="panel-heading">
224 <h3 class="panel-title">提示信息</h3>
225 </div>
226 <div class="panel-body">';
227echo $content;
228
229if ($back) {
230 echo '<hr/><a href="'.$back.'"><< 返回上一页</a>';
231}
232else
233 echo '<hr/><a href="javascript:history.back(-1)"><< 返回上一页</a>';
234
235echo '</div>
236 </div>';
237}
238function sysmsg($msg = '未知的异常',$die = true) {
239 ?>
240 <!DOCTYPE html>
241 <html xmlns="http://www.w3.org/1999/xhtml" lang="zh-CN">
242 <head>
243 <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
244 <meta name="viewport" content="width=device-width, initial-scale=1.0">
245 <title>站点提示信息</title>
246 <style type="text/css">
247html{background:#eee}body{background:#fff;color:#333;font-family:"微软雅黑","Microsoft YaHei",sans-serif;margin:2em auto;padding:1em 2em;max-width:700px;-webkit-box-shadow:10px 10px 10px rgba(0,0,0,.13);box-shadow:10px 10px 10px rgba(0,0,0,.13);opacity:.8}h1{border-bottom:1px solid #dadada;clear:both;color:#666;font:24px "微软雅黑","Microsoft YaHei",,sans-serif;margin:30px 0 0 0;padding:0;padding-bottom:7px}#error-page{margin-top:50px}h3{text-align:center}#error-page p{font-size:9px;line-height:1.5;margin:25px 0 20px}#error-page code{font-family:Consolas,Monaco,monospace}ul li{margin-bottom:10px;font-size:9px}a{color:#21759B;text-decoration:none;margin-top:-10px}a:hover{color:#D54E21}.button{background:#f7f7f7;border:1px solid #ccc;color:#555;display:inline-block;text-decoration:none;font-size:9px;line-height:26px;height:28px;margin:0;padding:0 10px 1px;cursor:pointer;-webkit-border-radius:3px;-webkit-appearance:none;border-radius:3px;white-space:nowrap;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box;-webkit-box-shadow:inset 0 1px 0 #fff,0 1px 0 rgba(0,0,0,.08);box-shadow:inset 0 1px 0 #fff,0 1px 0 rgba(0,0,0,.08);vertical-align:top}.button.button-large{height:29px;line-height:28px;padding:0 12px}.button:focus,.button:hover{background:#fafafa;border-color:#999;color:#222}.button:focus{-webkit-box-shadow:1px 1px 1px rgba(0,0,0,.2);box-shadow:1px 1px 1px rgba(0,0,0,.2)}.button:active{background:#eee;border-color:#999;color:#333;-webkit-box-shadow:inset 0 2px 5px -3px rgba(0,0,0,.5);box-shadow:inset 0 2px 5px -3px rgba(0,0,0,.5)}table{table-layout:auto;border:1px solid #333;empty-cells:show;border-collapse:collapse}th{padding:4px;border:1px solid #333;overflow:hidden;color:#333;background:#eee}td{padding:4px;border:1px solid #333;overflow:hidden;color:#333}
248 </style>
249 </head>
250 <body id="error-page">
251 <?php echo '<h3>站点提示信息</h3>';
252 echo $msg; ?>
253 </body>
254 </html>
255 <?php
256 if ($die == true) {
257 exit;
258 }
259}
260
261function logjl($czuser_hsk_v = '操作用户',$lx_hsk_v = '操作类型',$lr_hsk_v = '内容',$qk_hsk_v = '操作情况',$DBZHER = 'NULL') {
262 if (!is_object($DBZHER) || !method_exists($DBZHER, 'query_prepare')) {
263 error_log('[MNBT业务日志失败] 数据库对象无效:'.$lx_hsk_v.' '.$lr_hsk_v);
264 return '0';
265 }
266 $ip_hxer_ipsz_envc = $_SERVER["REMOTE_ADDR"] ?? 'CLI';
267 $data_time_rq_sjv = date("Y-m-d H:i:s");
268 $czuser_hsk_v = mb_substr((string)$czuser_hsk_v, 0, 250, 'UTF-8');
269 $lx_hsk_v = mb_substr((string)$lx_hsk_v, 0, 250, 'UTF-8');
270 $lr_hsk_v = mb_substr((string)$lr_hsk_v, 0, 50, 'UTF-8');
271 $qk_hsk_v = (string)$qk_hsk_v;
272 try {
273 if($DBZHER->query_prepare("INSERT INTO `MN_log` (`czuser`, `date`, `lx`, `lr`, `ip`, `qk`) VALUES (?, ?, ?, ?, ?, ?)", [$czuser_hsk_v, $data_time_rq_sjv, $lx_hsk_v, $lr_hsk_v, $ip_hxer_ipsz_envc, $qk_hsk_v])) return '1';
274 $error = method_exists($DBZHER, 'error') ? $DBZHER->error() : '未知数据库错误';
275 error_log('[MNBT业务日志失败] '.$error.' | '.$lx_hsk_v.' '.$lr_hsk_v);
276 return '0'.$error;
277 } catch (Throwable $e) {
278 error_log('[MNBT业务日志异常] '.$e->getMessage().' | '.$lx_hsk_v.' '.$lr_hsk_v);
279 return '0'.$e->getMessage();
280 }
281}
282
283function mnbt_log($user = '系统', $type = '系统日志', $content = '内容', $status = '记录', $db = null) {
284 global $DB;
285 if ($db === null && isset($DB)) $db = $DB;
286 return logjl($user, $type, $content, $status, $db);
287}
288
289function mnbt_api_compat_mode()
290{
291 global $conf;
292 // api_compat='1' 时对外主机 API 还原 1.81 老协议行为,供未升级对接模块的客户过渡使用
293 return isset($conf['api_compat']) && (string)$conf['api_compat'] === '1';
294}
295
296function send_post($url, $post_data) {
297 if(!is_array($post_data)) $post_data=[];
298 $postdata = http_build_query($post_data);
299 $options = array(
300 'http' => array(
301 'method' => 'POST',
302 'header' => 'Content-type:application/x-www-form-urlencoded',
303 'content' => $postdata,
304 'timeout' => 4// 超时时间(单位:s)
305 )
306 );
307 $context = stream_context_create($options);
308 $result = file_get_contents($url, false, $context);
309 return $result;
310}
311
312function ary_asd($mn_conf){
313 $fh_ry='"';
314 foreach($mn_conf as $sne=>$via){
315 $fh_ry_r='"';
316 if(is_array($via)){
317 $via='array('.ary_asd($via).')';
318 $fh_ry_r='';
319 }
320 if(is_numeric($via)){
321 $fh_ry_r='';
322 }
323 if($kr_sxy==""){
324 $kr_sxy.=$fh_ry.$sne.$fh_ry.'=>'.$fh_ry_r.$via.$fh_ry_r;
325 } else{
326 $kr_sxy.=','.$fh_ry.$sne.$fh_ry.'=>'.$fh_ry_r.$via.$fh_ry_r;
327 }
328 }
329 return $kr_sxy;
330}
331
332 function deldir($dir) { //删除目录下的文件
333 //先删除目录下的文件:
334 $dh = opendir($dir);
335 while ($file = readdir($dh)) {
336 if ($file != "." && $file != "..") {
337 $fullpath = $dir.
338 "/".$file;
339 if (!is_dir($fullpath)) {
340 unlink($fullpath);
341 } else {
342 deldir($fullpath);
343 }
344 }
345 }
346 closedir($dh);
347 //删除当前文件夹:
348 if (rmdir($dir)) {
349 return true;
350 } else {
351 return false;
352 }
353 }
354
355 function dirfiles($data, $type) { //控制面板返回的文件数据处理$filename如果不为false则为获取指定文件名数据
356 $userinisf=0;
357 $printarry = [];
358 foreach($data as $val) {
359 $arr = []; //为本次循环新建一个数组存放本条次数据
360 $valarr = explode(";", $val);
361 if($valarr[0]=='.user.ini' && $type=='file'){$userinisf=1; continue;} //防跨站配置文件不用显示给用户
362 $arr['name'] = $valarr[0]; //文件名
363 $arr['type'] = $type; //文件类型
364 $arr['mtime'] = $valarr[2]; //修改时间戳
365 $arr['size'] = $valarr[1]; //文件大小
366 $arr['download']=$valarr[6]; //是否外链分享
367 $printarry[] = $arr; //数组存储
368 unset($arr);
369 }
370 return ["file"=>$printarry,"couts"=>$userinisf];
371 }
372
373 function delval_array($arr,$value,$path=''){ //删除一维数组中指定的值,同时取消名称不规范的目录/文件,并且判断执行完成后是否存在文件可删
374 foreach ($arr as $k=>$v){
375 if($path.$v==$value)unset($arr[$k]); //删除指定的值的参数
376 if(strpos($v,'/'))unset($arr[$k]); //删除值不规范的参数
377 $arr = array_merge($arr);
378 }
379 if(empty($arr)){ //判断是否为空数组
380 return false;
381 }else{
382 return $arr;
383 }
384 }
385
386function zipfile($path,$zipth,$paths='/',$filetext=false) {
387 //压缩目录(被压缩的目录,此函数上一次执行的位置,压缩包存放处,程序配置文件内容)
388 $zip = new \ZipArchive;
389 $pathname=substr($path,strripos($path,'/')+1);
390 //获取目录名
391 if($zip->open($zipth, \ZIPARCHIVE::CREATE)===true) {
392 //新建一个压缩包
393 if($paths=='/') {
394 $zip->addEmptyDir($pathname);
395 //新建一个目录
396 } else {
397 $zip->addEmptyDir($pathname.$paths);
398 //新建一个目录
399 }
400 if($filetext) {
401 $zip->addFromString($pathname.$paths.'mnbt_file_conf.json', $filetext);
402 }
403 $list=scandir($path.$paths);
404 foreach ($list as $val) {
405 if($val=='.' || $val=='..')continue;
406 if(is_dir($path.$paths.$val)) {
407 //如果是目录则执行函数
408 $zip->close();
409 //关闭压缩包
410 if($paths=='/') {
411 zipfile($path,$zipth,$paths.$val.'/',false);
412 } else {
413 zipfile($path,$zipth,$paths.'/'.$val.'/',false);
414 }
415 } else {
416 //文件
417 $zip->addFile($path.$paths.$val,$pathname.$paths.$val);
418 }
419 }
420 } else return ["code"=>4,"msg"=>"错误!创建压缩包失败!"];
421 $zip->close();
422 //关闭压缩包
423 return ["code"=>1,"msg"=>"程序打包完成"];
424}
425
426function mnbt_json_encode($code, $extra = [], $success = null)
427{
428 $msg = is_scalar($code) ? (string)$code : '返回信息';
429 if ($success === null) {
430 $success = !isset($extra['qk']) || (string)$extra['qk'] !== '4';
431 }
432 if (class_exists('Response')) {
433 $result = Response::build($code, $msg, empty($extra) ? null : $extra, null, $success);
434 } else {
435 $result = [
436 'success' => (bool)$success,
437 'code' => $code,
438 'msg' => $msg,
439 'redirect' => null,
440 ];
441 if (!empty($extra)) $result['data'] = $extra;
442 }
443 foreach ($extra as $k => $v) {
444 $result[$k] = $v;
445 }
446 $json = json_encode($result, JSON_UNESCAPED_UNICODE);
447 if ($json === false) $json = '{"success":false,"code":"' . addslashes((string)$code) . '","msg":"JSON编码失败"}';
448 return $json;
449}
450
451function json_exit($code, $extra = [])
452{
453 exit(mnbt_json_encode($code, $extra));
454}
455
456function json_exit_success($msg, $extra = [])
457{
458 $extra['qk'] = 1;
459 exit(mnbt_json_encode($msg, $extra, true));
460}
461
462function json_exit_error($msg, $extra = [])
463{
464 $extra['qk'] = 4;
465 exit(mnbt_json_encode($msg, $extra, false));
466}
467
468function json_echo($code, $extra = [])
469{
470 echo mnbt_json_encode($code, $extra);
471}
472
473function json_return($code, $extra = [])
474{
475 return mnbt_json_encode($code, $extra);
476}
477?>