Files
youlegames/codes/agent/game/api/framework/function/global.func.php
2026-03-15 01:27:05 +08:00

1202 lines
36 KiB
PHP
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<?php
defined('IN_IA') or exit('Access Denied');
// 修复apibase.php的路径 - 使用绝对路径
$apibase_path = dirname(dirname(__DIR__)) . '/source/apis/apibase.php';
if (file_exists($apibase_path)) {
require_once $apibase_path;
} else {
// 如果文件不存在,记录错误但不中断执行
error_log("apibase.php not found at: $apibase_path");
}
// 比较两个版本的大小
// 第一个版本低于第二个版本的时候 return -1
// 第一个版本等于第二个版本的时候 return 0
// 第一个版本小于第二个版本的时候 return 1
function ver_compare($version1, $version2) {
$version1 = str_replace('.', '', $version1);
$version2 = str_replace('.', '', $version2);
$oldLength = istrlen($version1);
$newLength = istrlen($version2);
if ($oldLength > $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 实体
// 并将内容的&amp;替换为&
function ihtmlspecialchars($var) {
// str_replace替换指定字符串中指定的值为某个值
// 参数1要替换的内容
// 参数2要替换后的内容
// 参数3被搜索的字符串
// htmlspecialchars把预定义的字符 "<" (小于)和 ">" (大于)转换为 HTML 实体
// 参数1要处理的字符串
// 参数2可选。规定如何处理引号、无效的编码以及使用哪种文档类型。
// 可用的引号类型:
// ENT_COMPAT - 默认。仅编码双引号。
// ENT_QUOTES - 编码双引号和单引号。
// ENT_NOQUOTES - 不编码任何引号。
//无效的编码:
// ENT_IGNORE - 忽略无效的编码,而不是让函数返回一个空的字符串。
// 应尽量避免,因为这可能对安全性有影响。
// ENT_SUBSTITUTE - 把无效的编码替代成一个指定的带有 Unicode 替代字符
// U+FFFDUTF-8或者 &#FFFD; 的字符,而不是返回一个空的字符串。
// ENT_DISALLOWED - 把指定文档类型中的无效代码点替代成 Unicode
// 替代字符 U+FFFDUTF-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('&amp;', '&', 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 = '<div><ul class="pagination pagination-centered">';
if ($pdata['cindex'] > 1) {
$html .= "<li><a {$pdata['faa']} class=\"pager-nav\">首页</a></li>";
$html .= "<li><a {$pdata['paa']} class=\"pager-nav\">&laquo;上一页</a></li>";
}
if (!$context['before'] && $context['before'] != 0) {
$context['before'] = 5;
}
if (!$context['after'] && $context['after'] != 0) {
$context['after'] = 4;
}
if ($context['after'] != 0 && $context['before'] != 0) {
$range = array();
$range['start'] = max(1, $pdata['cindex'] - $context['before']);
$range['end'] = min($pdata['tpage'], $pdata['cindex'] + $context['after']);
if ($range['end'] - $range['start'] < $context['before'] + $context['after']) {
$range['end'] = min($pdata['tpage'], $range['start'] + $context['before'] + $context['after']);
$range['start'] = max(1, $range['end'] - $context['before'] - $context['after']);
}
for ($i = $range['start']; $i <= $range['end']; $i++) {
if ($context['isajax']) {
$aa = 'href="javascript:;" page="' . $i . '" '. ($callbackfunc ? 'onclick="'.$callbackfunc.'(\'' . $_W['script_name'] . $url . '\', \'' . $i . '\', this);return false;"' : '');
} else {
if ($url) {
$aa = 'href="?' . str_replace('*', $i, $url) . '"';
} else {
$_GET['page'] = $i;
$aa = 'href="?' . http_build_query($_GET) . '"';
}
}
$html .= ($i == $pdata['cindex'] ? '<li class="active"><a href="javascript:;">' . $i . '</a></li>' : "<li><a {$aa}>" . $i . '</a></li>');
}
}
if ($pdata['cindex'] < $pdata['tpage']) {
$html .= "<li><a {$pdata['naa']} class=\"pager-nav\">下一页&raquo;</a></li>";
$html .= "<li><a {$pdata['laa']} class=\"pager-nav\">尾页</a></li>";
}
$html .= '</ul></div>';
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
// 地址,可以做到防盗链作用,只有点击超链接(即<A href=...>
// 打开的页面才有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('&amp;', '&', $_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('&amp;', '&quot;', '&lt;', '&gt;'), 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('&amp;', '&quot;', '&lt;', '&gt;'), $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","/:<W>","/: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","/:<L>","/:jump","/:shake","/:<O>","/:circle",
"/:kotow","/:turn","/:skip","/:oY","/:#-0","/:hiphot","/:kiss","/:<&","/:&>"
);
foreach ($emotions as $index => $emotion) {
$message = str_replace($emotion, '<img style="width:'.$size.';vertical-align:middle;" src="http://res.mail.qq.com/zh_CN/images/mo/DEFAULT2/'.$index.'.gif" />', $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 ? "<xml>" : '';
foreach ($arr as $tagname => $value) {
if (is_numeric($tagname)) {
$tagname = $value['TagName'];
unset($value['TagName']);
}
if (!is_array($value)) {
$s .= "<{$tagname}>" . (!is_numeric($value) ? '<![CDATA[' : '') . $value . (!is_numeric($value) ? ']]>' : '') . "</{$tagname}>";
} else {
$s .= "<{$tagname}>" . array2xml($value, $level + 1) . "</{$tagname}>";
}
}
$s = preg_replace("/([\x01-\x08\x0b-\x0c\x0e-\x1f])+/", ' ', $s);
return $level == 1 ? $s . "</xml>" : $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;', '#nbsp;', $str);
return str_replace('#nbsp;', '&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 = '<xml>';
foreach ($Xml as $Key => $Value)
{
if (is_numeric($Value))
{
$Result .= "<{$Key}>{$Value}</{$Key}>";
}
elseif (is_object($Value) || is_array($Value))
{
$Value = XmlObjectToXmlString($Value);
$Result .= "<{$Key}><![CDATA[{$Value}]]></{$Key}>";
}
else
{
$Result .= "<{$Key}><![CDATA[{$Value}]]></{$Key}>";
}
}
$Result .= '</xml>';
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;
}