Initial commit,修正

This commit is contained in:
2025-07-13 19:37:38 +08:00
parent 38ce288e27
commit 65bbd06981
12384 changed files with 3985464 additions and 8 deletions
+339
View File
@@ -0,0 +1,339 @@
<?php
/**
* @author Fm453
* @site www.hiluker.com
* @remark:接口通信证书处理
*/
defined('HI_FM') or exit("Access Denied");
fm_load()->fm_func('fm');
fm_load()->fm_func('file');
//判断某用户证书是否存在
/*
@username 用户名
*/
function fmFunc_cert_exist($username)
{
global $_GPC;
global $_HI;
global $_FM;
$file = $_HI['apiCertPath'].$username.'.php';
if(file_exists($file)){
$cert = require($file);
return $cert;
}
return false;
}
//登陆前,根据来路判断访问是否合规
/*
@username 用户名
@ip 来路IP
@domain 来路域名
*考虑到CDN加速导致IP变化的原因,域名或IP有一个符合规则即可
*/
function fmFunc_cert_beforeLogin($cert,$ip,$domain)
{
global $_GPC;
global $_HI;
global $_FM;
if(!is_array($cert) && !empty($cert)){
//未引入证书时,不判断
return true;
}elseif(empty($ip) && empty($domain)){
//ip与domain均未传入时,不判断
return true;
}
$ips = isset($cert['suIp']) ? $cert['suIp'] : false;
$domains = isset($cert['suDomain']) ? $cert['suDomain'] : false;
$username = isset($cert['api']) ? $cert['api'] : false;
if(!$ips || !$domains || !$username){
//没有有效的证书配置时,不判断
return true;
}
//为fm453本地开发放行,为公共密钥publicapi放行
if($username == 'vcms.localhost' || $username == 'publicapi') {
return true;
}
//判断ip与domain的合法性
if(!in_array($ip,$ips) && !in_array($domain,$domains)){
return false;
}
return true;
}
//登陆后,更新证书
/*
*有则更新,无则创建
*/
function fmFunc_cert_afterLogin(){
global $_GPC;
global $_HI;
global $_FM;
if(!isset($_FM['user']['name'])){
return false;
}
$_FM['viaDomain'] = isset($_FM['viaDomain']) ? $_FM['viaDomain'] : fmFunc_server_via_domain();
$_FM['viaIp'] = isset($_FM['viaIp']) ? $_FM['viaIp'] : fmFunc_server_via_ip();
$connection = yii::$app->db;
//客户侧是否请求刷新token;否,则直接取token值后返回(应对同一账号同一站点多模块使用的情况)(同一账号,同一站点对应同一token;同一账号可拥有多个token)
if(!isset($_GET['refreshToken']) || empty($_GET['refreshToken'])){
$sql = "SELECT `accesstoken` FROM c_access WHERE username = :username AND ip = :ip AND domain = :domain ORDER BY id ASC";
$params = array();
$params[':username'] = $_FM['user']['name'];
$params[':ip'] = $_FM['viaIp'];
$params[':domain'] = $_FM['viaDomain'];
//$AccessToken = fmFunc_pdo_yii_fetchcolumn($connection,$sql, $params);
$AccessToken = fmFunc_pdo_yii_fetchcolumn($connection,$table='c_access', $column='accesstoken', $conditions = 'username = :username AND ip = :ip AND domain = :domain ORDER BY id ASC', $params);
$_FM['token'] = $AccessToken;
//cert证书文件
//如果没有,创建之;如果有,更新其中的token
$username = $_FM['user']['name'];
$cert = fmFunc_cert_exist($username);
if(!$cert){
$cert = array();
$cert['id'] = $_FM['user']['uid'];
$cert['siteId'] = $_FM['timestamp'];
$cert['suIp'] = array($_FM['viaIp']);
$cert['siteName'] = '';
$cert['suDomain'] = array($_FM['viaDomain']);
$cert['siteUrl'] = '';
$cert['api'] = $username;
$cert['code'] = '';
$cert['token'] = $AccessToken;
$cert['status'] = '0';
$cert['remark'] = '新创建待审核,创建时间:'.date('Y-m-d H:i:s',$_FM['timestamp']);
}
$_FM['apiCert'] = $cert;
fmFunc_cert_write($username,$cert);
if($AccessToken) {
return;
}
}
//生成一个新AccssToken
/*
*生成方法:
@md5: 用户名username+编码useruid+当前时间戳timestamp+失效时间expiretime+随机混淆码randchars 拼接
*/
$randchars = randchars(5);
$content = array();
$content[] = $_FM['user']['name'];
$content[] = $_FM['user']['uid'];
$content[] = $_FM['timestamp'];
$content[] = $expiretime = 3600 * 24 * 30;
$content[] = $randchars;
$_content = iserializer($content);
$AccessToken = md5($_content);
$_FM['token'] = $AccessToken;
//在c_access表中记录登陆对应的有效token
$initdata = array();
$initdata['accesstoken'] = $AccessToken;
$initdata['updatetime'] = $_FM['timestamp'];
$initdata['expiretime'] = $_FM['timestamp']+$expiretime;
$initdata['hashchars'] = $randchars;
$sql = "SELECT `id` FROM c_access WHERE username = :username AND ip = :ip AND domain = :domain ORDER BY id ASC";
$params = array();
$params[':username'] = $_FM['user']['name'];
$params[':ip'] = $_FM['viaIp'];
$params[':domain'] = $_FM['viaDomain'];
$hasId = fmFunc_pdo_yii_fetch($connection,$sql, $params);
if($hasId) {
$condition = 'username = :username AND ip = :ip AND domain = :domain';
fmFunc_pdo_yii_update($connection, 'c_access', $initdata, $condition, $params);
}else{
$initdata['username'] = $_FM['user']['name'];
$initdata['uid'] = $_FM['user']['uid'];
$initdata['userType'] = 2; //客户系统侧的用户登陆,统一归为user类型(接口使用者)
$initdata['ip'] = $_FM['viaIp'];
$initdata['domain'] = $_FM['viaDomain'];
$initdata['data'] = $_content;
$initdata['create_time'] = date('y-m-d H:i:s',$_FM['timestamp']);
fmFunc_pdo_yii_insert($connection, 'c_access', $initdata);
}
//cert证书文件进一步校验
//如果没有,创建之;如果有,更新其中的token
$username = $_FM['user']['name'];
$cert = fmFunc_cert_exist($username);
if(!$cert){
$cert = array();
$cert['id'] = $_FM['user']['uid'];
$cert['siteId'] = $_FM['timestamp'];
$cert['suIp'] = array($_FM['viaIp']);
$cert['siteName'] = '';
$cert['suDomain'] = array($_FM['viaDomain']);
$cert['siteUrl'] = '';
$cert['api'] = $username;
$cert['code'] = '';
$cert['token'] = $AccessToken;
$cert['status'] = '0';
$cert['remark'] = '新创建待审核,创建时间:'.date('Y-m-d H:i:s',$_FM['timestamp']);
}elseif(is_array($cert)){
$cert['token'] = $AccessToken;
$cert['updatetime'] = '更新时间:'.date('Y-m-d H:i:s',$_FM['timestamp']);
}
fmFunc_cert_write($username,$cert);
}
//为指定用户写证书
/*
@username 用户名
@cert 证书内容
*/
function fmFunc_cert_write($username,$cert)
{
global $_GPC;
global $_HI;
global $_FM;
if(!$username){
return false;
}
$file = $_HI['apiCertPath'].$username.'.php';
$content = "<?php";
$content .= "\r\n";
$content .= "/*";
$content .= "\r\n";
$content .= "* 通讯证书文件";
$content .= "\r\n";
$content .= "@status 站点状态,-1禁止 0只读 1可用";
$content .= "\r\n";
$content .= "@siteId 站点ID";
$content .= "\r\n";
$content .= "@suIp 允许访问的IP";
$content .= "\r\n";
$content .= "@suDomain 允许访问的域名";
$content .= "\r\n";
$content .= "@api 接口用户名(站点用户名)";
$content .= "\r\n";
$content .= "@code 用户授权码";
$content .= "\r\n";
$content .= "@token 接口通讯的accesstoken文件";
$content .= "\r\n";
$content .= "*/";
$content .= "\r\n";
$content .= "\$cert = array();";
$content .= "\r\n";
foreach($cert as $k=>$v){
if(!is_array($v)) {
$content .= "\$cert['".$k."'] = '".(string)$v."';";
}else{
$content .= "\$cert['".$k."'] = array(";
$len = count($v);
for($i = $len;$i>0;$i--){
if($i>1) {
$content .= "'".(string)$v[$i-1]."',";
}elseif($i==1) {
$content .= "'".(string)$v[$i-1]."'";
}
}
$content .= ");";
}
$content .= "\r\n";
}
$content .= "return \$cert;";
$content .= "\r\n";
fmFunc_file_write($file,$content);
}
/*__________________________________________________*/
//根据请求数据返回通讯授权结果(0为正常,>0表示错误代码)
/*
*判断机制:
(1)get方式接收到username与accesstoken,判断是否匹配
(2)username对应的证书文件是否存在
(3)根据证书检测是否合规的访问
*/
function fmFunc_cert_checkAuth(){
global $_GPC;
global $_HI;
global $_FM;
//检查appid
if(!isset($_FM['get']['appid'])){
return 45300205; //未指定有效的appid
}elseif(empty($_FM['get']['appid'])){
return 45300205; //未指定有效的appid
}
//检查accesstoken
if(!isset($_FM['get']['accesstoken'])){
return 45300204; //未指定有效的accesstoken
}elseif(empty($_FM['get']['accesstoken'])){
return 45300204; //未指定有效的accesstoken
}
//检查appid与accesstoken是否匹配
$username = $_FM['get']['appid'];
$accesstoken = $_FM['get']['accesstoken'];
$connection = yii::$app->db;
$sql = "SELECT `id` FROM c_access WHERE username = :username AND accesstoken = :accesstoken ";
$params = array();
$params[':username'] = $username;
$params[':accesstoken'] = $accesstoken;
$hasId = fmFunc_pdo_yii_fetch($connection,$sql, $params);
if(!$hasId){
return 45300206; //不匹配
}
//设置用户为登陆状态
$_FM['user']['name'] = $username;
// 使用指定用户名获取用户身份实例
$User = new common\models\User;
$identity = $User->findOne(['username' => $_FM['user']['name']]);
$_FM['user']['uid'] = $identity->id;
// 登录用户,有效期30d
$duration = 3600 * 24 * 30;
Yii::$app->user->login($identity, $duration);
//查询服务器证书
$cert = fmFunc_cert_exist($username);
if(!$cert){
return 45300104; //未查询到服务器证书
}
//检查证书有效性
$ips = isset($cert['suIp']) ? $cert['suIp'] : false;
$domains = isset($cert['suDomain']) ? $cert['suDomain'] : false;
$api = (isset($cert['api']) && !empty($cert['api'])) ? $cert['api'] : false;
if((!$ips && !$domains) || !$api){
return 45300105; //无效的证书
}
//来路域名与IP
$_FM['viaDomain'] = isset($_FM['viaDomain']) ? $_FM['viaDomain'] : fmFunc_server_via_domain();
$_FM['viaIp'] = isset($_FM['viaIp']) ? $_FM['viaIp'] : fmFunc_server_via_ip();
//为fm453本地开发放行,为公共密钥publicapi放行,其他来路均需判断合法性
if($username != 'vcms.localhost' && $username != 'publicapi') {
//判断ip与domain的合法性
if(!in_array($_FM['viaIp'],$ips) && !in_array($_FM['viaDomain'],$domains)){
return 45300101; //来源IP或域名不在白名单中
}
}
$_FM['apiCert'] = $cert;
return 0;
}
+253
View File
@@ -0,0 +1,253 @@
<?php
/**
* @author Fm453
* @site www.hiluker.com
* @remark:文件处理
*/
defined('HI_FM') or exit("Access Denied");
global $_GPC;
global $_HI;
global $_FM;
fm_load()->fm_func('fm');
$_HI['setting']['filemode'] = 0777; //该数字不可加引号
//判断文件是否存在
/*
@filename 文件名
@route 相对于yii安装根目录的路径
*/
function fmFunc_file_checkExist($filename,$route)
{
global $_FM;
$file = $route.$filename;
$file = FM_YII_ROOT.$file;
if(file_exists($file)){
return true;
}
return false;
}
//创建目录
/*
@path 文件目录
*/
function fmFunc_file_mkdirs($path)
{
if (!is_dir($path)) {
fmFunc_file_mkdirs(dirname($path));
mkdir($path);
}
return is_dir($path);
}
//写文件
/*
@filename 文件名
@data 要写入的数据
*/
function fmFunc_file_write($filename,$data)
{
global $_GPC;
global $_HI;
global $_FM;
fmFunc_file_mkdirs(dirname($filename));
file_put_contents($filename, $data);
@chmod($filename, $_HI['setting']['filemode']);
return is_file($filename);
}
//读文件
/*
@filename 完整文件名
*/
function fmFunc_file_read($filename)
{
global $_FM;
$filename = FM_YII_ROOT.$filename;
if (!is_file($filename)) {
return false;
}
return file_get_contents($filename);
}
//移动文件
/*
@filename 完整文件名
@destination 要移入的目标路径
*/
function fmFunc_file_move($filename,$destination)
{
global $_GPC;
global $_HI;
global $_FM;
$filename = FM_YII_ROOT.$filename;
fmFunc_file_mkdirs(dirname($dest));
if (is_uploaded_file($filename)) {
move_uploaded_file($filename, $dest);
} else {
rename($filename, $destination);
}
@chmod($filename, $_HI['setting']['filemode']);
return is_file($destination);
}
//复制文件
/*
@src 源文件(要被复制的文件)
@des 目标文件
@filter 过滤器
*/
function fmFunc_file_copy($src, $des, $filter)
{
global $_FM;
$dir = opendir($src);
@mkdir($des);
while (false !== ($file = readdir($dir))) {
if (($file != '.') && ($file != '..')) {
if (is_dir($src . '/' . $file)) {
fmFunc_file_copy($src . '/' . $file, $des . '/' . $file, $filter);
} elseif (!in_array(substr($file, strrpos($file, '.') + 1), $filter)) {
copy($src . '/' . $file, $des . '/' . $file);
}
}
}
closedir($dir);
}
//删除目录
/*
@path 文件目录
@clean 是否清空
*/
function fmFunc_file_rmdirs($path, $clean = false)
{
if (!is_dir($path)) {
return false;
}
$files = glob($path . '/*');
if ($files) {
foreach ($files as $file) {
is_dir($file) ? fmFunc_file_rmdirs($file) : @unlink($file);
}
}
return $clean ? true : @fmFunc_file_rmdir($path);
}
//删除指定文件(永久删除)
/*
@file 文件名(含路径)
*/
function fmFunc_file_delete($file) {
if (empty($file)) {
return FALSE;
}
if (file_exists($file)) {
@unlink($file);
}
if (file_exists(FM_YII_ROOT . '/' . $file)) {
@unlink(FM_YII_ROOT . '/' . $file);
}
return TRUE;
}
//列出目录树
/*
@path 文件目录
@include 文件名中包含的某些特定元素
*/
function fmFunc_file_tree($path, $include = array()) {
$files = array();
if (!empty($include)) {
$ds = glob($path . '/{' . implode(',', $include) . '}', GLOB_BRACE);
} else {
$ds = glob($path . '/*');
}
if (is_array($ds)) {
foreach ($ds as $entry) {
if (is_file($entry)) {
$files[] = $entry;
}
if (is_dir($entry)) {
$rs = fmFunc_file_tree($entry);
foreach ($rs as $f) {
$files[] = $f;
}
}
}
}
return $files;
}
//文件随机命名
/*
@dir 文件目录
@ext 文件扩展名
*/
function fmFunc_file_randomName($dir, $ext) {
do {
$filename = random(32) . '.' . $ext;
} while (file_exists($dir . $filename));
return $filename;
}
/*______________________________________数据文件类操作______________________________*/
//写数据文件(data目录)
/*
@filename PHP文件名
@route 相对于数据根目录data的路径
@data 要写入的数据
*/
function fmFunc_file_dataWrite($filename,$data,$uri=null,$origin_cache_key=null)
{
global $_FM;
$filelink = 'data/';
$file = $filelink.$filename;
$file = FM_YII_ROOT.$file;
$file = $file.'.php';
// 在数据目录中添加一个文件并写入内容信息
$content = "<?php";
$content .= "\r\n";
$content .= "/*";
$content .= "\r\n";
if($uri) {
$content .= "* @url 请求源:".$uri;
$content .= "\r\n";
}
if($origin_cache_key) {
$content .= "* @key 关联键:".$origin_cache_key;
$content .= "\r\n";
$content .= "* @checkmd5 文件名校验:".md5($origin_cache_key);
$content .= "\r\n";
}
$content .= "*/";
$content .= "\r\n";
$content .= "\$FmApiDataCache = '';";
$content .= "\r\n";
$content .= "\$FmApiDataCache = ";
$content .= "'".$data."'"; //写入前已经进行序列化操作,以便能存储各种类型的数据
$content .= ";";
fmFunc_file_write($file,$content);
}
function fmFunc_file_dataLoad($filename)
{
global $_FM;
$filelink = 'data/';
$file = $filelink.$filename;
$file = FM_YII_ROOT.$file;
require $file;;
$data = htmlspecialchars(iunserializer($FmApiDataCache));
return $data;
}
+136
View File
@@ -0,0 +1,136 @@
<?php
/**
* @author Fm453
* @remark Api站公用函数
*/
defined('HI_FM') or exit("Access Denied");
function getMillisecond(){
//获取毫秒级时间
list($t1,$t2) = explode(' ',microtime());
return (float)sprintf('%.f',(floatval($t1) + floatval($t2))*1000);
}
//手机号掩码
function mobile_mask($mobile) {
return substr($mobile, 0, 3) . '****' . substr($mobile, 7);
}
//银行卡号加空格隔断
function bankcard_space($cardnumber){
$card ='';
for($i=0; $i<5; $i++){
$card = $card. substr($cardnumber,4*$i,4). ' ';
}
return $card;
}
//PHP stdClass Object转array
if(!function_exists('fm_object2array')){
function fm_object2array($array) {
if(is_object($array)) {
$array = (array)$array;
}
if(is_array($array)) {
foreach($array as $key=> &$value) {
if(is_object($value)) {
$value = (array)$value;
}
if(is_array($value)){
foreach($value as $k => &$v){
$value[$k] = fm_object2array($v);
}
}
$array[$key] = $value;
}
}
return $array;
}
}
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_callback('!s:(\d+):"(.*?)";!s', function ($matchs){
return 's:'.strlen($matchs[2]).':"'.$matchs[2].'";';
}, $value);
return unserialize($temp);
}
return $result;
}
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;
}
//生成不重复的随机字符串
function randchars($len)
{
$chars='ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyz';
$string=time();
for(;$len>=1;$len--)
{
$position=rand()%strlen($chars);
$position2=rand()%strlen($string);
$string=substr_replace($string,substr($chars,$position,1),$position2,0);
}
return $string;
}
+403
View File
@@ -0,0 +1,403 @@
<?php
defined('HI_FM') or exit("Access Denied");
/*
针对YII写的常用PDO封装,用于单独指派其他数据库的时候
*/
/*
* 根据配置,创建连接(使用yii的链接方式)
* 返回一个可用的连接
*/
function fmFunc_dbconn_yii($data=null)
{
if(is_array($data)){
$host = $data['host'];
if(isset($data['port'])) {
if(!empty($data['port'])) {
$port = $data['port'];
}
}else{
$port = "3306";
}
$dbname = $data['database'];
$dsn = "mysql:host={$host};port={$port};dbname={$dbname}";
$username = $data['username'];
$password = $data['password'];
$charset = $data['charset'];
$connection = new yii\db\Connection([
'dsn' => $dsn,
'username' => $username,
'password' => $password,
'charset' => $charset,
'tablePrefix' => $data['tablepre'],
]);
}else{
$connection = yii::$app->db;
}
return $connection;
}
/*
* 取PDO
*/
function fmFunc_pdo_yii($dbconn=null)
{
static $pdo;
if(!$dbconn){
$dbconn = yii::$app->db;
}
$dbconn->open();
$pdo = $dbconn->getMasterPdo();
return $pdo;
}
/*
* 根据条件包装自有类FMDB的PDO的sql操作
*/
/*
* query查询操作,执行而不一定返回数据
*/
function fmFunc_pdo_yii_query($connection,$sql, $params = array()) {
$command = $connection->createCommand($sql);
if(!empty($params) && is_array($params)){
foreach($params as $p=>$v){
$command->bindValue($p, $v);
}
}
$result = $command->query();
return $result;
}
/*
* 查找单行数据
*/
function fmFunc_pdo_yii_fetch($connection,$sql, $params = array()) {
$command = $connection->createCommand($sql);
if(!empty($params) && is_array($params)){
foreach($params as $p=>$v){
$command->bindValue($p, $v);
}
}
$result = $command->queryOne();
return $result;
}
/*
* 查找全部匹配行
*/
function fmFunc_pdo_yii_fetchall($connection,$sql, $params = array()) {
$command = $connection->createCommand($sql);
if(!empty($params) && is_array($params)){
foreach($params as $p=>$v){
$command->bindValue($p, $v);
}
}
return $command->queryAll();
}
/*
* 查找第一列数据
@table, 使用绝对表名(有前缀的情况下需要直接写在表名上)
@column 要查询的字段列
@conditions 附加条件(用于条件筛选,sql中where的条件部分)
@params 要绑定到附加条件的参数
*/
function fmFunc_pdo_yii_fetchcolumn($connection,$table, $column, $conditions = '', $params = array()) {
$fields = "`".$column."`";
$sql = " SELECT ".$fields." FROM ".$table." WHERE ".$conditions;
$command = $connection->createCommand($sql);
if(!empty($params) && is_array($params)){
foreach($params as $p=>$v){
$command->bindValue($p, $v);
}
}
$result = $command->queryColumn();
if($result) {
return $result[0];
}else{
return $result;
}
}
/*
* 取指定表单行数据
@table, 使用绝对表名(有前缀的情况下需要直接写在表名上)
@columns 要取的列(字段名组合的数组)
@conditions 附加条件(用于条件筛选,sql中where的条件部分)
@params 要绑定到附加条件的参数
@limits 截断操作(数组)(开始位置,结束位置)(如:start=>0,end=>3)
*/
function fmFunc_pdo_yii_get($connection, $table, $columns = array(), $conditions = '', $params = array(), $limits = array()) {
$fields = '*';
if(!empty($columns) && is_array($columns)) {
$fields = '';
$i = count($columns);
foreach($columns as $k=>$v){
$i --;
if($i==0){
$fields .="`".$v."`";
}else{
$fields .="`".$v."`,";
}
}
}
$sql = " SELECT ".$fields." FROM ".$table." WHERE ".$conditions;
$_limit = "";
if(!empty($limits) && is_array($limits)){
$limits['start'] = isset($limits['start']) ? intval($limits['start']) : 0;
$limits['end'] = $limits['start']+1;
$_limit = " LIMIT ".$limits['start'].", ".$limits['end'];
}
$_order = "";
$orders = array(
'displayorder' => 'DESC',
'id' => 'DESC',
);
if(!empty($orders) && is_array($orders)){
$order = "";
$i = count($orders);
foreach($orders as $p=>$v){
$i--;
if($i==0){
$order .= " `".$p."` ". strtoupper($v) ."";
}else{
$order .= " `".$p."` ". strtoupper($v) .",";
}
}
$_order = " ORDER BY ".$order;
}
$sql = $sql.$_order.$_limit;
$command = $connection->createCommand($sql);
if(!empty($params) && is_array($params)){
foreach($params as $p=>$v){
$command->bindValue($p, $v);
}
}
$result = $command->queryOne();
return $result;
}
/*
* 取指定表多行数据
@table, 使用绝对表名(有前缀的情况下需要直接写在表名上)
@columns 要取的列(字段名组合的数组)
@conditions 附加条件(用于条件筛选,sql中where的条件部分)
@params 要绑定到附加条件的参数
@limits 截断操作(数组)(开始位置,结束位置)(如:start=>0,end=>3)
@orders 排序操作(数组)(字段名=>排序方法)
*/
function fmFunc_pdo_yii_getall($connection, $table, $columns = array(), $conditions = '', $params = array(), $limits = array(), $orders=array()) {
$fields = '*';
if(!empty($columns) && is_array($columns)){
$fields = '';
$i = count($columns);
foreach($columns as $k=>$v){
$i--;
if($i==0){
$fields .="`".$v."`";
}else{
$fields .="`".$v."`,";
}
}
}
$sql = " SELECT ".$fields." FROM ".$table." WHERE ".$conditions;
$_limit = "";
if(!empty($limits) && is_array($limits)){
$limits['start'] = isset($limits['start']) ? intval($limits['start']) : 0;
$limits['end'] = isset($limits['end']) ? intval($limits['end']) : 0;
$limits['end'] = ($limits['end'] > $limits['start']) ? $limits['end'] : $limits['start']+1;
$_limit = " LIMIT ".$limits['start'].", ".$limits['end'];
}
$_order = "";
if(empty($orders)){
$orders = array(
'displayorder' => 'DESC',
'id' => 'DESC',
);
}
if(is_array($orders)){
$order = "";
$i = count($orders);
foreach($orders as $p=>$v){
$i--;
if($i==0){
$order .= " `".$p."` ". strtoupper($v) ."";
}else{
$order .= " `".$p."` ". strtoupper($v) .",";
}
}
$_order = " ORDER BY ".$order;
}
$sql = $sql.$_order.$_limit;
$command = $connection->createCommand($sql);
if(!empty($params) && is_array($params)){
foreach($params as $p=>$v){
$command->bindValue($p, $v);
}
}
$result = $command->queryAll();
return $result;
}
/*
* 更新指定表数据
@table, 要更新的表,使用绝对表名(有前缀的情况下需要直接写在表名上)
@columns 要更新的列(字段名=》新值)
@condition 附加条件(用于条件筛选,sql中where的条件部分)
@params 要绑定到附加条件的参数
*/
function fmFunc_pdo_yii_update($connection, $table, $columns, $conditions = '', $params = array()) {
$command = $connection->createCommand();
$result = $command->update($table, $columns, $conditions, $params)->execute();
return $result;
}
/*
* 向指定表插入数据
@table, 要插入的表,使用绝对表名(有前缀的情况下需要直接写在表名上)
@data 指定数据(字段名=》值)
*/
function fmFunc_pdo_yii_insert($connection, $table, $data = array()) {
$command = $connection->createCommand();
$result = $command->insert($table, $data)->execute();
return $result;
}
/*
* 取刚刚插入值的id
* 必须确保在insert之后执行
*/
function fmFunc_pdo_yii_insertid($connection,$table) {
$result = $connection->getLastInsertedID();
return $result;
}
/*
* 删除指定表指定条件数据
@table, 要插入的表,使用绝对表名(有前缀的情况下需要直接写在表名上)
@condition 指定条件
@params 条件附加参数 array()
*/
function fmFunc_pdo_yii_delete($connection, $table, $condition = '', $params = []) {
$command = $connection->createCommand()->delete($table, $condition);
if(!empty($params) && is_array($params)){
foreach($params as $p=>$v){
$command->bindValue($p, $v);
}
}
$result = $command->execute();
return $result;
}
/*
* 批量运行sql脚本 run 高危操作,不开放
@sqls 要运行的脚本
脚本中的各sql命令必须明确指定表名
*/
function fmFunc_pdo_yii_run($connection,$sqls) {
return;
if(!isset($sqls) || empty($sqls)) return;
$ret = array();
$num = 0;
$sqls = preg_replace("/\;[ \f\t\v]+/", ';', $sqls);
foreach(explode(";\n", trim($sqls)) as $query) {
$ret[$num] = '';
$queries = explode("\n", trim($query));
foreach($queries as $query) {
$ret[$num] .= (isset($query[0]) && $query[0] == '#') || (isset($query[1]) && isset($query[1]) && $query[0].$query[1] == '--') ? '' : $query;
}
$num++;
}
unset($sqls);
$result = [];
foreach($ret as $query) {
$query = trim($query);
if($query) {
$command = $connection->createCommand($query);
$result[] = $command->query();
}
}
return $result;
}
/*
* 判断表字段是否存在
@table 指定表
@filedname 字段名
*/
function fmFunc_pdo_yii_fieldexists($connection,$table, $fieldname) {
$sql = "DESCRIBE " . $table . " `{$fieldname}`";
$isexists = fmFunc_pdo_yii_fetch($connection,$sql, $params = array());
return !empty($isexists) ? true : false;
}
/*
* 判断表索引是否存在
@table 指定表
@indexname 索引名
*/
function fmFunc_pdo_yii_indexexists($connection,$table, $indexname) {
$sql = "SHOW INDEX FROM " . $table;
$indexes = fmFunc_pdo_yii_fetchall($connection,$sql, $params = array());
if (!empty($indexs) && is_array($indexs)) {
foreach ($indexs as $row) {
if ($row['Key_name'] == $indexname) {
return true;
}
}
}
return false;
}
/*
* 判断表是否存在
@table 指定表
*/
function fmFunc_pdo_yii_tableexists($connection,$table) {
$sql = "SHOW TABLES LIKE '{$table}'";
$isexists = fmFunc_pdo_yii_fetch($connection,$sql, $params = array());
return !empty($isexists) ? true : false;
}
/*
* 取表字段
@table 指定表
TBD:设定fetchall的排序方法
*/
function fmFunc_pdo_yii_tablefields($connection,$table) {
$sql = "DESCRIBE {$table}";
$fields = fmFunc_pdo_yii_fetchall($connection,$sql, $params = array());
$fields = array_keys($fields);
return $fields;
}
+68
View File
@@ -0,0 +1,68 @@
<?php
/**
* @author Fm453
* @site www.hiluker.com
* @remark:服务器类函数集
*/
defined('HI_FM') or exit("Access Denied");
//定义授权信息数据库
function fmFunc_authDb(){
$database = array(
'host' => 'www.hiluker.com', //数据库IP或是域名
//'host' => '127.0.0.1', //数据库IP或是域名
'username' => 'formodules', // 数据库连接用户名
'password' => '', // 数据库连接密码
'database' => 'fm453_access', // 数据库名
'port' => 3306, // 数据库连接端口
'tablepre' => '', // 表前缀,如果没有前缀留空即可pre_
'charset' => 'utf8', // 数据库默认编码
'pconnect' => 0, // 是否使用长连接
);
return $database;
}
//判断来路域名
function fmFunc_server_via_domain() {
global $_FM;
if(isset($_SERVER["HTTP_REFERER"])) {
$url = $_SERVER["HTTP_REFERER"]; //获取完整的来路URL
$str = str_replace("http://","",$url); //去掉http://
$str = str_replace("https://","",$url); //去掉https://
$strdomain = explode("/",$str); // 以“/”分开成数组
$domain = $strdomain[0]; //取第一个“/”以前的字符
}else{
$domain = '';
}
$_FM['viaDomain'] = $domain;
return $domain;
}
//判断来路ip
function fmFunc_server_via_ip() {
global $_FM;
$ip = '';
if(!empty($_SERVER["HTTP_CLIENT_IP"])){
$ip = $_SERVER["HTTP_CLIENT_IP"];
}elseif(!empty($_SERVER["HTTP_X_FORWARDED_FOR"])){
$ip = $_SERVER["HTTP_X_FORWARDED_FOR"];
}elseif(!empty($_SERVER["REMOTE_ADDR"])){
$ip = $_SERVER["REMOTE_ADDR"];
}
$_FM['viaIp'] = $ip;
return $ip;
}
//生成客户侧的用户uid
function fmFunc_server_hash_id($id) {
global $_FM;
require Yii::getAlias('@frontend/controllers/_public/plat.php');
$str = '';
$str .= '+'.$siteId;
$str .= '+'.$platid;
$str .= '+'.$uniacid;
$str .= '+'.$shopid;
$str .= '+'.$id;
$id = md5($str);
return $id;
}
+21
View File
@@ -0,0 +1,21 @@
<?php
/**
* 转换字节数为其他单位
* @param string $filesize 字节大小
* @return string 返回大小
*/
function sizeCount($filesize){
global $_GPC;
global $_W;
global $_FM;
if ($filesize >= 1073741824) {
$filesize = round($filesize / 1073741824 * 100) / 100 . ' GB';
} elseif ($filesize >= 1048576) {
$filesize = round($filesize / 1048576 * 100) / 100 . ' MB';
} elseif ($filesize >= 1024) {
$filesize = round($filesize / 1024 * 100) / 100 . ' KB';
} else {
$filesize = $filesize . ' Bytes';
}
return $filesize;
}
+155
View File
@@ -0,0 +1,155 @@
<?php
/**
* @author Fm453
* @site www.hiluker.com
* @remark:数据流量统计处理
*/
defined('HI_FM') or exit("Access Denied");
//更新某用户的数据用量
/*
@username 用户名
@bytes 本次入站数据大小
*/
function fmFunc_stat_bytes_in($username,$bytes)
{
global $_GPC;
global $_HI;
global $_FM;
$connection = yii::$app->db;
$table='c_user';
$column = 'inbytes';
$conditions = 'username = :username';
$params = array();
$params[':username'] = $username;
$inbytes = fmFunc_pdo_yii_fetchcolumn($connection,$table, $column, $conditions, $params);
$columns=array();
$columns[$column] = $inbytes+intval($bytes);
fmFunc_pdo_yii_update($connection, $table, $columns, $conditions, $params);
}
/*
@username 用户名
@bytes 出站数据大小
*/
function fmFunc_stat_bytes_out($username,$bytes)
{
global $_GPC;
global $_HI;
global $_FM;
$connection = yii::$app->db;
$table='c_user';
$column = 'outbytes';
$conditions = 'username = :username';
$params = array();
$params[':username'] = $username;
$outbytes = fmFunc_pdo_yii_fetchcolumn($connection,$table, $column, $conditions, $params);
$columns=array();
$columns[$column] = $outbytes+intval($bytes);
fmFunc_pdo_yii_update($connection, $table, $columns, $conditions, $params);
}
/*
@username 用户名
@times 出站接口调用次数
*/
function fmFunc_stat_times_out($username,$times)
{
global $_GPC;
global $_HI;
global $_FM;
$connection = yii::$app->db;
$table='c_user';
$column = 'outtimes';
$conditions = 'username = :username';
$params = array();
$params[':username'] = $username;
$outtimes = fmFunc_pdo_yii_fetchcolumn($connection,$table, $column, $conditions, $params);
$columns=array();
$columns[$column] = $outtimes+intval($times);
fmFunc_pdo_yii_update($connection, $table, $columns, $conditions, $params);
}
/*
@username 用户名
@times 入站接口调用次数
*/
function fmFunc_stat_times_in($username,$times)
{
global $_GPC;
global $_HI;
global $_FM;
$connection = yii::$app->db;
$table='c_user';
$column = 'intimes';
$conditions = 'username = :username';
$params = array();
$params[':username'] = $username;
$intimes = fmFunc_pdo_yii_fetchcolumn($connection,$table, $column, $conditions, $params);
$columns=array();
$columns[$column] = $intimes+intval($times);
fmFunc_pdo_yii_update($connection, $table, $columns, $conditions, $params);
}
/*
@username 用户名
@times 短信接口调用次数
*/
function fmFunc_stat_sms_send($username,$times)
{
global $_GPC;
global $_HI;
global $_FM;
$connection = yii::$app->db;
$table='c_user';
$column = 'sms_total';
$column2 = 'sms_left';
$conditions = 'username = :username';
$params = array();
$params[':username'] = $username;
$total = fmFunc_pdo_yii_fetchcolumn($connection,$table, $column, $conditions, $params);
$left = fmFunc_pdo_yii_fetchcolumn($connection,$table, $column2, $conditions, $params);
if($times==0){
return int($left);
}
$columns=array();
$columns[$column] = $total+intval($times);
$columns[$column2] = $left-intval($times);
fmFunc_pdo_yii_update($connection, $table, $columns, $conditions, $params);
return $columns[$column2];
}
//取某用户的数据用量
/*
@username 用户名
*/
function fmFunc_stat_get($username)
{
global $_GPC;
global $_HI;
global $_FM;
$connection = yii::$app->db;
$table='c_user';
$fields = "`inbytes`,`intimes`,`outbytes`,`outtimes`,`sms_total`,`sms_left`,`sms_type`";
$conditions = 'username = :username';
$params = array();
$params[':username'] = $username;
$sql = "SELECT ".$fields." FROM ".$table." WHERE ".$conditions." LIMIT 1";
return fmFunc_pdo_yii_fetch($connection,$sql, $params);
}
+15
View File
@@ -0,0 +1,15 @@
<?php
# @Author: 嗨噜客科技(www.hiluker.cn) <fm453>
# @Date: 1970-01-01T08:00:00+08:00
# @Email: fm453@hiluker.com
# @Last modified by: fm453
# @Last modified time: 2021-09-15T10:14:51+08:00
/*判断一个路径是网络图片还是本地图片*/
function fmFunc_url_img($src,$atturl){
$url = $src;
$str = str_replace("http://","",$url); //去掉http://
$str = str_replace("https://","",$url); //去掉https://
if($str==$src) return $atturl.$src; //本地图片
return $src;
}
+139
View File
@@ -0,0 +1,139 @@
<?php
// 取客户端的ip、地理信息、浏览器、本地真实IP
//获得访客浏览器类型
function fmFunc_UA_getBrowser(){
if(!empty($_SERVER['HTTP_USER_AGENT'])){
$br = $_SERVER['HTTP_USER_AGENT'];
if (preg_match('/MSIE/i',$br)) {
$br = 'MSIE';
}elseif (preg_match('/Firefox/i',$br)) {
$br = 'Firefox';
}elseif (preg_match('/Chrome/i',$br)) {
$br = 'Chrome';
}elseif (preg_match('/Safari/i',$br)) {
$br = 'Safari';
}elseif (preg_match('/Opera/i',$br)) {
$br = 'Opera';
}else {
$br = 'Other';
}
return $br;
}else{return "获取浏览器信息失败!";}
}
////获得访客浏览器语言
function fmFunc_UA_getLang(){
if(!empty($_SERVER['HTTP_ACCEPT_LANGUAGE'])){
$lang = $_SERVER['HTTP_ACCEPT_LANGUAGE'];
$lang = substr($lang,0,5);
if(preg_match("/zh-cn/i",$lang)){
$lang = "简体中文";
}elseif(preg_match("/zh/i",$lang)){
$lang = "繁体中文";
}else{
$lang = "English";
}
return $lang;
}else{return "获取浏览器语言失败!";}
}
////获取访客操作系统
function fmFunc_UA_getOs(){
if(!empty($_SERVER['HTTP_USER_AGENT'])){
$OS = $_SERVER['HTTP_USER_AGENT'];
if (preg_match('/win/i',$OS)) {
$OS = 'Windows';
}elseif (preg_match('/mac/i',$OS)) {
$OS = 'MAC';
}elseif (preg_match('/linux/i',$OS)) {
$OS = 'Linux';
}elseif (preg_match('/unix/i',$OS)) {
$OS = 'Unix';
}elseif (preg_match('/bsd/i',$OS)) {
$OS = 'BSD';
}else {
$OS = 'Other';
}
return $OS;
}else{
return "获取访客操作系统信息失败!";
}
}
////获得访客真实ip
function fmFunc_UA_getIp(){
if(!empty($_SERVER["HTTP_CLIENT_IP"])){
$ip = $_SERVER["HTTP_CLIENT_IP"];
}
if(!empty($_SERVER['HTTP_X_FORWARDED_FOR'])){ //获取代理ip
$ips = explode(',',$_SERVER['HTTP_X_FORWARDED_FOR']);
}
if($ip){
$ips = array_unshift($ips,$ip);
}
$count = count($ips);
for($i=0;$i<$count;$i++){
if(!preg_match("/^(10|172\.16|192\.168)\./i",$ips[$i])){//排除局域网ip
$ip = $ips[$i];
break;
}
}
$tip = empty($_SERVER['REMOTE_ADDR']) ? $ip : $_SERVER['REMOTE_ADDR'];
if($tip=="127.0.0.1"){ //获得本地真实IP
return fmFunc_UA_getOnlineIp();
}else{
return $tip;
}
}
////获得本地真实IP
function fmFunc_UA_getOnlineIp() {
$mip = file_get_contents("http://city.ip138.com/city0.asp");
if($mip){
preg_match("/\[.*\]/",$mip,$sip);
$p = array("/\[/","/\]/");
return preg_replace($p,"",$sip[0]);
}else{return "获取本地IP失败!";}
}
////根据ip获得访客所在地地名
function fmFunc_UA_getAddress($ip=''){
if(empty($ip)){
$ip = fmFunc_UA_getIp();
}
$ipadd = file_get_contents("http://int.dpool.sina.com.cn/iplookup/iplookup.php?ip=".$ip);//根据新浪api接口获取
if($ipadd){
$charset = iconv("gbk","utf-8",$ipadd);
preg_match_all("/[\x{4e00}-\x{9fa5}]+/u",$charset,$ipadds);
return $ipadds; //返回一个二维数组
}else{
return "ipaddree is null";
}
}
//微信浏览器判断
function fmFunc_UA_isWeichat() {
if (empty($_SERVER['HTTP_USER_AGENT']) || strpos($_SERVER['HTTP_USER_AGENT'], 'MicroMessenger') === false && strpos($_SERVER['HTTP_USER_AGENT'], 'Windows Phone') === false) {
return FALSE;
}
return TRUE;
}
/**
* 是否是移动端访问
* 判断是否有HTTP_X_WAP_PROFILE,有则一定是移动设备。
* @return bool
* 有些服务商会屏蔽该信息
*/
function fmFunc_UA_isMobile()
{
if (isset ($_SERVER['HTTP_X_WAP_PROFILE'])) {
return true;
} else {
return false;
}
}