shopxo/application/common.php
2018-12-29 13:13:09 +08:00

1104 lines
32 KiB
PHP
Executable File
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
// +----------------------------------------------------------------------
// | ShopXO 国内领先企业级B2C免费开源电商系统
// +----------------------------------------------------------------------
// | Copyright (c) 2011~2018 http://shopxo.net All rights reserved.
// +----------------------------------------------------------------------
// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )
// +----------------------------------------------------------------------
// | Author: Devil
// +----------------------------------------------------------------------
// 应用公共文件
/**
* [FileSizeByteToUnit 文件大小转常用单位]
* @author Devil
* @blog http://gong.gg/
* @version 1.0.0
* @datetime 2018-11-28T01:05:29+0800
* @param [int] $bit [字节数]
*/
function FileSizeByteToUnit($bit)
{
//单位每增大1024则单位数组向后移动一位表示相应的单位
$type = array('Bytes','KB','MB','GB','TB');
for($i = 0; $bit >= 1024; $i++)
{
$bit/=1024;
}
//floor是取整函数为了防止出现一串的小数这里取了两位小数
return (floor($bit*100)/100).$type[$i];
}
/**
* 异步调用方法
* @author Devil
* @blog http://gong.gg/
* @version 1.0.0
* @date 2018-06-11
* @desc 异步运行url地址方法
* @param [string] $url [url地址 支持get参数]
*/
function SyncJob($url, $port = 80, $time = 30)
{
$url_str = str_replace(array('http://', 'https://'), '', $url);
$location = strpos($url_str, '/');
$host = substr($url_str, 0, $location);
$fp = fsockopen($host, $port, $errno, $errstr, $time);
if($fp)
{
$out = "GET ".str_replace($host, '', $url_str)." HTTP/1.1\r\n";
$out .= "Host: ".$host."\r\n";
$out .= "Content-type: application/x-www-form-urlencoded\r\n";
$out .= "Connection: Close\r\n\r\n";
fputs($fp, $out);
fclose($fp);
}
}
/**
* [DataReturn 公共返回数据]
* @author Devil
* @blog http://gong.gg/
* @version 0.0.1
* @datetime 2016-12-07T22:03:40+0800
* @param [string] $msg [提示信息]
* @param [int] $code [状态码]
* @param [mixed] $data [数据]
* @return [json] [json数据]
*/
function DataReturn($msg = '', $code = 0, $data = '')
{
// ajax的时候success和error错误由当前方法接收
if(IS_AJAX)
{
if(isset($msg['info']))
{
// success模式下code=0, error模式下code参数-1
$result = array('msg'=>$msg['info'], 'code'=>-1, 'data'=>'');
}
}
// 默认情况下,手动调用当前方法
if(empty($result))
{
$result = array('msg'=>$msg, 'code'=>$code, 'data'=>$data);
}
// 错误情况下,防止提示信息为空
if($result['code'] != 0 && empty($result['msg']))
{
$result['msg'] = '操作失败';
}
return $result;
}
/**
* 生成url地址
* @author Devil
* @blog http://gong.gg/
* @version 1.0.0
* @date 2018-06-12
* @desc description
* @param string $c [控制器名称]
* @param string $a [方法名称]
* @param array $params [参数]
*/
function MyUrl($path, $params=[])
{
$url = url($path, $params, true, true);
// 是否根目录访问项目
if(defined('IS_ROOT_ACCESS'))
{
$url = str_replace('public/', '', $url);
}
return $url;
}
/**
* [PriceBeautify 金额美化]
* @author Devil
* @blog http://gong.gg/
* @version 1.0.0
* @datetime 2018-04-12T16:54:51+0800
* @param [float] $price [金额]
* @param [mixed] $default [默认值]
*/
function PriceBeautify($price = 0, $default = null)
{
if(empty($price))
{
return $default;
}
$price = str_replace('.00', '', $price);
if(strpos ($price, '.') !== false)
{
if(substr($price, -1) == 0)
{
$price = substr($price, 0, -1);
}
}
return $price;
}
/**
* [FileUploadError 文件上传错误校验]
* @author Devil
* @blog http://gong.gg/
* @version 0.0.1
* @datetime 2017-04-12T17:21:51+0800
* @param [string] $name [表单name]
* @param [int] $index[多文件索引]
* @return [mixed] [true | 错误信息]
*/
function FileUploadError($name, $index = false)
{
// 是否存在该name表单
if($index === false)
{
if(empty($_FILES[$name]))
{
return '请选择需要上传的文件';
}
} else {
if(empty($_FILES[$name]['name'][$index]))
{
return '请选择需要上传的文件';
}
}
// 是否正常
$error = null;
if($index === false)
{
if($_FILES[$name]['error'] == 0)
{
return true;
}
$error = $_FILES[$name]['error'];
} else {
if($_FILES[$name]['error'][$index] == 0)
{
return true;
}
$error = $_FILES[$name]['error'][$index];
}
// 错误码对应的错误信息
$file_error_list = lang('common_file_upload_error_list');
if(isset($file_error_list[$error]))
{
return $file_error_list[$error];
}
return '未知错误'.'[file error '.$error.']';
}
/**
* [LangValueKeyFlip 公共数据翻转]
* @author Devil
* @blog http://gong.gg/
* @version 0.0.1
* @datetime 2017-04-07T11:32:02+0800
* @param [array] $data [需要翻转的数据]
* @param [mixed] $default [默认值]
* @param [string] $value_field [value值字段名称]
* @param [string] $name_field [name值字段名称]
* @return [array] [翻转后的数据]
*/
function LangValueKeyFlip($data, $default = false, $value_field = 'id', $name_field = 'name')
{
$result = array();
if(!empty($data) && is_array($data))
{
foreach($data as $k=>$v)
{
$result[$v[$name_field]] = $v[$value_field];
if(isset($v['checked']) && $v['checked'] == true)
{
$result['default'] = $v[$value_field];
}
}
}
if($default !== false)
{
$result['default'] = $default;
}
return $result;
}
/**
* [ScienceNumToString 科学数字转换成原始的数字]
* @author Devil
* @blog http://gong.gg/
* @version 0.0.1
* @datetime 2017-04-06T17:21:51+0800
* @param [int] $num [科学数字]
* @return [string] [数据原始的值]
*/
function ScienceNumToString($num)
{
if(stripos($num, 'e') === false) return $num;
// 出现科学计数法,还原成字符串
$num = trim(preg_replace('/[=\'"]/','',$num,1),'"');
$result = '';
while($num > 0)
{
$v = $num-floor($num/10)*10;
$num = floor($num/10);
$result = $v.$result;
}
return $result;
}
/**
* [GetClientIP 客户端ip地址]
* @author Devil
* @blog http://gong.gg/
* @version 0.0.1
* @datetime 2017-02-09T12:53:13+0800
* @param [boolean] $long [是否将ip转成整数]
* @return [string|int] [ip地址|ip地址整数]
*/
function GetClientIP($long = false)
{
$onlineip = '';
if(getenv('HTTP_CLIENT_IP') && strcasecmp(getenv('HTTP_CLIENT_IP'), 'unknown'))
{
$onlineip = getenv('HTTP_CLIENT_IP');
} elseif(getenv('HTTP_X_FORWARDED_FOR') && strcasecmp(getenv('HTTP_X_FORWARDED_FOR'), 'unknown'))
{
$onlineip = getenv('HTTP_X_FORWARDED_FOR');
} elseif(getenv('REMOTE_ADDR') && strcasecmp(getenv('REMOTE_ADDR'), 'unknown'))
{
$onlineip = getenv('REMOTE_ADDR');
} elseif(isset($_SERVER['REMOTE_ADDR']) && $_SERVER['REMOTE_ADDR'] && strcasecmp($_SERVER['REMOTE_ADDR'], 'unknown'))
{
$onlineip = $_SERVER['REMOTE_ADDR'];
}
if($long)
{
$onlineip = sprintf("%u", ip2long($onlineip));
}
return $onlineip;
}
/**
* [UrlParamJoin url参数拼接]
* @author Devil
* @blog http://gong.gg/
* @version 0.0.1
* @datetime 2017-01-09T23:33:44+0800
* @param [array] $param [url参数一维数组]
* @return [string] [url参数字符串]
*/
function UrlParamJoin($param)
{
$string = '';
if(!empty($param) && is_array($param))
{
foreach($param as $k=>$v)
{
if(is_string($v))
{
$string .= $k.'='.$v.'&';
}
}
if(!empty($string))
{
$url_model= config('URL_MODEL');
$join_tag = ($url_model == 0 || $url_model == 3) ? '&' : '?';
$string = $join_tag.substr($string, 0, -1);
}
}
return $string;
}
/**
* [MyC 读取站点配置信息]
* @author Devil
* @blog http://gong.gg/
* @version 0.0.1
* @datetime 2016-12-29T17:17:25+0800
* @param [string] $key [索引名称]
* @param [mixed] $default [默认值]
* @param [boolean] $mandatory [是否强制校验值,默认false]
* @return [mixed] [配置信息值,没找到返回null]
*/
function MyC($key, $default = null, $mandatory = false)
{
$data = cache(config('shopxo.cache_common_my_config_key'));
if($mandatory === true)
{
return empty($data[$key]) ? $default : $data[$key];
}
return isset($data[$key]) ? $data[$key] : $default;
}
/**
* [EmptyDir 清空目录下所有文件]
* @author Devil
* @blog http://gong.gg/
* @version 0.0.1
* @datetime 2016-12-21T19:25:57+0800
* @param [string] $dir_path [目录地址]
* @return [boolean] [成功true, 失败false]
*/
function EmptyDir($dir_path)
{
if(is_dir($dir_path))
{
$dn = @opendir($dir_path);
if($dn !== false)
{
while(false !== ($file = readdir($dn)))
{
if($file != '.' && $file != '..')
{
if(!unlink($dir_path.$file))
{
return false;
}
}
}
} else {
return false;
}
}
return true;
}
/**
* [Utf8Strlen 计算符串长度(中英文一致)]
* @author Devil
* @blog http://gong.gg/
* @version 0.0.1
* @datetime 2016-12-13T21:34:09+0800
* @param [string] $string [需要计算的字符串]
* @return [int] [字符长度]
*/
function Utf8Strlen($string = null)
{
preg_match_all("/./us", $string, $match);
return count($match[0]);
}
/**
* [IsMobile 是否是手机访问]
* @author Devil
* @blog http://gong.gg/
* @version 0.0.1
* @datetime 2016-12-05T10:52:20+0800
* @return [boolean] [手机访问true, 则false]
*/
function IsMobile()
{
/* 如果有HTTP_X_WAP_PROFILE则一定是移动设备 */
if(isset($_SERVER['HTTP_X_WAP_PROFILE'])) return true;
/* 此条摘自TPM智能切换模板引擎适合TPM开发 */
if(isset($_SERVER['HTTP_CLIENT']) && 'PhoneClient' == $_SERVER['HTTP_CLIENT']) return true;
/* 如果via信息含有wap则一定是移动设备,部分服务商会屏蔽该信息 */
if(isset($_SERVER['HTTP_VIA']) && stristr($_SERVER['HTTP_VIA'], 'wap') !== false) return true;
/* 判断手机发送的客户端标志,兼容性有待提高 */
if(isset($_SERVER['HTTP_USER_AGENT']))
{
$clientkeywords = array(
'nokia','sony','ericsson','mot','samsung','htc','sgh','lg','sharp','sie-','philips','panasonic','alcatel','lenovo','iphone','ipad','ipod','blackberry','meizu','android','netfront','symbian','ucweb','windowsce','palm','operamini','operamobi','openwave','nexusone','cldc','midp','wap','mobile'
);
/* 从HTTP_USER_AGENT中查找手机浏览器的关键字 */
if(preg_match("/(" . implode('|', $clientkeywords) . ")/i", strtolower($_SERVER['HTTP_USER_AGENT']))) {
return true;
}
}
/* 协议法,因为有可能不准确,放到最后判断 */
if(isset($_SERVER['HTTP_ACCEPT']))
{
/* 如果只支持wml并且不支持html那一定是移动设备 */
/* 如果支持wml和html但是wml在html之前则是移动设备 */
if((strpos($_SERVER['HTTP_ACCEPT'], 'vnd.wap.wml') !== false) && (strpos($_SERVER['HTTP_ACCEPT'], 'text/html') === false || (strpos($_SERVER['HTTP_ACCEPT'], 'vnd.wap.wml') < strpos($_SERVER['HTTP_ACCEPT'], 'text/html')))) return true;
}
return false;
}
/**
* [Is_Json 校验json数据是否合法]
* @author Devil
* @blog http://gong.gg/
* @version 0.0.1
* @datetime 2016-12-03T21:58:54+0800
* @param [string] $jsonstr [需要校验的json字符串]
* @return [boolean] [合法true, 则false]
*/
function Is_Json($jsonstr)
{
if(PHP_VERSION > 5.3)
{
json_decode($jsonstr);
return (json_last_error() == JSON_ERROR_NONE);
} else {
return is_null(json_decode($jsonstr)) ? false : true;
}
}
/**
* [Curl_Post curl模拟post]
* @author Devil
* @blog http://gong.gg/
* @version 0.0.1
* @datetime 2016-12-03T21:58:54+0800
* @param [string] $url [请求地址]
* @param [array] $post [发送的post数据]
*/
function Curl_Post($url, $post)
{
$options = array(
CURLOPT_RETURNTRANSFER => true,
CURLOPT_HEADER => false,
CURLOPT_POST => true,
CURLOPT_POSTFIELDS => $post,
);
$ch = curl_init($url);
curl_setopt_array($ch, $options);
$result = curl_exec($ch);
curl_close($ch);
return $result;
}
/**
* [Fsockopen_Post fsockopen方式]
* @author Devil
* @blog http://gong.gg/
* @version 0.0.1
* @datetime 2016-12-03T21:58:54+0800
* @param [string] $url [url地址]
* @param [string] $data [发送参数]
*/
function Fsockopen_Post($url, $data = '')
{
$row = parse_MyUrl($url);
$host = $row['host'];
$port = isset($row['port']) ? $row['port'] : 80;
$file = $row['path'];
$post = '';
while (list($k,$v) = each($data))
{
if(isset($k) && isset($v)) $post .= rawurlencode($k)."=".rawurlencode($v)."&"; //转URL标准码
}
$post = substr( $post , 0 , -1 );
$len = strlen($post);
$fp = @fsockopen( $host ,$port, $errno, $errstr, 10);
if (!$fp) {
return "$errstr ($errno)\n";
} else {
$receive = '';
$out = "POST $file HTTP/1.0\r\n";
$out .= "Host: $host\r\n";
$out .= "Content-type: application/x-www-form-urlencoded\r\n";
$out .= "Connection: Close\r\n";
$out .= "Content-Length: $len\r\n\r\n";
$out .= $post;
fwrite($fp, $out);
while (!feof($fp)) {
$receive .= fgets($fp, 128);
}
fclose($fp);
$receive = explode("\r\n\r\n",$receive);
unset($receive[0]);
return implode("",$receive);
}
}
/**
* [Xml_Array xml转数组]
* @author Devil
* @blog http://gong.gg/
* @version 0.0.1
* @datetime 2016-12-03T21:58:54+0800
* @param [xml] $xmlstring [xml数据]
* @return [array] [array数组]
*/
function Xml_Array($xmlstring) {
return json_decode(json_encode((array) simplexml_load_string($xmlstring)), true);
}
/**
* [CheckMobile 手机号码格式校验]
* @author Devil
* @blog http://gong.gg/
* @version 0.0.1
* @datetime 2016-12-03T21:58:54+0800
* @param [int] $mobile [手机号码]
* @return [boolean] [正确true失败false]
*/
function CheckMobile($mobile)
{
return (preg_match('/'.lang('common_regex_mobile').'/', $mobile) == 1) ? true : false;
}
/**
* [CheckTel 电话号码格式校验]
* @author Devil
* @blog http://gong.gg/
* @version 0.0.1
* @datetime 2016-12-03T21:58:54+0800
* @param [string] $tel [电话号码]
* @return [boolean] [正确true失败false]
*/
function CheckTel($tel)
{
return (preg_match('/'.lang('common_regex_tel').'/', $tel) == 1) ? true : false;
}
/**
* [CheckEmail 电子邮箱格式校验]
* @author Devil
* @blog http://gong.gg/
* @version 0.0.1
* @datetime 2016-12-03T21:58:54+0800
* @param [string] $email [电子邮箱]
* @return [boolean] [正确true失败false]
*/
function CheckEmail($email)
{
return (preg_match('/'.lang('common_regex_email').'/', $email) == 1) ? true : false;
}
/**
* [CheckIdCard 身份证号码格式校验]
* @author Devil
* @blog http://gong.gg/
* @version 0.0.1
* @datetime 2016-12-03T21:58:54+0800
* @param [string] $number [身份证号码]
* @return [boolean] [正确true失败false]
*/
function CheckIdCard($number)
{
return (preg_match('/'.lang('common_regex_id_card').'/', $number) == 1) ? true : false;
}
/**
* [CheckPrice 价格格式校验]
* @author Devil
* @blog http://gong.gg/
* @version 0.0.1
* @datetime 2016-12-03T21:58:54+0800
* @param [float] $price [价格]
* @return [boolean] [正确true失败false]
*/
function CheckPrice($price)
{
return (preg_match('/'.lang('common_regex_price').'/', $price) == 1) ? true : false;
}
/**
* [CheckIp ip校验]
* @author Devil
* @blog http://gong.gg/
* @version 0.0.1
* @datetime 2016-12-03T21:58:54+0800
* @param [string] $ip [ip]
*/
function CheckIp($ip)
{
return (preg_match('/'.lang('common_regex_ip').'/', $ip) == 1) ? true : false;
}
/**
* [CheckUrl url校验]
* @author Devil
* @blog http://gong.gg/
* @version 0.0.1
* @datetime 2016-12-03T21:58:54+0800
* @param [string] $url [url地址]
*/
function CheckUrl($url)
{
return (preg_match('/'.lang('common_regex_url').'/', $url) == 1) ? true : false;
}
/**
* [CheckUserName 用户名校验]
* @author Devil
* @blog http://gong.gg/
* @version 0.0.1
* @datetime 2016-12-03T21:58:54+0800
* @param [string] $string [用户名]
* @return [boolean] [成功true, 失败false]
*/
function CheckUserName($string)
{
return (preg_match('/'.lang('common_regex_username').'/', $string) == 1) ? true : false;
}
/**
* [CheckSort 排序值校验]
* @author Devil
* @blog http://gong.gg/
* @version 0.0.1
* @datetime 2016-12-03T21:58:54+0800
* @param [int] $value [数据值]
* @return [boolean] [成功true, 失败false]
*/
function CheckSort($value)
{
$temp = intval($value);
return ($temp >= 0 && $temp <= 255);
}
/**
* [CheckColor 颜色值校验]
* @author Devil
* @blog http://gong.gg/
* @version 0.0.1
* @datetime 2016-12-03T21:58:54+0800
* @param [string] $value [数据值]
*/
function CheckColor($value)
{
return (preg_match('/'.lang('common_regex_color').'/', $value) == 1) ? true : false;
}
/**
* [CheckLoginPwd 密码格式校验]
* @author Devil
* @blog http://gong.gg/
* @version 0.0.1
* @datetime 2016-12-03T21:58:54+0800
* @param [string] $string [登录密码]
* @return [boolean] [正确true, 错误false]
*/
function CheckLoginPwd($string)
{
return (preg_match('/'.lang('common_regex_pwd').'/', $string) == 1) ? true : false;
}
/**
* [IsExistRemoteImage 检测一张网络图片是否存在]
* @author Devil
* @blog http://gong.gg/
* @version 0.0.1
* @datetime 2016-12-03T21:58:54+0800
* @param [string] $url [图片地址]
* @return [boolean] [存在true, 则false]
*/
function IsExistRemoteImage($url)
{
if(!empty($url))
{
$content = get_headers($url, 1);
if(!empty($content[0]))
{
return preg_match('/200/',$content[0]);
}
}
return false;
}
/**
* [GetNumberCode 随机数生成生成]
* @author Devil
* @blog http://gong.gg/
* @version 0.0.1
* @datetime 2016-12-03T21:58:54+0800
* @param [int] $length [生成位数]
* @return [int] [生成的随机数]
*/
function GetNumberCode($length = 6)
{
$code = '';
for($i=0; $i<intval($length); $i++) $code .= rand(0, 9);
return $code;
}
/**
* [LoginPwdEncryption 登录密码加密]
* @author Devil
* @blog http://gong.gg/
* @version 0.0.1
* @datetime 2016-12-03T21:58:54+0800
* @param [string] $pwd [需要加密的密码]
* @param [string] $salt [配合密码加密的随机数]
* @return [string] [加密后的密码]
*/
function LoginPwdEncryption($pwd, $salt)
{
return md5($salt.trim($pwd));
}
/**
* [PwdPayEncryption 支付密码加密]
* @author Devil
* @blog http://gong.gg/
* @version 0.0.1
* @datetime 2016-12-03T21:58:54+0800
* @param [string] $pwd [需要加密的密码]
* @param [string] $salt [配合密码加密的随机数]
* @return [string] [加密后的密码]
*/
function PwdPayEncryption($pwd, $salt)
{
return md5(md5(trim($pwd).$salt));
}
/**
* @author Devil
* @blog http://gong.gg/
* @version 0.0.1
* @datetime 2016-12-03T21:58:54+0800
* [PwdStrength 密码强度校验]
* @param [string] $pwd [需要校验的密码]
* @return [int] [密码强度值0~10]
*/
function PwdStrength($pwd)
{
$score = 0;
if(preg_match("/[0-9]+/", $pwd)) $score ++;
if(preg_match("/[0-9]{3,}/", $pwd)) $score ++;
if(preg_match("/[a-z]+/", $pwd)) $score ++;
if(preg_match("/[a-z]{3,}/", $pwd)) $score ++;
if(preg_match("/[A-Z]+/", $pwd)) $score ++;
if(preg_match("/[A-Z]{3,}/", $pwd)) $score ++;
if(preg_match("/[_|\-|+|=|*|!|@|#|$|%|^|&|(|)]+/", $pwd)) $score += 2;
if(preg_match("/[_|\-|+|=|*|!|@|#|$|%|^|&|(|)]{3,}/", $pwd)) $score ++ ;
if(strlen($pwd) >= 10) $score ++;
return $score;
}
/**
* @author Devil
* @blog http://gong.gg/
* @version 0.0.1
* @datetime 2016-12-03T21:58:54+0800
* $lng = '116.655540';
* $lat = '39.910980';
* $squares = returnSquarePoint($lng, $lat);
*
* print_r($squares);
* $info_sql = "select id,locateinfo,lat,lng from `lbs_info` where lat<>0 and lat>{$squares['right-bottom']['lat']} and lat<{$squares['left-top']['lat']} and lng>{$squares['left-top']['lng']} and lng<{$squares['right-bottom']['lng']} ";
* 计算某个经纬度的周围某段距离的正方形的四个点
*
* param lng float 经度
* param lat float 纬度
* param Distance float 该点所在圆的半径该圆与此正方形内切默认值为0.5千米
* return array 正方形的四个点的经纬度坐标
*/
function ReturnSquarePoint($lng, $lat, $Distance = 1.2)
{
/* 地球半径平均半径为6371km */
$Radius = 6371;
$d_lng = 2 * asin(sin($Distance / (2 * $Radius)) / cos(deg2rad($lat)));
$d_lng = rad2deg($d_lng);
$d_lat = $Distance/$Radius;
$d_lat = rad2deg($d_lat);
return array(
'left-top'=>array('lat'=>$lat + $d_lat,'lng'=>$lng-$d_lng),
'right-top'=>array('lat'=>$lat + $d_lat, 'lng'=>$lng + $d_lng),
'left-bottom'=>array('lat'=>$lat - $d_lat, 'lng'=>$lng - $d_lng),
'right-bottom'=>array('lat'=>$lat - $d_lat, 'lng'=>$lng + $d_lng)
);
}
/**
* [Authcode 明文或密文]
* @author Devil
* @blog http://gong.gg/
* @version 0.0.1
* @datetime 2016-12-03T21:58:54+0800
* @param [string] $string [明文或密文]
* @param [string] $operation [加密ENCODE, 解密DECODE]
* @param [string] $key [密钥]
* @param [integer] $expiry [密钥有效期]
* @return [string] [加密或解密后的数据]
*/
function Authcode($string, $operation = 'DECODE', $key = '', $expiry = 0) {
// 动态密匙长度,相同的明文会生成不同密文就是依靠动态密匙
// 加入随机密钥,可以令密文无任何规律,即便是原文和密钥完全相同,加密结果也会每次不同,增大破解难度。
// 取值越大,密文变动规律越大,密文变化 = 16 的 $ckey_length 次方
// 当此值为 0 时,则不产生随机密钥
$ckey_length = 4;
// 密匙
// $GLOBALS['discuz_auth_key'] 这里可以根据自己的需要修改
$key = md5($key ? $key : 'devil');
// 密匙a会参与加解密
$keya = md5(substr($key, 0, 16));
// 密匙b会用来做数据完整性验证
$keyb = md5(substr($key, 16, 16));
// 密匙c用于变化生成的密文
$keyc = $ckey_length ? ($operation == 'DECODE' ? substr($string, 0, $ckey_length): substr(md5(microtime()), -$ckey_length)) : '';
// 参与运算的密匙
$cryptkey = $keya.md5($keya.$keyc);
$key_length = strlen($cryptkey);
// 明文前10位用来保存时间戳解密时验证数据有效性10到26位用来保存$keyb(密匙b),解密时会通过这个密匙验证数据完整性
// 如果是解码的话,会从第$ckey_length位开始因为密文前$ckey_length位保存 动态密匙,以保证解密正确
$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') {
// substr($result, 0, 10) == 0 验证数据有效性
// substr($result, 0, 10) - time() > 0 验证数据有效性
// substr($result, 10, 16) == substr(md5(substr($result, 26).$keyb), 0, 16) 验证数据完整性
// 验证数据有效性,请看未加密明文的格式
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 {
// 把动态密匙保存在密文里,这也是为什么同样的明文,生产不同密文后能解密的原因
// 因为加密后的密文可能是一些特殊字符复制过程可能会丢失所以用base64编码
return $keyc.str_replace('=', '', base64_encode($result));
}
}
/**
* [SS 设置缓存]
* @author Devil
* @blog http://gong.gg/
* @version 1.0.0
* @datetime 2017-09-24T19:01:00+0800
* @param [string] $key [缓存key]
* @param [mixed] $data [需要存储的数据]
* @return [boolean] [成功true, 失败false]
*/
function SS($key, $data)
{
if(empty($key) || empty($data))
{
return false;
}
$data['cache_time'] = time();
return cache($key, $data);
}
/**
* [GS 获取缓存]
* @author Devil
* @blog http://gong.gg/
* @version 1.0.0
* @datetime 2017-09-24T18:54:54+0800
* @param [string] $key [缓存key]
* @param [integer] $expires_time [默认过期时间0长期有效单位秒]
* @param [boolean] $is_filem_time [是否返回文件上一次更新时间]
* @return [boolean|mixed] [没数据false, 则数据]
*/
function GS($key, $expires_time = 0, $is_filem_time = false)
{
if(empty($key))
{
return false;
}
$data = cache($key);
if($data !== null)
{
$expires_time = intval($expires_time);
if($expires_time > 0)
{
if($data['cache_time']+$expires_time < time())
{
return false;
}
}
return $data;
}
return false;
}
/**
* [DS 删除缓存]
* @author Devil
* @blog http://gong.gg/
* @version 1.0.0
* @datetime 2017-09-24T19:01:00+0800
* @param [string] $key [缓存key]
* @return [boolean] [成功true, 失败false]
*/
function DS($key)
{
return cache($key, null);
}
/**
* [ParamsChecked 参数校验方法]
* @author Devil
* @blog http://gong.gg/
* @version 1.0.0
* @datetime 2017-12-12T15:26:13+0800
* @param [array] $data [原始数据]
* @param [array] $params [校验数据]
* @return [boolean|string] [成功true, 失败 错误信息]
*/
function ParamsChecked($data, $params)
{
if (empty($params) || !is_array($data) || !is_array($params))
{
return '内部调用参数配置有误';
}
foreach ($params as $v)
{
if (empty($v['key_name']) || empty($v['error_msg']))
{
return '内部调用参数配置有误';
}
// 是否需要验证
$is_checked = true;
// 数据或字段存在则验证
// 1 数据存在则验证
// 2 字段存在则验证
if(isset($v['is_checked']))
{
if($v['is_checked'] == 1)
{
if(empty($data[$v['key_name']]))
{
$is_checked = false;
}
} else if($v['is_checked'] == 2)
{
if(!isset($data[$v['key_name']]))
{
$is_checked = false;
}
}
}
// 是否需要验证
if($is_checked === false)
{
continue;
}
// 验证规则默认isset
$checked_type = isset($v['checked_type']) ? $v['checked_type'] : 'isset';
switch($checked_type)
{
// 是否存在
case 'isset' :
if (!isset($data[$v['key_name']]))
{
return $v['error_msg'];
}
break;
// 是否为空
case 'empty' :
if (empty($data[$v['key_name']]))
{
return $v['error_msg'];
}
break;
// 是否存在于验证数组中
case 'in' :
if (empty($v['checked_data']) || !is_array($v['checked_data']))
{
return '内部调用参数配置有误';
}
if (!isset($data[$v['key_name']]) || !in_array($data[$v['key_name']], $v['checked_data']))
{
return $v['error_msg'];
}
break;
// 是否为数组
case 'is_array' :
if (!isset($data[$v['key_name']]) || !is_array($data[$v['key_name']]))
{
return $v['error_msg'];
}
break;
// 长度
case 'length' :
if(!isset($v['checked_data']))
{
return '长度规则值未定义';
}
if(!is_string($v['checked_data']))
{
return '内部调用参数配置有误';
}
if(!isset($data[$v['key_name']]))
{
return $v['error_msg'];
}
$length = mb_strlen($data[$v['key_name']], 'utf-8');
$rule = explode(',', $v['checked_data']);
if(count($rule) == 1)
{
if($length > intval($rule[0]))
{
return $v['error_msg'];
}
} else {
if($length < intval($rule[0]) || $length > intval($rule[1]))
{
return $v['error_msg'];
}
}
break;
// 自定义函数
case 'fun' :
if (empty($v['checked_data']) || !function_exists($v['checked_data']))
{
return '验证函数为空或函数未定义';
}
$fun = $v['checked_data'];
if(!$fun($data[$v['key_name']]))
{
return $v['error_msg'];
}
break;
}
}
return true;
}
?>