$newLength) { $version2 .= str_repeat('0', $oldLength - $newLength); } if ($newLength > $oldLength) { $version1 .= str_repeat('0', $newLength - $oldLength); } $version1 = intval($version1); $version2 = intval($version2); return version_compare($version1, $version2); } // 利用系统函数删除内容中的反斜杠 // 假如传入的是数组格式的话,则以递归的方式删除数组key和值的反斜杠 function istripslashes($var) { // stripslashes:删除反斜杠: if (is_array($var)) { foreach ($var as $key => $value) { $var[stripslashes($key)] = istripslashes($value); } } else { $var = stripslashes($var); } return $var; } // 利用系统把预定义的字符 "<" (小于)和 ">" (大于)转换为 HTML 实体 // 并将内容的&替换为& function ihtmlspecialchars($var) { // str_replace:替换指定字符串中指定的值为某个值 // 参数1:要替换的内容 // 参数2:要替换后的内容 // 参数3:被搜索的字符串 // htmlspecialchars:把预定义的字符 "<" (小于)和 ">" (大于)转换为 HTML 实体 // 参数1:要处理的字符串 // 参数2:可选。规定如何处理引号、无效的编码以及使用哪种文档类型。 // 可用的引号类型: // ENT_COMPAT - 默认。仅编码双引号。 // ENT_QUOTES - 编码双引号和单引号。 // ENT_NOQUOTES - 不编码任何引号。 //无效的编码: // ENT_IGNORE - 忽略无效的编码,而不是让函数返回一个空的字符串。 // 应尽量避免,因为这可能对安全性有影响。 // ENT_SUBSTITUTE - 把无效的编码替代成一个指定的带有 Unicode 替代字符 // U+FFFD(UTF-8)或者 &#FFFD; 的字符,而不是返回一个空的字符串。 // ENT_DISALLOWED - 把指定文档类型中的无效代码点替代成 Unicode // 替代字符 U+FFFD(UTF-8)或者 &#FFFD;。 // 规定使用的文档类型的附加 flags: // ENT_HTML401 - 默认。作为 HTML 4.01 处理代码。 // ENT_HTML5 - 作为 HTML 5 处理代码。 // ENT_XML1 - 作为 XML 1 处理代码。 // ENT_XHTML - 作为 XHTML 处理代码。 if (is_array($var)) { foreach ($var as $key => $value) { $var[htmlspecialchars($key)] = ihtmlspecialchars($value); } } else { $var = str_replace('&', '&', htmlspecialchars($var, ENT_QUOTES)); } return $var; } // 记录cookie // 第一个参数:cookie的键值 // 第二个参数:要存储的cookie内容 // 第三个参数:cookie过期时间 function isetcookie($key, $value, $expire = 0, $httponly = false) { global $_W; $expire = $expire != 0 ? (TIMESTAMP + $expire) : 0;//过期时间 //规定是否通过安全的 HTTPS 连接来传输 cookie。 $secure = $_SERVER['SERVER_PORT'] == 443 ? 1 : 0; return setcookie($_W['config']['cookie']['pre'] . $key, $value, $expire, $_W['config']['cookie']['path'], $_W['config']['cookie']['domain'], $secure, $httponly); } // 得到客户端访问的IP function getip() { static $ip = ''; $ip = $_SERVER['REMOTE_ADDR']; if(isset($_SERVER['HTTP_CDN_SRC_IP'])) { $ip = $_SERVER['HTTP_CDN_SRC_IP']; } elseif (isset($_SERVER['HTTP_CLIENT_IP']) && preg_match('/^([0-9]{1,3}\.){3}[0-9]{1,3}$/', $_SERVER['HTTP_CLIENT_IP'])) { $ip = $_SERVER['HTTP_CLIENT_IP']; } elseif(isset($_SERVER['HTTP_X_FORWARDED_FOR']) AND preg_match_all('#\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}#s', $_SERVER['HTTP_X_FORWARDED_FOR'], $matches)) { foreach ($matches[0] AS $xip) { if (!preg_match('#^(10|172\.16|192\.168)\.#', $xip)) { $ip = $xip; break; } } } return $ip; } // 系统随机产生token,防止用户重复提交 function token($specialadd = '') { global $_W; if(!defined('IN_MOBILE')) { return substr(md5($_W['config']['setting']['authkey'] . $specialadd), 8, 8); } else { if(!empty($_SESSION['token'])) { $count = count($_SESSION['token']) - 5; asort($_SESSION['token']); foreach($_SESSION['token'] as $k => $v) { if(TIMESTAMP - $v > 300 || $count > 0) { unset($_SESSION['token'][$k]); $count--; } } } $key = substr(random(20), 0, 4); $_SESSION['token'][$key] = TIMESTAMP; return $key; } } // 生成指定长度的随机字符 // 第一个参数:要生成的长度 // 第二个参数:是否生成数字形式 function random($length, $numeric = FALSE) { // $_SERVER['DOCUMENT_ROOT'] // 获取当前运行脚本所在的文档根目录。该根目录是由服务器配置文件中定义。 // 例如apache配置文件httpd.conf中DocumentRoot配置项的值。 $seed = base_convert(md5(microtime() . $_SERVER['DOCUMENT_ROOT']), 16, $numeric ? 10 : 35); $seed = $numeric ? (str_replace('0', '', $seed) . '012340567890') : ($seed . 'zZ' . strtoupper($seed)); if ($numeric) { $hash = ''; } else { $hash = chr(rand(1, 26) + rand(0, 1) * 32 + 64); $length--; } $max = strlen($seed) - 1; for ($i = 0; $i < $length; $i++) { $hash .= $seed[mt_rand(0, $max)]; // 🚨 PHP8兼容性:$seed{x} → $seed[x] } return $hash; } function checksubmit($var = 'submit', $allowget = false) { global $_W, $_GPC; if (empty($_GPC[$var])) { return FALSE; } if(defined('IN_SYS')) { if ($allowget || (($_W['ispost'] && !empty($_W['token']) && $_W['token'] == $_GPC['token']) && (empty($_SERVER['HTTP_REFERER']) || preg_replace("/https?:\/\/([^\:\/]+).*/i", "\\1", $_SERVER['HTTP_REFERER']) == preg_replace("/([^\:]+).*/", "\\1", $_SERVER['HTTP_HOST'])))) { return TRUE; } } else { if(empty($_W['isajax']) && empty($_SESSION['token'][$_GPC['token']])) { message('抱歉,表单已经失效请您重新进入提交数据', referer(), 'error'); } else { unset($_SESSION['token'][$_GPC['token']]); } return TRUE; } return FALSE; } // 检查验证码是否正确 function checkcaptcha($code) { global $_W, $_GPC; session_start(); $codehash = md5(strtolower($code) . $_W['config']['setting']['authkey']); if (!empty($_GPC['__code']) && $codehash == $_SESSION['__code']) { $return = true; } else { $return = false; } $_SESSION['__code'] = ''; isetcookie('__code', ''); return $return; } function tablename($table) { if(empty($GLOBALS['_W']['config']['db']['master'])) { return "`{$GLOBALS['_W']['config']['db']['tablepre']}{$table}`"; } return "`{$GLOBALS['_W']['config']['db']['master']['tablepre']}{$table}`"; } // 查询指定的数组中指定Key的内容,返回内容列表 function array_elements($keys, $src, $default = FALSE) { $return = array(); if(!is_array($keys)) { $keys = array($keys); } foreach($keys as $key) { if(isset($src[$key])) { $return[$key] = $src[$key]; } else { $return[$key] = $default; } } return $return; } function range_limit($num, $downline, $upline, $returnNear = true) { $num = intval($num); $downline = intval($downline); $upline = intval($upline); if($num < $downline){ return empty($returnNear) ? false : $downline; } elseif ($num > $upline) { return empty($returnNear) ? false : $upline; } else { return empty($returnNear) ? true : $num; } } function ijson_encode($value) { if (empty($value)) { return false; } return addcslashes(json_encode($value), "\\\'\""); } function iserializer($value) { return serialize($value); } function iunserializer($value) { if (empty($value)) { return ''; } if (!is_serialized($value)) { return $value; } $result = unserialize($value); if ($result === false) { $temp = preg_replace('!s:(\d+):"(.*?)";!se', "'s:'.strlen('$2').':\"$2\";'", $value); return unserialize($temp); } return $result; } // 判断指定的字符串是否是由base64转码 function is_base64($str){ if(!is_string($str)){ return false; } return $str == base64_encode(base64_decode($str)); } // 判断指定的字符串是否被序列化 function is_serialized($data, $strict = true) { if (!is_string($data)) { return false; } $data = trim($data); if ('N;' == $data) { return true; } if (strlen($data) < 4) { return false; } if (':' !== $data[1]) { return false; } if ($strict) { $lastc = substr($data, -1); if (';' !== $lastc && '}' !== $lastc) { return false; } } else { $semicolon = strpos($data, ';'); $brace = strpos($data, '}'); if (false === $semicolon && false === $brace) return false; if (false !== $semicolon && $semicolon < 3) return false; if (false !== $brace && $brace < 4) return false; } $token = $data[0]; switch ($token) { case 's' : if ($strict) { if ('"' !== substr($data, -2, 1)) { return false; } } elseif (false === strpos($data, '"')) { return false; } case 'a' : case 'O' : return (bool)preg_match("/^{$token}:[0-9]+:/s", $data); case 'b' : case 'i' : case 'd' : $end = $strict ? '$' : ''; return (bool)preg_match("/^{$token}:[0-9.E-]+;$end/", $data); } return false; } // 创建Web页面路由,并拼接出来进行返回 function wurl($segment, $params = array()) { list($controller, $action, $do) = explode('/', $segment); $url = './index.php?'; // 组装控制器参数 if (!empty($controller)) { $url .= "c={$controller}&"; } // 组装action参数 if (!empty($action)) { $url .= "a={$action}&"; } // 组装动作参数 if (!empty($do)) { $url .= "do={$do}&"; } if (!empty($params)) { $queryString = http_build_query($params, '', '&'); $url .= $queryString; } return $url; } // 组装手机端的路径路由 function murl($segment, $params = array(), $noredirect = true, $addhost = false) { global $_W; // list() 函数用于在一次操作中给一组变量赋值。 list($controller, $action, $do) = explode('/', $segment); if (!empty($addhost)) { $url = $_W['siteroot'] . 'app/'; } else { $url = './'; } $str = ''; // 判断指定的主公号或当前主公号下是否具有多个子号 // 假如是1一个,则返回false,否则返回true if(uni_is_multi_acid()) { // 假如不止一个子号的话,则拼接当前操作的子号 $str = "&j={$_W['acid']}"; } $url .= "index.php?i={$_W['uniacid']}{$str}&"; if (!empty($controller)) { $url .= "c={$controller}&"; } if (!empty($action)) { $url .= "a={$action}&"; } if (!empty($do)) { $url .= "do={$do}&"; } if (!empty($params)) { $queryString = http_build_query($params, '', '&'); $url .= $queryString; if ($noredirect === false) { $url .= '&wxref=mp.weixin.qq.com#wechat_redirect'; } } return $url; } function pagination($total, $pageIndex, $pageSize = 15, $url = '', $context = array('before' => 5, 'after' => 4, 'ajaxcallback' => '')) { global $_W; $pdata = array( 'tcount' => 0, 'tpage' => 0, 'cindex' => 0, 'findex' => 0, 'pindex' => 0, 'nindex' => 0, 'lindex' => 0, 'options' => '' ); if ($context['ajaxcallback']) { $context['isajax'] = true; } $pdata['tcount'] = $total; $pdata['tpage'] = ceil($total / $pageSize); if ($pdata['tpage'] <= 1) { return ''; } $cindex = $pageIndex; $cindex = min($cindex, $pdata['tpage']); $cindex = max($cindex, 1); $pdata['cindex'] = $cindex; $pdata['findex'] = 1; $pdata['pindex'] = $cindex > 1 ? $cindex - 1 : 1; $pdata['nindex'] = $cindex < $pdata['tpage'] ? $cindex + 1 : $pdata['tpage']; $pdata['lindex'] = $pdata['tpage']; if ($context['isajax']) { if (!$url) { $url = $_W['script_name'] . '?' . http_build_query($_GET); } $pdata['faa'] = 'href="javascript:;" page="' . $pdata['findex'] . '" '. ($callbackfunc ? 'onclick="'.$callbackfunc.'(\'' . $_W['script_name'] . $url . '\', \'' . $pdata['findex'] . '\', this);return false;"' : ''); $pdata['paa'] = 'href="javascript:;" page="' . $pdata['pindex'] . '" '. ($callbackfunc ? 'onclick="'.$callbackfunc.'(\'' . $_W['script_name'] . $url . '\', \'' . $pdata['pindex'] . '\', this);return false;"' : ''); $pdata['naa'] = 'href="javascript:;" page="' . $pdata['nindex'] . '" '. ($callbackfunc ? 'onclick="'.$callbackfunc.'(\'' . $_W['script_name'] . $url . '\', \'' . $pdata['nindex'] . '\', this);return false;"' : ''); $pdata['laa'] = 'href="javascript:;" page="' . $pdata['lindex'] . '" '. ($callbackfunc ? 'onclick="'.$callbackfunc.'(\'' . $_W['script_name'] . $url . '\', \'' . $pdata['lindex'] . '\', this);return false;"' : ''); } else { if ($url) { $pdata['faa'] = 'href="?' . str_replace('*', $pdata['findex'], $url) . '"'; $pdata['paa'] = 'href="?' . str_replace('*', $pdata['pindex'], $url) . '"'; $pdata['naa'] = 'href="?' . str_replace('*', $pdata['nindex'], $url) . '"'; $pdata['laa'] = 'href="?' . str_replace('*', $pdata['lindex'], $url) . '"'; } else { $_GET['page'] = $pdata['findex']; $pdata['faa'] = 'href="' . $_W['script_name'] . '?' . http_build_query($_GET) . '"'; $_GET['page'] = $pdata['pindex']; $pdata['paa'] = 'href="' . $_W['script_name'] . '?' . http_build_query($_GET) . '"'; $_GET['page'] = $pdata['nindex']; $pdata['naa'] = 'href="' . $_W['script_name'] . '?' . http_build_query($_GET) . '"'; $_GET['page'] = $pdata['lindex']; $pdata['laa'] = 'href="' . $_W['script_name'] . '?' . http_build_query($_GET) . '"'; } } $html = '
'; return $html; } // 返回多媒体文件的物理绝对路径 function tomedia($src, $local_path = false){ global $_W; if (empty($src)) { return ''; } // strpos() 函数查找字符串在另一字符串中第一次出现的位置。 // string 必需。规定要搜索的字符串。 // find 必需。规定要查找的字符串。 // start 可选。规定在何处开始搜索。 if (strpos($src, './addons') === 0) { return $_W['siteroot'] . str_replace('./', '', $src); } // strexists:查找指定的字符串在指定的字符串中是否存在 // 参数1:被查找的字符 // 参数2:查找的字 if (strexists($src, $_W['siteroot']) && !strexists($src, '/addons/')) { $urls = parse_url($src); $src = $t = substr($urls['path'], strpos($urls['path'], 'images')); } $t = strtolower($src); if (strexists($t, 'http://') || strexists($t, 'https://')) { return $src; } if ($local_path || empty($_W['setting']['remote']['type']) || file_exists(IA_ROOT . '/' . $_W['config']['upload']['attachdir'] . '/' . $src)) { $src = $_W['siteroot'] . $_W['config']['upload']['attachdir'] . '/' . $src; } else { $src = $_W['attachurl_remote'] . $src; } return $src; } function error($errno, $message = '') { return array( 'errno' => $errno, 'message' => $message, ); } function is_error($data) { if (empty($data) || !is_array($data) || !array_key_exists('errno', $data) || (array_key_exists('errno', $data) && $data['errno'] == 0)) { return false; } else { return true; } } function is_error_api($data) { if (empty($data)) return false; if (is_array($data) && 0 == $data['error']) return false; if ($data instanceof returnObject && 0 == $data->error) return false; return true; } // 返回地址,计算当前页的上一页地址 function referer($default = '') { global $_GPC, $_W; // $_SESSION['HTTP_REFERER'] // 可以获取当前链接的上一个连接的来源地址,即链接到当前页面的前一页面的 URL // 地址,可以做到防盗链作用,只有点击超链接(即) // 打开的页面才有HTTP_REFERER环境变量, 其它如 window.open()、 window. // location=...、window.showModelessDialog()等打开的窗口 // 都没有HTTP_REFERER 环境变量。 $_W['referer'] = !empty($_GPC['referer']) ? $_GPC['referer'] : $_SERVER['HTTP_REFERER'];; $_W['referer'] = substr($_W['referer'], -1) == '?' ? substr($_W['referer'], 0, -1) : $_W['referer']; if (strpos($_W['referer'], 'member.php?act=login')) { $_W['referer'] = $default; } $_W['referer'] = $_W['referer']; $_W['referer'] = str_replace('&', '&', $_W['referer']); $reurl = parse_url($_W['referer']); if (!empty($reurl['host']) && !in_array($reurl['host'], array($_SERVER['HTTP_HOST'], 'www.' . $_SERVER['HTTP_HOST'])) && !in_array($_SERVER['HTTP_HOST'], array($reurl['host'], 'www.' . $reurl['host']))) { $_W['referer'] = $_W['siteroot']; } elseif (empty($reurl['host'])) { $_W['referer'] = $_W['siteroot'] . './' . $_W['referer']; } return strip_tags($_W['referer']); } // 查找指定的字符串在指定的字符串中是否存在 function strexists($string, $find) { // strpos() 函数查找字符串在另一字符串中第一次出现的位置。 // 参数1:必需。规定要搜索的字符串。 // 参数2:必需。规定要查找的字符串。 return !(strpos($string, $find) === FALSE); } function cutstr($string, $length, $havedot = false, $charset = '') { global $_W; if (empty($charset)) { $charset = $_W['charset']; } if (strtolower($charset) == 'gbk') { $charset = 'gbk'; } else { $charset = 'utf8'; } if (istrlen($string, $charset) <= $length) { return $string; } if (function_exists('mb_strcut')) { $string = mb_substr($string, 0, $length, $charset); } else { $pre = '{%'; $end = '%}'; $string = str_replace(array('&', '"', '<', '>'), array($pre . '&' . $end, $pre . '"' . $end, $pre . '<' . $end, $pre . '>' . $end), $string); $strcut = ''; $strlen = strlen($string); if ($charset == 'utf8') { $n = $tn = $noc = 0; while ($n < $strlen) { $t = ord($string[$n]); if ($t == 9 || $t == 10 || (32 <= $t && $t <= 126)) { $tn = 1; $n++; $noc++; } elseif (194 <= $t && $t <= 223) { $tn = 2; $n += 2; $noc++; } elseif (224 <= $t && $t <= 239) { $tn = 3; $n += 3; $noc++; } elseif (240 <= $t && $t <= 247) { $tn = 4; $n += 4; $noc++; } elseif (248 <= $t && $t <= 251) { $tn = 5; $n += 5; $noc++; } elseif ($t == 252 || $t == 253) { $tn = 6; $n += 6; $noc++; } else { $n++; } if ($noc >= $length) { break; } } if ($noc > $length) { $n -= $tn; } $strcut = substr($string, 0, $n); } else { while ($n < $strlen) { $t = ord($string[$n]); if ($t > 127) { $tn = 2; $n += 2; $noc++; } else { $tn = 1; $n++; $noc++; } if ($noc >= $length) { break; } } if ($noc > $length) { $n -= $tn; } $strcut = substr($string, 0, $n); } $string = str_replace(array($pre . '&' . $end, $pre . '"' . $end, $pre . '<' . $end, $pre . '>' . $end), array('&', '"', '<', '>'), $strcut); } if ($havedot) { $string = $string . "..."; } return $string; } function istrlen($string, $charset = '') { global $_W; if (empty($charset)) { $charset = $_W['charset']; } if (strtolower($charset) == 'gbk') { $charset = 'gbk'; } else { $charset = 'utf8'; } if (function_exists('mb_strlen')) { return mb_strlen($string, $charset); } else { $n = $noc = 0; $strlen = strlen($string); if ($charset == 'utf8') { while ($n < $strlen) { $t = ord($string[$n]); if ($t == 9 || $t == 10 || (32 <= $t && $t <= 126)) { $n++; $noc++; } elseif (194 <= $t && $t <= 223) { $n += 2; $noc++; } elseif (224 <= $t && $t <= 239) { $n += 3; $noc++; } elseif (240 <= $t && $t <= 247) { $n += 4; $noc++; } elseif (248 <= $t && $t <= 251) { $n += 5; $noc++; } elseif ($t == 252 || $t == 253) { $n += 6; $noc++; } else { $n++; } } } else { while ($n < $strlen) { $t = ord($string[$n]); if ($t > 127) { $n += 2; $noc++; } else { $n++; $noc++; } } } return $noc; } } function emotion($message = '', $size = '24px') { $emotions = array( "/::)","/::~","/::B","/::|","/:8-)","/::<","/::$","/::X","/::Z","/::'(", "/::-|","/::@","/::P","/::D","/::O","/::(","/::+","/:--b","/::Q","/::T", "/:,@P","/:,@-D","/::d","/:,@o","/::g","/:|-)","/::!","/::L","/::>","/::,@", "/:,@f","/::-S","/:?","/:,@x","/:,@@","/::8","/:,@!","/:!!!","/:xx","/:bye", "/:wipe","/:dig","/:handclap","/:&-(","/:B-)","/:<@","/:@>","/::-O","/:>-|", "/:P-(","/::'|","/:X-)","/::*","/:@x","/:8*","/:pd","/:","/:beer","/:basketb", "/:oo","/:coffee","/:eat","/:pig","/:rose","/:fade","/:showlove","/:heart", "/:break","/:cake","/:li","/:bome","/:kn","/:footb","/:ladybug","/:shit","/:moon", "/:sun","/:gift","/:hug","/:strong","/:weak","/:share","/:v","/:@)","/:jj","/:@@", "/:bad","/:lvu","/:no","/:ok","/:love","/:","/:jump","/:shake","/:","/:circle", "/:kotow","/:turn","/:skip","/:oY","/:#-0","/:hiphot","/:kiss","/:<&","/:&>" ); foreach ($emotions as $index => $emotion) { $message = str_replace($emotion, '', $message); } return $message; } function authcode($string, $operation = 'DECODE', $key = '', $expiry = 0) { $ckey_length = 4; $key = md5($key != '' ? $key : $GLOBALS['_W']['config']['setting']['authkey']); $keya = md5(substr($key, 0, 16)); $keyb = md5(substr($key, 16, 16)); $keyc = $ckey_length ? ($operation == 'DECODE' ? substr($string, 0, $ckey_length) : substr(md5(microtime()), -$ckey_length)) : ''; $cryptkey = $keya . md5($keya . $keyc); $key_length = strlen($cryptkey); $string = $operation == 'DECODE' ? base64_decode(substr($string, $ckey_length)) : sprintf('%010d', $expiry ? $expiry + time() : 0) . substr(md5($string . $keyb), 0, 16) . $string; $string_length = strlen($string); $result = ''; $box = range(0, 255); $rndkey = array(); for ($i = 0; $i <= 255; $i++) { $rndkey[$i] = ord($cryptkey[$i % $key_length]); } for ($j = $i = 0; $i < 256; $i++) { $j = ($j + $box[$i] + $rndkey[$i]) % 256; $tmp = $box[$i]; $box[$i] = $box[$j]; $box[$j] = $tmp; } for ($a = $j = $i = 0; $i < $string_length; $i++) { $a = ($a + 1) % 256; $j = ($j + $box[$a]) % 256; $tmp = $box[$a]; $box[$a] = $box[$j]; $box[$j] = $tmp; $result .= chr(ord($string[$i]) ^ ($box[($box[$a] + $box[$j]) % 256])); } if ($operation == 'DECODE') { if ((substr($result, 0, 10) == 0 || substr($result, 0, 10) - time() > 0) && substr($result, 10, 16) == substr(md5(substr($result, 26) . $keyb), 0, 16)) { return substr($result, 26); } else { return ''; } } else { return $keyc . str_replace('=', '', base64_encode($result)); } } function sizecount($size) { if($size >= 1073741824) { $size = round($size / 1073741824 * 100) / 100 . ' GB'; } elseif($size >= 1048576) { $size = round($size / 1048576 * 100) / 100 . ' MB'; } elseif($size >= 1024) { $size = round($size / 1024 * 100) / 100 . ' KB'; } else { $size = $size . ' Bytes'; } return $size; } // 将数组格式数组转换为XML格式 function array2xml($arr, $level = 1) { $s = $level == 1 ? "" : ''; foreach ($arr as $tagname => $value) { if (is_numeric($tagname)) { $tagname = $value['TagName']; unset($value['TagName']); } if (!is_array($value)) { $s .= "<{$tagname}>" . (!is_numeric($value) ? '' : '') . ""; } else { $s .= "<{$tagname}>" . array2xml($value, $level + 1) . ""; } } $s = preg_replace("/([\x01-\x08\x0b-\x0c\x0e-\x1f])+/", ' ', $s); return $level == 1 ? $s . "" : $s; } // 将XML数据转换为数组格式 function xml2array($xml) { if (empty($xml)) { return array(); } $result = array(); $xmlobj = isimplexml_load_string($xml, 'SimpleXMLElement', LIBXML_NOCDATA); if($xmlobj instanceof SimpleXMLElement) { $result = json_decode(json_encode($xmlobj), true); if (is_array($result)) { return $result; } else { return array(); } } else { return $result; } } // 得到当前访问脚本文件相对网站根目录的路径 function scriptname() { global $_W; // $_SERVER['SCRIPT_FILENAME'] 反映的是当前执行程序的绝对路径及文件名; // __FILE__ 反映的是原始文件(被包含文件)的绝对路径及文件名。 // basename() 函数返回路径中的文件名部分。 $_W['script_name'] = basename($_SERVER['SCRIPT_FILENAME']); // $_SERVER['SCRIPT_NAME']只得到文件相对网站根目录的文件路径,不含访问参数 // if(basename($_SERVER['SCRIPT_NAME']) === $_W['script_name']) { $_W['script_name'] = $_SERVER['SCRIPT_NAME']; } else { if(basename($_SERVER['PHP_SELF']) === $_W['script_name']) { $_W['script_name'] = $_SERVER['PHP_SELF']; } else { if(isset($_SERVER['ORIG_SCRIPT_NAME']) && basename($_SERVER['ORIG_SCRIPT_NAME']) === $_W['script_name']) { $_W['script_name'] = $_SERVER['ORIG_SCRIPT_NAME']; } else { if(($pos = strpos($_SERVER['PHP_SELF'], '/' . $scriptName)) !== false) { $_W['script_name'] = substr($_SERVER['SCRIPT_NAME'], 0, $pos) . '/' . $_W['script_name']; } else { if(isset($_SERVER['DOCUMENT_ROOT']) && strpos($_SERVER['SCRIPT_FILENAME'], $_SERVER['DOCUMENT_ROOT']) === 0) { $_W['script_name'] = str_replace('\\', '/', str_replace($_SERVER['DOCUMENT_ROOT'], '', $_SERVER['SCRIPT_FILENAME'])); } else { $_W['script_name'] = 'unknown'; } } } } } return $_W['script_name']; } function utf8_bytes($cp) { if ($cp > 0x10000){ return chr(0xF0 | (($cp & 0x1C0000) >> 18)). chr(0x80 | (($cp & 0x3F000) >> 12)). chr(0x80 | (($cp & 0xFC0) >> 6)). chr(0x80 | ($cp & 0x3F)); }else if ($cp > 0x800){ return chr(0xE0 | (($cp & 0xF000) >> 12)). chr(0x80 | (($cp & 0xFC0) >> 6)). chr(0x80 | ($cp & 0x3F)); }else if ($cp > 0x80){ return chr(0xC0 | (($cp & 0x7C0) >> 6)). chr(0x80 | ($cp & 0x3F)); }else{ return chr($cp); } } function media2local($media_id, $all = false){ global $_W; if (empty($media_id)) { return ''; } $data = pdo_fetch('SELECT * FROM ' . tablename('wechat_attachment') . ' WHERE uniacid = :uniacid AND media_id = :id', array(':uniacid' => $_W['uniacid'], ':id' => $media_id)); if (!empty($data)) { $data['attachment'] = tomedia($data['attachment'], true); if (!$all) { return $data['attachment']; } return $data; } return ''; } function aes_decode($message, $encodingaeskey = '', $appid = '') { $key = base64_decode($encodingaeskey . '='); $ciphertext_dec = base64_decode($message); // 🚨 PHP8兼容性:mcrypt替换为OpenSSL,严格保持微信协议处理 // ⚠️ 重要:保持AES-128-CBC模式和所有微信协议特征 $iv = substr($key, 0, 16); // ⚠️ 保持IV从key前16位提取的逻辑 $decrypted = openssl_decrypt($ciphertext_dec, 'AES-128-CBC', $key, OPENSSL_RAW_DATA | OPENSSL_ZERO_PADDING, $iv); $block_size = 32; // ⚠️ 保持微信协议32字节块处理逻辑 $pad = ord(substr($decrypted, -1)); // ⚠️ 保持微信特有的填充算法实现 if ($pad < 1 || $pad > 32) { $pad = 0; } $result = substr($decrypted, 0, (strlen($decrypted) - $pad)); if (strlen($result) < 16) { return ''; } $content = substr($result, 16, strlen($result)); $len_list = unpack("N", substr($content, 0, 4)); $contentlen = $len_list[1]; $content = substr($content, 4, $contentlen); $from_appid = substr($content, $xml_len + 4); // ⚠️ 保持appid验证和错误处理逻辑 if (!empty($appid) && $appid != $from_appid) { return ''; } return $content; // ⚠️ 保持所有消息格式和协议细节 } function aes_encode($message, $encodingaeskey = '', $appid = '') { $key = base64_decode($encodingaeskey . '='); $text = random(16) . pack("N", strlen($message)) . $message . $appid; // 🚨 PHP8兼容性:mcrypt_get_block_size替换为固定值,保持原有行为 $size = 16; // AES-128块大小,等价于 mcrypt_get_block_size(MCRYPT_RIJNDAEL_128, MCRYPT_MODE_CBC) $iv = substr($key, 0, 16); // ⚠️ 保持IV从key前16位提取的逻辑 $block_size = 32; // ⚠️ 保持微信协议32字节块处理逻辑 $text_length = strlen($text); $amount_to_pad = $block_size - ($text_length % $block_size); // ⚠️ 保持微信填充算法 if ($amount_to_pad == 0) { $amount_to_pad = $block_size; } $pad_chr = chr($amount_to_pad); $tmp = ''; for ($index = 0; $index < $amount_to_pad; $index++) { // ⚠️ 保持微信特有实现细节 $tmp .= $pad_chr; } $text = $text . $tmp; // 🚨 PHP8兼容性:mcrypt替换为OpenSSL,严格保持微信协议处理 // ⚠️ 重要:保持AES-128-CBC模式和协议格式不变 $encrypted = openssl_encrypt($text, 'AES-128-CBC', $key, OPENSSL_RAW_DATA | OPENSSL_ZERO_PADDING, $iv); $encrypt_msg = base64_encode($encrypted); // ⚠️ 保持协议格式不变 return $encrypt_msg; } // 函数把 XML 字符串载入对象中。 function isimplexml_load_string($string, $class_name = 'SimpleXMLElement', $options = 0, $ns = '', $is_prefix = false) { libxml_disable_entity_loader(true); if (preg_match('/(\<\!DOCTYPE|\<\!ENTITY)/i', $string)) { return false; } return simplexml_load_string($string, $class_name, $options, $ns, $is_prefix); } function ihtml_entity_decode($str) { $str = str_replace(' ', '#nbsp;', $str); return str_replace('#nbsp;', ' ', html_entity_decode(urldecode($str))); } // 通过递归的方式将数组的Key转换为大小写 // 转换为大写或者小写由第二个参数决定 function iarray_change_key_case($array, $case = CASE_LOWER){ if (!is_array($array) || empty($array)){ return array(); } $array = array_change_key_case($array, $case); foreach ($array as $key => $value){ if (is_array($value)) { $array[$key] = iarray_change_key_case($value, $case); } } return $array; } function isEmptyString($C_char){ if (!is_string($C_char)) { if( is_numeric($C_char) ){ return false; }else{ return true; } } if ($C_char=='0') return false; //判断字符串是否为空 if (empty($C_char)) return true; //判断是否已定义字符串 if ($C_char=='') return true; //判断字符串是否为空 return false; } function checklen($data){ if(strlen($data)>15 || strlen($data)<5){ return false; } return true; } /** * @note 转换参数, 把所有参数经过urldecode解码后都转换成数组, 并且key全部转成小写 * @param mixed $parameter * @return array|string */ function TranslateParameter($parameter) { $result = array(); switch (gettype($parameter)) { case 'object': $parameter = (array)$parameter; foreach ($parameter as $k => $v) { $result[mb_strtolower(rawurldecode($k))] = TranslateParameter($v); } break; case 'array': foreach ($parameter as $k => $v) { $result[mb_strtolower(rawurldecode($k))] = TranslateParameter($v); } break; case 'string': $o = JsonStringToJsonObject($parameter); if (!is_object($o)) { $result = rawurldecode($parameter); if( is_float($result) ){ $result = (float)$result; } if( is_int($result) ){ $result = (int)$result; } } else { $result = TranslateParameter($o); } break; default: $result = rawurldecode($parameter); if( is_float($result) ){ $result = (float)$result; } if( is_int($result) ){ $result = (int)$result; } break; } return $result; } /******************************* * name: UnicodeCodeToUnicodeString. * note: convert unicodecode to string(\uxxxx-->xx). * parameters: string * return: unicodestring if the function call succeeded, null otherwise. ******************************* * @param string $string * @return string *******************************/ function UnicodeCodeToUnicodeString($string) { try { if (function_exists('preg_replace_callback')) return preg_replace_callback('#\\\u([0-9a-f]{4})#i', function ($r) { return iconv('UCS-2BE', 'UTF-8', pack('H4', $r[1])); }, $string); elseif (function_exists('preg_replace')) return preg_replace('#\\\u([0-9a-f]{4})#ie', 'iconv(\'UCS-2BE\', \'UTF-8\', pack(\'H4\', \'\\1\'))', $string); else return $string; } catch (Exception $Exception) { return null; } } /******************************* * name: JsonObjectToJsonString. * note: convert object to string on json_encode function. * parameters: mixed object * return: return value for json_encode. ******************************* * @param mixed $object * @return string *******************************/ function JsonObjectToJsonString($object) { /// http://php.net/manual/zh/function.json-encode.php if (defined('JSON_UNESCAPED_UNICODE')) return json_encode($object, JSON_UNESCAPED_UNICODE); else return UnicodeCodeToUnicodeString(json_encode($object)); } /******************************* * name: JsonStringToJsonObject. * note: convert string to object on json_decode function. * parameters: string * return: object if the function call succeeded, null otherwise. ******************************* * @param string $string * @return mixed *******************************/ function JsonStringToJsonObject($string) { /// http://php.net/manual/zh/function.json-decode.php if (!$object = json_decode($string)) { //$object = json_decode(addslashes($string)); //stripslashes /** @noinspection PhpIncludeInspection */ ///$string = preg_replace_callback('/' . preg_quote('\\') . '/', function ($char){return '\\\\';}, $string); $string = str_replace('\\', '\\\\', $string); $object = json_decode($string); if (!$object) $object = $string; } return $object; } function XmlObjectToXmlString($Object) { if (is_object($Object)) $Xml = (array)$Object; else $Xml = $Object; if (!is_array($Xml)) return strval($Xml); elseif (Count($Xml) <= 0) return ''; $Result = ''; foreach ($Xml as $Key => $Value) { if (is_numeric($Value)) { $Result .= "<{$Key}>{$Value}"; } elseif (is_object($Value) || is_array($Value)) { $Value = XmlObjectToXmlString($Value); $Result .= "<{$Key}>"; } else { $Result .= "<{$Key}>"; } } $Result .= ''; return $Result; } function XmlStringToXmlObject($String) { // 将XML转为array // 禁止引用外部xml实体 libxml_disable_entity_loader(true); $Result = @simplexml_load_string($String, 'SimpleXMLElement', LIBXML_NOCDATA); return $Result ? $Result : $String; }