1184 lines
39 KiB
PHP
1184 lines
39 KiB
PHP
<?php
|
||
/* =================================================================================
|
||
* License: GPL-2.0 license
|
||
* Author: 众产® https://ciy.cn/code
|
||
* Version: 0.7.9
|
||
====================================================================================*/
|
||
/*
|
||
* common.php 常用公共函数库
|
||
*
|
||
* 功能函数相关
|
||
* clog/var_dump PHP调试变量界面打印
|
||
* fixmonth/todate 日期月份增减函数/数字时间转字符串
|
||
* locinzone 当前经纬度是否在围栏中
|
||
* timems 获取当前微秒数
|
||
* totimepoint 数字时钟转字符串
|
||
* ismobile 判断手机号是否合法
|
||
* isweixin 判断客户端是否在微信中
|
||
* idcard 判断身份证号合法
|
||
* iduscc 判断统一社会信用代码合法
|
||
* locdistance 计算两经纬度之间的距离(毫米METRE)
|
||
*
|
||
* 加解密相关
|
||
* encrypt 字符串加解密
|
||
* enid/deid ID数字加解密
|
||
* conv33_10/conv10_33 数字转33进制
|
||
*
|
||
* 字符串/数组相关
|
||
* arrayrand 随机抽取数组元素并删除
|
||
* startwith/endwith 首字符/尾字符匹配
|
||
* strpos_first 字符数组优先匹配,一般匹配 ' "
|
||
* gb_substr/gb_strlen/gb_haschinese 中文字符串处理函数
|
||
* getstrparam/setstrparam 比json还简化的数据保存方式,一般用于数据字典保存。例: name=AAA|age=12|cc=CCTT
|
||
*
|
||
* 数据库相关
|
||
* fieldadd 手动增加列表显示字段,并返回排序字段字符串
|
||
* getrelation 获取表内关联数据,用于大数据量表的所属ID转文字
|
||
* tran_delcheck/tran_delall/me 事务删除前确认/删除相关数据
|
||
*
|
||
* 字典相关
|
||
* id2map 将 id/name代码数组对 转换为 键值对
|
||
* ccode 代码数组中,通过代码值找代码名
|
||
* mcode 代码数组中,通过代码值找代码名,多级
|
||
* scode 代码数组中,查找多个代码值,返回数组
|
||
* dcode 代码数组中,通过代码名找代码值
|
||
*
|
||
* LOG相关
|
||
* savelogfile 保存log信息写入到本地文件
|
||
* logdbstr 将数据变化格式化成字符串
|
||
*
|
||
* 输入输出相关
|
||
* \ciy\post{} payload json参数处理类 is/get/getint/getfloat/getdate/getbool/getraw/safehtml
|
||
* getstr/getint/post/request/cookie 获取用户输入数据(不能信任任何用户输入,包括cookie)
|
||
* getip IP的快捷函数,支持数字和字符串返回
|
||
*
|
||
* 文件相关
|
||
* dirmake/filedel/copy/save/load 创建多层新文件夹/文件静默删除/拷贝/保存/读取
|
||
* file_down URL文件下载保存
|
||
* fileext 获取文件扩展名,如jpg
|
||
*/
|
||
if (substr(__DIR__, 0, 1) == '/')
|
||
error_reporting(0); //0禁用错误输出;E_ALL打开错误输出
|
||
else
|
||
error_reporting(E_ALL); //0禁用错误输出;E_ALL打开错误输出
|
||
date_default_timezone_set('Asia/Shanghai');
|
||
|
||
if (!isset($path))
|
||
$path = $_SERVER['DOCUMENT_ROOT'];
|
||
defined('PATH_ROOT') || define('PATH_ROOT', substr($path, 0, strrpos($path, '/') + 1)); //web根目录。
|
||
defined('PATH_WEB') || define('PATH_WEB', PATH_ROOT . 'web/'); //web根目录。
|
||
defined('NAME_SELF') || define('NAME_SELF', substr($_SERVER['PHP_SELF'], strrpos($_SERVER['PHP_SELF'], '/') + 1, -4));
|
||
defined('MAXTIMES') || define('MAXTIMES', 9999999999999);
|
||
$logpath = PATH_ROOT . 'log/';
|
||
|
||
spl_autoload_register(function ($class) {
|
||
if (substr($class, 0, 4) == 'ciy\\') //将zciyphp简写成ciy,z开头的目录通常排在最下,不过影响找业务目录。
|
||
$class = 'zciyphp\\' . substr($class, 4);
|
||
$file = PATH_ROOT . $class . '.php';
|
||
$file = str_replace('\\', '/', $file);
|
||
if (is_file($file)) {
|
||
require_once $file;
|
||
return;
|
||
}
|
||
});
|
||
class emptyclass {
|
||
}
|
||
|
||
function clog() {
|
||
echo "\n" . '<pre>';
|
||
$first = true;
|
||
foreach (func_get_args() as $var) {
|
||
if (is_null($var))
|
||
echo 'null';
|
||
else if (is_long($var))
|
||
echo 'long:' . $var;
|
||
else if (is_integer($var))
|
||
echo 'int:' . $var;
|
||
else if (is_string($var)) {
|
||
if (strlen($var) == 0)
|
||
echo 'str:---空字符串----';
|
||
else {
|
||
if ($first && func_num_args() > 1)
|
||
echo '<kbd>' . $var . '</kbd>';
|
||
else
|
||
echo 'str:' . $var;
|
||
}
|
||
} else if (is_bool($var))
|
||
echo 'bool:' . ($var ? 'true' : 'false');
|
||
else {
|
||
echo 'Type:' . gettype($var) . "\n";
|
||
print_r($var);
|
||
}
|
||
$first = false;
|
||
echo "\n";
|
||
}
|
||
echo '</pre>' . "\n";
|
||
@ob_flush();
|
||
flush();
|
||
}
|
||
|
||
function fixmonth($num, $dt) { //php +n months 修复在28号之后产生的错误
|
||
$day = date('d', $dt);
|
||
if ($day < 29)
|
||
return strtotime(($num > 0 ? '+' : '-') . $num . ' month', $dt);
|
||
$lastday = date('d', strtotime('last day of this month', $dt));
|
||
$nextdt = strtotime(($num > 0 ? '+' : '-') . $num . ' month', strtotime(date('Y-m-1', $dt)));
|
||
$nextlastday = date('d', strtotime('last day of this month', $nextdt));
|
||
if ($day <= $nextlastday)
|
||
return strtotime(date('Y-m-', $nextdt) . $day);
|
||
return strtotime(date('Y-m-', $nextdt) . ($nextlastday - $lastday + $day));
|
||
}
|
||
function tostr($str = '') {
|
||
if (!$str)
|
||
return '';
|
||
return $str . '';
|
||
}
|
||
function toint($str = 0) {
|
||
if (!$str)
|
||
return 0;
|
||
if (!is_numeric($str))
|
||
return 0;
|
||
return intval(round($str));
|
||
}
|
||
function todate($time, $format = 'i') {
|
||
if ($time == 0)
|
||
return '--';
|
||
if ($format == 'H')
|
||
return date('Y-m-d H', $time);
|
||
if ($format == 'd')
|
||
return date('Y-m-d', $time);
|
||
if ($format == 'hi')
|
||
return date('H:i', $time);
|
||
if ($format == 'm')
|
||
return date('Y-m', $time);
|
||
if ($format == 's')
|
||
return date('Y-m-d H:i:s', $time);
|
||
return date('Y-m-d H:i', $time);
|
||
}
|
||
function totimepoint($time, $bsecond = false) {
|
||
$time = toint($time);
|
||
if ($time <= 0 || $time > 86400)
|
||
return '';
|
||
$time--;
|
||
$hour = toint($time / 3600);
|
||
$minute = toint((($time - $hour * 3600) / 60));
|
||
$ret = str_pad($hour, 2, '0', STR_PAD_LEFT) . ':' . str_pad($minute, 2, '0', STR_PAD_LEFT);
|
||
if ($bsecond)
|
||
return $ret;
|
||
$second = toint($time - $hour * 3600 - $minute * 60);
|
||
return $ret . ':' . str_pad($second, 2, '0', STR_PAD_LEFT);
|
||
}
|
||
function tounit($val) {
|
||
$us = explode('|', $val);
|
||
$vals = array();
|
||
if (count($us) == 5)
|
||
$vals[] = '1' . $us[4] . $us[3] . $us[2];
|
||
if (count($us) > 2)
|
||
$vals[] = '1' . $us[2] . $us[1] . $us[0];
|
||
if (count($vals) == 0 && !empty($us[0]))
|
||
$vals[] = $us[0];
|
||
return $vals;
|
||
}
|
||
function tocyc($val) {
|
||
if ($val < 0)
|
||
return -$val . '月';
|
||
else if ($val >= 86400)
|
||
return toint($val / 86400) . '天';
|
||
else
|
||
return $val . '秒';
|
||
}
|
||
function tostamp($str = 'now') {
|
||
if ($str == 'now')
|
||
return time();
|
||
$time = strtotime($str);
|
||
if ($time === false)
|
||
return 0;
|
||
return $time;
|
||
}
|
||
function locinzone($paths, $zlat, $zlng) {
|
||
//30.434272 120.274938,30.433977 120.277270,30.432403 120.277957,30.431764 120.276340,30.432270 120.273358,30.433997 120.273283
|
||
$fences = explode(',', $paths);
|
||
$nvert = count($fences);
|
||
$vertx = [];
|
||
$verty = [];
|
||
foreach ($fences as $r) {
|
||
list($lat, $lng) = explode(' ', $r);
|
||
$vertx[] = $lat;
|
||
$verty[] = $lng;
|
||
}
|
||
$i = $j = 0;
|
||
$c = false;
|
||
for ($i = 0, $j = $nvert - 1; $i < $nvert; $j = $i++) {
|
||
if ((($verty[$i] > $zlng) != ($verty[$j] > $zlng)) &&
|
||
($zlat < ($vertx[$j] - $vertx[$i]) * ($zlng - $verty[$i]) / ($verty[$j] - $verty[$i]) + $vertx[$i])
|
||
)
|
||
$c = !$c;
|
||
}
|
||
return $c;
|
||
}
|
||
function timems() {
|
||
$microtime = microtime();
|
||
$comps = explode(' ', $microtime);
|
||
return toint(sprintf('%d%03d', $comps[1], $comps[0] * 1000));
|
||
}
|
||
function ismobile($mob) {
|
||
return preg_match('/^1\d{10}$/', $mob);
|
||
}
|
||
function ismail($str) {
|
||
return filter_var($str, FILTER_VALIDATE_EMAIL);
|
||
}
|
||
function isweixin() {
|
||
$useragent = strtolower($_SERVER["HTTP_USER_AGENT"]);
|
||
$is_weixin = strripos($useragent, 'micromessenger');
|
||
if ($is_weixin > 0)
|
||
return true;
|
||
return false;
|
||
}
|
||
function getcciycheck($num) {
|
||
$checksum = 0;
|
||
for ($i = 15; $i > 0; $i--) {
|
||
$nibble = ($num >> (4 * $i)) & 0xF;
|
||
$checksum ^= $nibble;
|
||
}
|
||
return $checksum;
|
||
}
|
||
function iscciy($num) {
|
||
return getcciycheck($num) == ($num & 0xf);
|
||
}
|
||
function idcard($str) {
|
||
$str = strtoupper(trim($str));
|
||
if (empty($str))
|
||
return '身份证未输入';
|
||
if (strlen($str) != 18)
|
||
return '身份证长度错误';
|
||
$province = ['11', '12', '13', '14', '15', '21', '22', '23', '31', '32', '33', '34', '35', '36', '37', '41', '42', '43', '44', '45', '46', '50', '51', '52', '53', '54', '61', '62', '63', '64', '65', '71', '81', '82', '91'];
|
||
if (!in_array(substr($str, 0, 2), $province))
|
||
return '身份证地区不合法';
|
||
|
||
$birth_year = substr($str, 6, 4);
|
||
$birth_month = substr($str, 10, 2);
|
||
$birth_day = substr($str, 12, 2);
|
||
$birth = strtotime($birth_year . '-' . $birth_month . '-' . $birth_day);
|
||
if ($birth === false)
|
||
return '身份证生日错误';
|
||
if ($birth > time())
|
||
return '身份证生日不能超过今天';
|
||
$ahead17_char = substr($str, 0, 17);
|
||
$last_char = substr($str, -1);
|
||
$factor = array(7, 9, 10, 5, 8, 4, 2, 1, 6, 3, 7, 9, 10, 5, 8, 4, 2);
|
||
$c = array(1, 0, 'X', 9, 8, 7, 6, 5, 4, 3, 2);
|
||
$t_res = 0;
|
||
for ($i = 0; $i < 17; $i++) {
|
||
$t_res += intval($ahead17_char[$i]) * $factor[$i];
|
||
}
|
||
$calc_last_char = $c[$t_res % 11];
|
||
if (strtolower($last_char) != strtolower($calc_last_char))
|
||
return '身份证校验位错误'; // . $calc_last_char;
|
||
$sex = substr($str, -2, 1);
|
||
if ($sex % 2 == 0)
|
||
$sex = 2;
|
||
else
|
||
$sex = 1;
|
||
//$age = toint(date('Y')) - toint($birth_year);
|
||
return ['code' => $str, 'birth' => $birth_year . '-' . $birth_month . '-' . $birth_day, 'sex' => $sex, 'area' => substr($str, 0, 6)];
|
||
}
|
||
function iduscc($uscc) {
|
||
$uscc = strtoupper(trim($uscc));
|
||
if (empty($uscc))
|
||
return '统一社会信用代码未输入';
|
||
if (strlen($uscc) != 18)
|
||
return '统一社会信用代码不是18位';
|
||
$province = ['11', '12', '13', '14', '15', '21', '22', '23', '31', '32', '33', '34', '35', '36', '37', '41', '42', '43', '44', '45', '46', '50', '51', '52', '53', '54', '61', '62', '63', '64', '65', '71', '81', '82', '91'];
|
||
if (!in_array(substr($uscc, 2, 2), $province))
|
||
return '统一社会信用代码地区不合法';
|
||
$lcrc = _tsucc(substr($uscc, 0, 17));
|
||
if (substr($uscc, -1, 1) != $lcrc)
|
||
return '统一社会信用代码校验位错误';
|
||
return ['code' => $uscc, 'area' => substr($uscc, 2, 6), 'pn' => substr($uscc, 0, 2)];
|
||
}
|
||
function _tsucc($usc) {
|
||
$list = array(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 'A' => 10, 'B' => 11, 'C' => 12, 'D' => 13, 'E' => 14, 'F' => 15, 'G' => 16, 'H' => 17, 'J' => 18, 'K' => 19, 'L' => 20, 'M' => 21, 'N' => 22, 'P' => 23, 'Q' => 24, 'R' => 25, 'T' => 26, 'U' => 27, 'W' => 28, 'X' => 29, 'Y' => 30);
|
||
$listf = array_flip($list);
|
||
$wi = array(1, 3, 9, 27, 19, 26, 16, 17, 20, 29, 25, 13, 8, 24, 10, 30, 28);
|
||
$num = 0;
|
||
for ($i = 0; $i < 17; $i++) {
|
||
$num += $list[$usc[$i]] * $wi[$i];
|
||
}
|
||
switch ($num % 31) {
|
||
case '0':
|
||
$result = 0;
|
||
break;
|
||
default:
|
||
$result = 31 - $num % 31;
|
||
break;
|
||
}
|
||
return $listf[$result];
|
||
}
|
||
function locdistance($lat1, $lng1, $lat2, $lng2) {
|
||
$earthRadius = 6367000;
|
||
$lat1 = ($lat1 * pi()) / 180;
|
||
$lng1 = ($lng1 * pi()) / 180;
|
||
$lat2 = ($lat2 * pi()) / 180;
|
||
$lng2 = ($lng2 * pi()) / 180;
|
||
$calcLongitude = $lng2 - $lng1;
|
||
$calcLatitude = $lat2 - $lat1;
|
||
$stepOne = pow(sin($calcLatitude / 2), 2) + cos($lat1) * cos($lat2) * pow(sin($calcLongitude / 2), 2);
|
||
$stepTwo = 2 * asin(min(1, sqrt($stepOne)));
|
||
$Distance = $earthRadius * $stepTwo;
|
||
return $Distance * 1000;
|
||
}
|
||
function str2bin($str) {
|
||
$bytes = [];
|
||
for ($i = 0; $i < strlen($str); $i++) {
|
||
$bytes[] = ord($str[$i]);
|
||
}
|
||
return $bytes;
|
||
}
|
||
|
||
function ciysign($str, $key) {
|
||
$sign = hash_hmac('sha256', $str, $key, false);
|
||
$sign = substr($sign, 0, 16);
|
||
$sign = str_replace($sign, 'd', 'p');
|
||
$sign = str_replace($sign, 'e', 'z');
|
||
$sign = str_replace($sign, 'f', 'm');
|
||
return $sign;
|
||
}
|
||
/* * *******************************************************************
|
||
* 函数名称:encrypt
|
||
* 函数作用:加密解密字符串
|
||
* 安全函数,建议有能力自行修改一些
|
||
* 使用方法:
|
||
* 加密 :encrypt('str','E','nowamagic');
|
||
* 解密 :encrypt('被加密过的字符串','D','nowamagic');
|
||
* 参数说明:
|
||
* $string :需要加密解密的字符串
|
||
* $operation:判断是加密还是解密:E:加密 D:解密
|
||
* $key :加密的钥匙(密匙);
|
||
* ******************************************************************* */
|
||
function encrypt($string, $operation, $key = '') {
|
||
$key = md5($key, true);
|
||
$key_length = strlen($key);
|
||
if ($operation == 'D')
|
||
$string = base64_decode(substr(str_replace('_', '/', str_replace('-', '+', str_replace('*', '=', $string))), 1));
|
||
else {
|
||
$string = substr(md5($string . $key, true), 0, 8) . $string;
|
||
}
|
||
$string_length = strlen($string);
|
||
$rndkey = $box = array();
|
||
$result = '';
|
||
for ($i = 0; $i < 256; $i++) {
|
||
$rndkey[$i] = ord($key[$i % $key_length]);
|
||
$box[$i] = $i;
|
||
}
|
||
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 == 'D') {
|
||
if (substr($result, 0, 8) == substr(md5(substr($result, 8) . $key, true), 0, 8)) {
|
||
return substr($result, 8);
|
||
} else {
|
||
return '';
|
||
}
|
||
} else {
|
||
return '1' . str_replace('/', '_', str_replace('+', '-', str_replace('=', '*', base64_encode($result))));
|
||
}
|
||
}
|
||
/* * *******************************************************************
|
||
* 函数名称:enid/deid
|
||
* 函数作用:id加密函数/id解密函数。
|
||
* 安全函数,建议有能力自行修改一些
|
||
* 参数说明:
|
||
* $id 两位数的数字id(id>=10)
|
||
* 返回值:加密后的数字
|
||
* 例:enid(8245) = 872435
|
||
* 例:deid(872435) = 8245
|
||
* ******************************************************************* */
|
||
function enid($id, $key = 253) {
|
||
$id = toint($id);
|
||
if ($id <= 0)
|
||
return 0;
|
||
if ($id < 10)
|
||
$strid = '0' . $id;
|
||
else
|
||
$strid = $id . '';
|
||
$fx = _calnumber($id, $key);
|
||
$ulen = strlen($strid);
|
||
return substr($strid, 0, 1) . $fx[0] . substr($strid, 1, $ulen - 2) . $fx[1] . substr($strid, -1, 1);
|
||
}
|
||
function deid($id, $key = 253) {
|
||
$strid = $id . '';
|
||
$ulen = strlen($strid);
|
||
$fx = substr($strid, 1, 1) . substr($strid, -2, 1);
|
||
$id = toint(substr($strid, 0, 1) . substr($strid, 2, $ulen - 4) . substr($strid, -1, 1));
|
||
if ($fx == _calnumber($id, $key))
|
||
return $id;
|
||
return 0;
|
||
}
|
||
/* * *******************************************************************
|
||
* 函数名称:calnumber
|
||
* 函数作用:换算id的加密校验数,被enid、deid函数调用。
|
||
* 参数说明:
|
||
* $key 默认加密因子,可以自行修改。尽量用奇数100-1000
|
||
* $len 返回校验数位数。
|
||
* 返回值:len位数字字符串
|
||
* 例:calnumber(8245,224,2) = 73
|
||
* ******************************************************************* */
|
||
function _calnumber($num, $key, $len = 2) {
|
||
if ($num > 250600)
|
||
$num %= 250600;
|
||
$n = $num % 8566;
|
||
if ($n < 100)
|
||
$n += 100;
|
||
$xx = abs($num * $n + $key);
|
||
if ($xx % 13 > 8)
|
||
$xx += $key;
|
||
if ($xx % 13 > 4)
|
||
$xx += $key + $key + $key;
|
||
if ($len < 1)
|
||
$len = 2;
|
||
$ret = abs($xx % pow(10, $len));
|
||
return sprintf('%0' . $len . 'd', $ret);
|
||
}
|
||
function sha256($str) {
|
||
return hash('sha256', $str);
|
||
}
|
||
function sha512($str) {
|
||
return hash('sha512', $str);
|
||
}
|
||
function conv33_10($num) {
|
||
$from = 33;
|
||
$dict = 'abcdefghijkmnpqrstuvwxyz123456789';
|
||
$len = strlen($num);
|
||
$dec = 0;
|
||
for ($i = 0; $i < $len; $i++) {
|
||
$pos = strpos($dict, $num[$i]);
|
||
$dec = bcadd(bcmul(bcpow($from, $len - $i - 1), $pos), $dec);
|
||
}
|
||
return $dec;
|
||
}
|
||
|
||
function conv10_33($num) {
|
||
$to = 33;
|
||
$dict = 'abcdefghijkmnpqrstuvwxyz123456789';
|
||
$ret = '';
|
||
do {
|
||
$ret = $dict[bcmod($num, $to)] . $ret;
|
||
$num = bcdiv($num, $to);
|
||
} while ($num > 0);
|
||
return $ret;
|
||
}
|
||
function arrayrand($arr, $num = 1) {
|
||
$retarr = array();
|
||
if (count($arr) < $num)
|
||
$num = count($arr);
|
||
for ($i = 0; $i < $num; $i++) {
|
||
$ind = array_rand($arr);
|
||
$retarr[] = array_splice($arr, $ind, 1)[0];
|
||
}
|
||
return $retarr;
|
||
}
|
||
function startwith($str, $suffix) {
|
||
return strpos($str, $suffix) === 0;
|
||
}
|
||
function endwith($str, $suffix) {
|
||
return substr($str, -strlen($suffix)) === $suffix;
|
||
}
|
||
function strpos_first($search, $findstrs, $offset = 0) { //返回第一个char位置,第一个char,内部位置
|
||
if (strlen($search) < $offset)
|
||
return [-1, '', ''];
|
||
if (is_string($findstrs))
|
||
$findstrs = array($findstrs);
|
||
$f_str = '';
|
||
$f_ind = 2147483647;
|
||
foreach ($findstrs as $findstr) {
|
||
$ind = strpos($search, $findstr, $offset);
|
||
if ($ind === false)
|
||
continue;
|
||
if ($ind < $f_ind) {
|
||
$f_str = $findstr;
|
||
$f_ind = $ind;
|
||
}
|
||
}
|
||
if ($f_ind == 2147483647)
|
||
return [-1, '', ''];
|
||
$ind2 = strpos($search, $f_str, $f_ind + 1);
|
||
if ($ind2 > 0)
|
||
return [$f_ind, $f_str, substr($search, $f_ind + 1, $ind2 - $f_ind - 1)];
|
||
return [$f_ind, $f_str, ''];
|
||
}
|
||
/**
|
||
* 类似substr,主要用于显示字符限制。支持中文,2个半角算一个字符占位。超过部分用$dot代替。
|
||
* 建议:能用css实现超出汉字隐藏,尽量不要用此函数。
|
||
* 例:gb_substr('CHN中华人民共和国',10)='CHN中华...' gb_substr('CHN中华人民共和国',9)='CHN中华...'
|
||
*/
|
||
function gb_substr($str, $len, $dot = '...') {
|
||
$i = 0;
|
||
$l = 0;
|
||
$c = 0;
|
||
$a = array();
|
||
while ($l < $len) {
|
||
$t = substr($str, $i, 1);
|
||
if (ord($t) >= 224) {
|
||
$c = 3;
|
||
$t = substr($str, $i, $c);
|
||
$l += 2;
|
||
} elseif (ord($t) >= 192) {
|
||
$c = 2;
|
||
$t = substr($str, $i, $c);
|
||
$l += 2;
|
||
} else {
|
||
$c = 1;
|
||
$l++;
|
||
}
|
||
$i += $c;
|
||
if ($l > $len)
|
||
break;
|
||
$a[] = $t;
|
||
}
|
||
$re = implode('', $a);
|
||
if (substr($str, $i, 1) !== false) {
|
||
array_pop($a);
|
||
($c == 1) and array_pop($a);
|
||
$re = implode('', $a);
|
||
$re .= $dot;
|
||
}
|
||
return $re;
|
||
}
|
||
function dbstr($str, $len) {
|
||
if (mb_strlen($str, 'UTF-8') > $len)
|
||
return mb_substr($str, 0, $len, 'UTF-8');
|
||
return $str;
|
||
}
|
||
/**
|
||
* 类似strlen,英文算1个,中文算2个字符。
|
||
* 例:gb_strlen('CHN中华人民共和国')=17
|
||
*/
|
||
function gb_strlen($str) {
|
||
return (strlen($str) + mb_strlen($str, 'UTF8')) / 2;
|
||
}
|
||
|
||
function gb_haschinese($str) {
|
||
return preg_match("/([\x81-\xfe][\x40-\xfe])/", $str);
|
||
}
|
||
/**
|
||
* 比json还简化的多数据保存方式。该方式有一定的限制,请熟悉后使用。
|
||
* 例:getstrparam('Skey=10392|Pid=33|Memo=其他备注文字') = Array([Skey] => 10392[Pid] => 33[Memo] => 其他备注文字);
|
||
* $sparam = getstrparam('Skey=10392|Pid=33|Memo=其他备注文字');
|
||
* $val = @$sparam['Memo'];
|
||
* $sparam['Memo'] = 'xxx';
|
||
* $retval = setstrparam($sparam); 值: 'Skey=10392|Pid=33|Memo=xxx'
|
||
*/
|
||
function getstrparam($pstr, $split = '|') {
|
||
$strs = explode($split, $pstr);
|
||
$data = array();
|
||
foreach ($strs as $str) {
|
||
$ind = strpos($str, '=');
|
||
if ($ind !== false)
|
||
$data[substr($str, 0, $ind)] = trim(substr($str, $ind + 1));
|
||
}
|
||
return $data;
|
||
}
|
||
function setstrparam($parr, $split = '|') {
|
||
$pstr = '';
|
||
foreach ($parr as $p => $a)
|
||
$pstr .= $p . '=' . $a . $split;
|
||
return trim($pstr, $split);
|
||
}
|
||
function split($sp, $str) {
|
||
return explode($sp, trim($str, $sp));
|
||
}
|
||
function fieldadd($fshow, &$field, $pos, $key, $val) {
|
||
$field[$key] = array('c' => $val);
|
||
$fshows = explode(',', $fshow);
|
||
if ($pos == -1) {
|
||
if (empty($fshows[0]))
|
||
$fshows[0] = $key;
|
||
else
|
||
$fshows[] = $key;
|
||
} else if ($pos == 0)
|
||
array_unshift($fshows, $key);
|
||
else
|
||
array_splice($fshows, $pos, 0, $key);
|
||
return implode(',', $fshows);
|
||
}
|
||
function getrelation($cdb, $rows, $table, $fieldstr, $column = 'id,name', $queryid = 'id') {
|
||
$ids = array();
|
||
$fields = explode(',', $fieldstr);
|
||
foreach ($fields as $field) {
|
||
foreach ($rows as $row) {
|
||
if (isset($row[$field]) && !in_array($row[$field], $ids))
|
||
$ids[] = $row[$field];
|
||
}
|
||
}
|
||
if (count($ids) == 0)
|
||
return array();
|
||
$csql = new \ciy\sql($table);
|
||
$csql->where($queryid . ' in ', implode(',', $ids));
|
||
$csql->column($column);
|
||
return $cdb->get($csql);
|
||
}
|
||
function delcheck($db, $delid, $table, $field, $msg = '', $where = '') {
|
||
$csql = new \ciy\sql($table);
|
||
if (!empty($where))
|
||
$csql->where($where);
|
||
$csql->where($field, $delid);
|
||
$cnt = $db->get1($csql);
|
||
if ($cnt > 0)
|
||
throw new \Exception('CIYIGN存在' . $cnt . '个' . $msg . ',不能删除');
|
||
}
|
||
function delall($db, $delid, $table, $field, $msg = '') {
|
||
$csql = new \ciy\sql($table);
|
||
$csql->where($field, $delid);
|
||
if ($db->delete($csql) === false)
|
||
throw new \Exception($msg . '删除失败:' . $db->error);
|
||
}
|
||
function delme($db, $delid, $table) {
|
||
$csql = new \ciy\sql($table);
|
||
$csql->where('id', $delid);
|
||
if ($db->delete($csql) === false)
|
||
throw new \Exception('删除失败:' . $db->error);
|
||
}
|
||
function deltimeall($db, $delid, $table, $field, $msg = '') {
|
||
if ($db->execute('update ' . $table . ' set deltimes=' . time() . ' where ' . $field . '=' . $delid) === false)
|
||
throw new \Exception($msg . '标记删除失败:' . $db->error);
|
||
}
|
||
function deltimeme($db, $delid, $table) {
|
||
if ($db->execute('update ' . $table . ' set deltimes=' . time() . ' where id=' . $delid) === false)
|
||
throw new \Exception('标记删除失败:' . $db->error);
|
||
}
|
||
|
||
function mapid2data($datas) {
|
||
$ret = array();
|
||
foreach ($datas as $data) {
|
||
$ret[$data['id']] = $data;
|
||
}
|
||
return $ret;
|
||
}
|
||
function mapid2any($datas) {
|
||
$ret = array();
|
||
foreach ($datas as $data) {
|
||
$ret[$data['id']] = $data;
|
||
}
|
||
return $ret;
|
||
}
|
||
function ccode($rows, $code, $showcode = 'id', $showtitle = 'name') {
|
||
foreach ($rows as $row) {
|
||
if ($code == $row[$showcode]) {
|
||
if (empty($showtitle))
|
||
return $row;
|
||
return $row[$showtitle];
|
||
}
|
||
}
|
||
if (empty($showtitle))
|
||
return null;
|
||
return '--';
|
||
}
|
||
function mcode($rows, $code, $showcode = 'id', $showtitle = 'name', $upcode = 'upid') {
|
||
$codes = array();
|
||
for ($i = 0; $i < 10; $i++) {
|
||
if ($code <= 0)
|
||
break;
|
||
$bfind = false;
|
||
foreach ($rows as $row) {
|
||
if ($code == $row[$showcode]) {
|
||
if (empty($showtitle))
|
||
array_unshift($codes, $row);
|
||
else
|
||
array_unshift($codes, $row[$showtitle]);
|
||
$code = toint(@$row[$upcode]);
|
||
$bfind = true;
|
||
break;
|
||
}
|
||
}
|
||
if (!$bfind)
|
||
break;
|
||
}
|
||
return $codes;
|
||
}
|
||
function scode($rows, $code, $showcode = 'id', $showtitle = 'name') {
|
||
$rets = array();
|
||
$codes = explode(',', $code);
|
||
foreach ($codes as $c) {
|
||
if (empty($c))
|
||
continue;
|
||
foreach ($rows as $row) {
|
||
if ($c == $row[$showcode]) {
|
||
if (empty($showtitle))
|
||
$rets[] = $row;
|
||
else
|
||
$rets[] = $row[$showtitle];
|
||
}
|
||
}
|
||
}
|
||
return $rets;
|
||
}
|
||
function bcode($rows, $val) {
|
||
$rets = array();
|
||
$val = toint($val);
|
||
foreach ($rows as $cod) {
|
||
if (($val & (1 << (toint($cod['id']) - 1))) != 0)
|
||
$rets[] = $cod['name'];
|
||
}
|
||
return $rets;
|
||
}
|
||
function dcode($rows, $codename, $showcode = 'id', $showtitle = 'name') {
|
||
foreach ($rows as $row) {
|
||
if ($codename == $row[$showtitle]) {
|
||
if (empty($showcode))
|
||
return $row;
|
||
return $row[$showcode];
|
||
}
|
||
}
|
||
return -1;
|
||
}
|
||
function logdbstr($oldrow, $newrow) {
|
||
$msg = '';
|
||
if (is_array($oldrow) && is_array($newrow)) {
|
||
$msg .= 'Upd=' . @$oldrow['id'];
|
||
$modify = false;
|
||
foreach ($newrow as $f => $v) {
|
||
if (!isset($oldrow[$f]))
|
||
continue;
|
||
if ($oldrow[$f] != $v) {
|
||
$msg .= '_|@|_' . $f . '=' . $oldrow[$f] . '→' . $v;
|
||
$modify = true;
|
||
}
|
||
}
|
||
if (!$modify)
|
||
return "";
|
||
} else if (is_array($newrow)) {
|
||
$msg .= 'Ins=' . @$newrow['id'];
|
||
foreach ($newrow as $f => $v) {
|
||
if ($f == 'id')
|
||
continue;
|
||
$msg .= '_|@|_' . $f . '=' . $v;
|
||
}
|
||
} else if (is_array($oldrow)) {
|
||
$msg .= 'Del=' . @$oldrow['id'];
|
||
foreach ($oldrow as $f => $v) {
|
||
if ($f == 'id')
|
||
continue;
|
||
$msg .= '_|@|_' . $f . '=' . $v;
|
||
}
|
||
} else {
|
||
return "";
|
||
}
|
||
return $msg;
|
||
}
|
||
function savelogfile($types, $msg, $isrequest = false) {
|
||
global $logpath;
|
||
if (substr($msg, 0, 6) == 'CIYIGN')
|
||
return true;
|
||
$filename = $logpath . $types . '.log';
|
||
$dir = dirname($filename);
|
||
dirmake($dir);
|
||
$fp = fopen($filename, 'a');
|
||
if (!$fp)
|
||
return false;
|
||
if ($isrequest) {
|
||
$msg .= ' GET:';
|
||
foreach ($_GET as $key => $value)
|
||
$msg .= $key . '=' . $value . '&';
|
||
$msg .= ' POST:' . file_get_contents('php://input');
|
||
}
|
||
$msg .= "\r\n";
|
||
if (@fwrite($fp, date('Y-m-d H:i:s') . "\t" . $msg)) {
|
||
fclose($fp);
|
||
return true;
|
||
}
|
||
fclose($fp);
|
||
return false;
|
||
}
|
||
/**
|
||
* JSON函数调用组件,用于界面Ajax请求在本页处理。
|
||
* isform 用于页面form提交刷新的直接请求。非ajax请求。(为兼容传统更新方式,不建议使用)
|
||
* ?func=函数名
|
||
* 将调用json_函数名(){}
|
||
* 函数返回array数组。
|
||
*/
|
||
function _setmemvar($db, $types, $value) {
|
||
// if (function_exists('setmemvar'))
|
||
// return setmemvar($db, $types, $value);
|
||
return false;
|
||
}
|
||
function ciy_ouputJSON($retarr, $ms = 0, $uri = '') {
|
||
global $db;
|
||
global $_token;
|
||
if ($db) {
|
||
if ($ms > 0) {
|
||
_setmemvar($db, 'func_runms', array('params+' . $ms));
|
||
if ($ms > 500 && !empty($uri)) {
|
||
$updata = array();
|
||
$updata['uri'] = $uri;
|
||
$updata['posts'] = file_get_contents('php://input');
|
||
$updata['ms'] = $ms;
|
||
$updata['addtimes'] = tostamp();
|
||
$csql = new \ciy\sql('zc_funcslow');
|
||
$db->insert($csql, $updata);
|
||
}
|
||
}
|
||
if (isset($retarr['code']) && $retarr['code'] == 1)
|
||
_setmemvar($db, 'func_succ', array('params+1'));
|
||
else
|
||
_setmemvar($db, 'func_fail', array('params+1'));
|
||
}
|
||
if (isset($_token['__ciyauth']))
|
||
$retarr['_ciyauth'] = $_token['__ciyauth'];
|
||
$jsonstr = json_encode($retarr, JSON_PARTIAL_OUTPUT_ON_ERROR | JSON_UNESCAPED_UNICODE);
|
||
if ($jsonstr === false) {
|
||
$retarr['errmsg'] = mb_convert_encoding($retarr['errmsg'], 'UTF-8', 'ISO-8859-1');
|
||
$jsonstr = json_encode($retarr);
|
||
if ($jsonstr === false) {
|
||
$retarr['errmsg'] = json_last_error_msg();
|
||
$jsonstr = json_encode($retarr);
|
||
}
|
||
}
|
||
if (isset($_GET['jsonp'])) {
|
||
$callback = $_GET['jsonp'];
|
||
if (strlen($callback) < 128 && preg_match('/^[A-Za-z_][A-Za-z0-9_]*$/', $callback)) {
|
||
header('Content-Type: application/javascript; charset=utf-8');
|
||
die($callback . '(' . $jsonstr . ')');
|
||
}
|
||
}
|
||
header('Content-Type: application/json; charset=utf-8');
|
||
die($jsonstr);
|
||
}
|
||
//code=2 未登录,3 未授权,9 函数未加载
|
||
function errjson($error, $errcode = 0, $ext = null) {
|
||
if (is_array($ext))
|
||
$ret = $ext;
|
||
else
|
||
$ret = array();
|
||
if ($errcode == 1)
|
||
$errcode = -1;
|
||
$ret['code'] = $errcode;
|
||
if (substr($error, 0, 6) == 'CIYIGN')
|
||
$error = substr($error, 6);
|
||
$ret['errmsg'] = $error;
|
||
return $ret;
|
||
}
|
||
function succjson($ext = null) {
|
||
if (is_array($ext))
|
||
$ret = $ext;
|
||
else
|
||
$ret = array();
|
||
$ret['code'] = 1;
|
||
return $ret;
|
||
}
|
||
function memadd($key) {
|
||
}
|
||
function randstr($num, $letter = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890') {
|
||
$b = [];
|
||
for ($i = 0; $i < $num; $i++) {
|
||
$b[] = $letter[rand(0, strlen($letter) - 1)];
|
||
}
|
||
return implode('', $b);
|
||
}
|
||
function objstr($obj, $name, $defvalue = '', $allow = 'text') { //text:仅文本,all:都可以
|
||
if (!isset($obj[$name]))
|
||
return $defvalue;
|
||
$val = $obj[$name];
|
||
if (empty($val))
|
||
return $defvalue;
|
||
if ($allow == 'text')
|
||
return strip_tags($val);
|
||
return $val;
|
||
}
|
||
function objint($obj, $name, $defvalue = 0) {
|
||
if (!isset($obj[$name]) || $obj[$name] === '')
|
||
return $defvalue;
|
||
return toint($obj[$name]);
|
||
}
|
||
function objfloat($obj, $name, $defvalue = 0.0) {
|
||
if (!isset($obj[$name]))
|
||
return $defvalue;
|
||
return (float)$obj[$name];
|
||
}
|
||
function objdate($obj, $name, $defvalue = 0) {
|
||
if (!isset($obj[$name]))
|
||
return $defvalue;
|
||
$val = $obj[$name];
|
||
if (strpos($val, '-') !== false)
|
||
return strtotime($val);
|
||
return toint($val);
|
||
}
|
||
function get($name, $defvalue = '', $allow = 'text') { //text:仅文本,all:都可以
|
||
if (!isset($_GET[$name]))
|
||
return $defvalue;
|
||
$val = $_GET[$name];
|
||
if ($allow == 'text')
|
||
return strip_tags($val . '');
|
||
return $val;
|
||
}
|
||
function getint($name, $defvalue = 0) {
|
||
if (!isset($_GET[$name]))
|
||
return $defvalue;
|
||
return toint($_GET[$name]);
|
||
}
|
||
function post($name, $defvalue = '', $allow = 'text') { //text:仅文本,all:都可以
|
||
if (!isset($_POST[$name]))
|
||
return $defvalue;
|
||
$val = $_POST[$name];
|
||
if ($allow == 'text')
|
||
return strip_tags($val);
|
||
return $val;
|
||
}
|
||
function request($name, $defvalue = '', $allow = 'text') { //text:仅文本,all:都可以
|
||
if (!isset($_REQUEST[$name]))
|
||
return $defvalue;
|
||
$val = $_REQUEST[$name];
|
||
if ($allow == 'text')
|
||
return strip_tags($val);
|
||
return $val;
|
||
}
|
||
function cookie($name, $defvalue = '', $allow = 'text') { //text:仅文本,all:都可以
|
||
if (!isset($_COOKIE[$name]))
|
||
return $defvalue;
|
||
$val = $_COOKIE[$name];
|
||
if ($allow == 'text')
|
||
return strip_tags($val);
|
||
return $val;
|
||
}
|
||
/**
|
||
* 返回32位int真实IP地址。显示时请用long2ip()函数。
|
||
* $real = true 时,返回字符串ip地址。
|
||
* 数据库ip字段建议设置:int有符号类型(建议);varchar(15);兼容IPv6 varchar(40)
|
||
* 例:getip() = 1343193298 getip(true) = '80.15.128.210'
|
||
* 例:getip() = -765170305 getip(true) = '210.100.109.127'
|
||
* 提示:真实IP地址访问方法有很多种,有些用户会用header伪造真实IP。请根据您的实际服务器集群部署调整本函数。特别是CDN和反向代理部分。
|
||
*/
|
||
function getip() {
|
||
$headers = [
|
||
'HTTP_CF_CONNECTING_IP',
|
||
'HTTP_TRUE_CLIENT_IP',
|
||
'HTTP_X_FORWARDED_FOR',
|
||
'HTTP_FORWARDED',
|
||
'HTTP_X_REAL_IP',
|
||
'HTTP_FORWARDED_FOR',
|
||
'HTTP_X_FORWARDED',
|
||
];
|
||
$ips = array();
|
||
foreach ($headers as $header) {
|
||
if (!empty($_SERVER[$header]))
|
||
$ips[] = strtolower($_SERVER[$header]);
|
||
}
|
||
foreach ($ips as $ip) {
|
||
$ind = strpos($ip, ',');
|
||
if ($ind !== false)
|
||
$ip = substr($ip, 0, $ind);
|
||
$ind = strpos($ip, 'for=');
|
||
if ($ind !== false) {
|
||
$ip = substr($ip, $ind + 4);
|
||
if ($ip[0] == '"') {
|
||
$ip = substr($ip, 1, strpos($ip, '"', 1) - 1);
|
||
$ind = strpos($ip, ']');
|
||
if ($ind !== false)
|
||
$ip = substr($ip, 1, $ind - 1);
|
||
} else if ($ip[0] == '[') {
|
||
$ip = substr($ip, 1, strpos($ip, ']') - 1);
|
||
} else {
|
||
$ind = strpos($ip, ';');
|
||
if ($ind !== false)
|
||
$ip = substr($ip, 0, $ind);
|
||
|
||
if (strpos($ip, '.') !== false) {
|
||
$ind = strpos($ip, ':');
|
||
if ($ind !== false)
|
||
$ip = substr($ip, 0, $ind);
|
||
}
|
||
}
|
||
} else {
|
||
if (strpos($ip, '.') !== false) {
|
||
$ind = strpos($ip, ':');
|
||
if ($ind !== false)
|
||
$ip = substr($ip, 0, $ind);
|
||
}
|
||
}
|
||
if (filter_var($ip, FILTER_VALIDATE_IP, FILTER_FLAG_NO_PRIV_RANGE | FILTER_FLAG_NO_RES_RANGE))
|
||
return $ip;
|
||
}
|
||
if (isset($_SERVER['REMOTE_ADDR']))
|
||
return $_SERVER['REMOTE_ADDR'];
|
||
return '0.0.0.0';
|
||
}
|
||
//循环建立新文件夹
|
||
function dirmake($dir, $power = 0777) {
|
||
if (!$dir)
|
||
return false;
|
||
if (!is_dir($dir)) {
|
||
$ret = mkdir($dir, $power, true);
|
||
if ($ret === false)
|
||
savelogfile('err_file', 'dir make err:' . $dir);
|
||
return $ret;
|
||
}
|
||
return true;
|
||
}
|
||
//静默删除文件
|
||
function filedel($file) {
|
||
try {
|
||
unlink($file);
|
||
} catch (Exception $ex) {
|
||
savelogfile('err_file', 'file del err:' . $file . ':' . $ex->getMessage());
|
||
}
|
||
}
|
||
//静默拷贝文件
|
||
function filecopy($srcfile, $dstfile) {
|
||
try {
|
||
copy($srcfile, $dstfile);
|
||
} catch (Exception $ex) {
|
||
savelogfile('err_file', 'file copy err:' . $srcfile . '->' . $dstfile . ':' . $ex->getMessage());
|
||
}
|
||
}
|
||
//存储文本到文件
|
||
function filesave($filename, $text) {
|
||
if (!$filename || !$text)
|
||
return false;
|
||
if (!dirmake(dirname($filename)))
|
||
return false;
|
||
try {
|
||
if ($fp = fopen($filename, 'w')) {
|
||
if (@fwrite($fp, $text)) {
|
||
fclose($fp);
|
||
return true;
|
||
} else {
|
||
fclose($fp);
|
||
return false;
|
||
}
|
||
}
|
||
} catch (Exception $ex) {
|
||
savelogfile('err_file', 'file save err:' . $filename . ':' . $ex->getMessage());
|
||
}
|
||
return false;
|
||
}
|
||
//读取文本文件
|
||
function fileload($dfile) {
|
||
if (!file_exists($dfile))
|
||
return '';
|
||
try {
|
||
return file_get_contents($dfile);
|
||
} catch (Exception $ex) {
|
||
savelogfile('err_file', 'file load err:' . $dfile . ':' . $ex->getMessage());
|
||
}
|
||
return '';
|
||
}
|
||
//存储文本到文件
|
||
function storsave($filename, $text) {
|
||
if (!$filename || !$text)
|
||
return false;
|
||
$filename = str_replace('{Y}', date('Y'), $filename);
|
||
$filename = str_replace('{m}', date('m'), $filename);
|
||
$filename = str_replace('{d}', date('d'), $filename);
|
||
if (substr($filename, 0, 1) == '/')
|
||
$filename = PATH_WEB . 'ud' . $filename;
|
||
return filesave($filename, $text);
|
||
}
|
||
function webini($section) {
|
||
if (!file_exists(PATH_ROOT . 'web.ini'))
|
||
return 'INI file nofind:' . PATH_ROOT . 'web.ini';
|
||
try {
|
||
$inis = explode("\n", file_get_contents(PATH_ROOT . 'web.ini'));
|
||
$vars = null;
|
||
foreach ($inis as $ini) {
|
||
if (empty($ini))
|
||
continue;
|
||
if (strpos($ini, '[') === 0) {
|
||
$sec = substr($ini, 1, strpos($ini, ']') - 1);
|
||
if ($sec == $section) {
|
||
$vars = array();
|
||
} else if (is_array($vars))
|
||
return $vars;
|
||
} else {
|
||
if (!is_array($vars))
|
||
continue;
|
||
$pos = strpos($ini, '=');
|
||
if ($pos === false)
|
||
continue;
|
||
$key = substr($ini, 0, $pos);
|
||
$val = substr($ini, $pos + 1);
|
||
$vars[$key] = trim($val);
|
||
}
|
||
}
|
||
return 'INI section nofind:' . $section;
|
||
} catch (Exception $ex) {
|
||
return 'INI catch:' . $ex->getMessage();
|
||
}
|
||
return 'INI error';
|
||
}
|
||
/**
|
||
* 下载音视频图片文件到本地
|
||
* url 下载链接地址
|
||
* savepath 保存相对路径。如ud/
|
||
* filename 保存文件名。默认日期文件名
|
||
* timeout 下载超时时间 秒
|
||
*/
|
||
function file_down($url, $savepath, $filename = '', $timeout = 60, $defext = '.jpg') {
|
||
if (!dirmake(PATH_WEB . $savepath))
|
||
return 'ERR:保存目录建立失败';
|
||
$ch = curl_init();
|
||
curl_setopt($ch, CURLOPT_URL, urldecode($url));
|
||
curl_setopt($ch, CURLOPT_TIMEOUT, $timeout);
|
||
curl_setopt($ch, CURLOPT_HEADER, 0);
|
||
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
|
||
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, 0);
|
||
@curl_setopt($ch, CURLOPT_IPRESOLVE, CURL_IPRESOLVE_V4);
|
||
$data = curl_exec($ch);
|
||
if ($data === false || empty($data)) {
|
||
return 'ERR:下载失败';
|
||
}
|
||
$info = curl_getinfo($ch);
|
||
curl_close($ch);
|
||
if (empty($filename))
|
||
$filename = date('Ymd_His_') . rand(1000, 9999);
|
||
$fileext = $defext;
|
||
if ($info['content_type'] == 'image/jpeg')
|
||
$fileext = '.jpg';
|
||
else if ($info['content_type'] == 'image/jpg')
|
||
$fileext = '.jpg';
|
||
else if ($info['content_type'] == 'image/png')
|
||
$fileext = '.png';
|
||
else if ($info['content_type'] == 'image/gif')
|
||
$fileext = '.gif';
|
||
else if ($info['content_type'] == 'audio/amr')
|
||
$fileext = '.amr';
|
||
else if ($info['content_type'] == 'audio/wav')
|
||
$fileext = '.wav';
|
||
else if ($info['content_type'] == 'audio/mpeg')
|
||
$fileext = '.mp3';
|
||
else if ($info['content_type'] == 'audio/ogg')
|
||
$fileext = '.ogg';
|
||
else if ($info['content_type'] == 'image/svg+xml')
|
||
$fileext = '.svg';
|
||
else if ($info['content_type'] == 'image/webp')
|
||
$fileext = '.webp';
|
||
$fp = fopen(PATH_WEB . $savepath . $filename . $fileext, 'w');
|
||
fwrite($fp, $data);
|
||
@fclose($fp);
|
||
return $savepath . $filename . $fileext;
|
||
}
|
||
//文件扩展名 jpg
|
||
function file_ext($file) {
|
||
$ind = strrpos($file, '.');
|
||
if ($ind === false)
|
||
return '';
|
||
return substr($file, $ind + 1);
|
||
}
|
||
function file_stor($url) {
|
||
if (!$url)
|
||
return '';
|
||
if (strtolower(substr($url, 0, 4)) === 'http')
|
||
return $url;
|
||
$cfg = webini('s3' . substr($url, 0, 1));
|
||
return $cfg['url'] . substr($url, 1);
|
||
}
|