diff --git a/admin/admin.inc.php b/admin/admin.inc.php index 4a7684c..afa40e6 100755 --- a/admin/admin.inc.php +++ b/admin/admin.inc.php @@ -3,7 +3,7 @@ * 简单图床设置页面 * 2022-1-24 05:57:35 */ -require_once __DIR__ . '/../application/header.php'; +require_once __DIR__ . '/../app/header.php'; require_once APP_ROOT . '/config/api_key.php'; require_once APP_ROOT . '/config/config.guest.php'; @@ -15,7 +15,7 @@ if (!is_who_login('admin')) { icon: "exclamation-sign" // 定义消息图标 }).show();'; header("refresh:2;url=" . $config['domain'] . "/admin/index.php"); - require_once APP_ROOT . '/application/footer.php'; + require_once APP_ROOT . '/app/footer.php'; exit; } @@ -499,7 +499,7 @@ auto_delete(); //定时删除
-
+
压缩文件夹
@@ -568,7 +568,7 @@ auto_delete(); //定时删除
上传日志 需要开启上传日志
- +
@@ -579,7 +579,7 @@ auto_delete(); //定时删除
登录日志 仅显示当月
- +
定时删除 数值为0时关闭
@@ -890,7 +890,7 @@ auto_delete(); //定时删除 $file_size = getDistUsed(filesize($file_cache_path)); // 大小 $filen_name = $cache_file[$i]; // 名称 $url = $config['domain'] . $file_path; // 网络连接 - $unlink_img = $config['domain'] . '/application/del.php?url=' . $file_path; // 删除连接 + $unlink_img = $config['domain'] . '/app/del.php?url=' . $file_path; // 删除连接 ?> @@ -899,7 +899,7 @@ auto_delete(); //定时删除 查看 - 信息 + 信息 恢复 删除 @@ -984,7 +984,7 @@ auto_delete(); //定时删除 Ip2region (2.0 - xdb) 是一个离线 IP 数据管理框架和定位库,支持亿级别的数据段,10微秒级别的查询性能,提供了许多主流编程语言的 xdb 数据管理引擎的实现。 每个 ip 数据段的 region 信息都固定了格式:国家|区域|省份|城市|ISP, 只有中国的数据绝大部分精确到了城市, 其他国家部分数据只能定位到国家, 后前的选项全部是0。

-
* 下载 ip2region.xdb IP数据库上传到 /application/ip2region/ 文件夹, 如遇到下载失败可访问开源地址下载: [ Github | Gitee ] 更新方法与此相同。
+
* 下载 ip2region.xdb IP数据库上传到 /app/ip2region/ 文件夹, 如遇到下载失败可访问开源地址下载: [ Github | Gitee ] 更新方法与此相同。
@@ -1135,7 +1135,7 @@ auto_delete(); //定时删除
  • 直接输入账号和密码即可完成修改
  • 更改后会立即生效并重新登录,请务必牢记账号和密码!
  • 如果忘记账号可以打开->/config/config.php文件->找到user对应的键值->填入
  • -
  • 如果忘记密码请将密码->转换成SHA256->转换网址->打开/config/config.php文件->找到password对应的键值->填入
  • +
  • 如果忘记密码请将密码->转换成SHA256->转换网址->打开/config/config.php文件->找到password对应的键值->填入
  • @@ -1232,7 +1232,7 @@ auto_delete(); //定时删除 $file_size = getDistUsed(filesize($file_cache_path)); // 大小 $filen_name = $cache_file[$i]; // 名称 $url = $config['domain'] . $file_path; // 网络连接 - $unlink_img = $config['domain'] . '/application/del.php?url=' . $file_path; // 删除连接 + $unlink_img = $config['domain'] . '/app/del.php?url=' . $file_path; // 删除连接 ?> @@ -1241,7 +1241,7 @@ auto_delete(); //定时删除 查看 - 信息 + 信息 恢复 删除 @@ -1365,7 +1365,7 @@ auto_delete(); //定时删除 文件管理 文件管理
    删除文件 * 删除后不可恢复
    - +

    @@ -1641,11 +1641,11 @@ auto_delete(); //定时删除 guestMyDataGrid.sortBy('add_time', 'desc'); /** 引入设置页面检测文件 */ - + // 更改网页标题 document.title = "图床设置 - " " -'; - exit(require_once APP_ROOT . '/application/footer.php'); + exit(require_once APP_ROOT . '/app/footer.php'); } else { session_start(); if (strtolower($_REQUEST['code']) !== $_SESSION['code']) { @@ -63,7 +63,7 @@ if (isset($_POST['password']) and isset($_POST['user'])) { // 延时2s跳转 window.setTimeout("window.location=\'./index.php\'",2000); '; - exit(require_once APP_ROOT . '/application/footer.php'); + exit(require_once APP_ROOT . '/app/footer.php'); } } } @@ -108,7 +108,7 @@ if (isset($_POST['password']) and isset($_POST['user'])) {
    '; header("refresh:3;url=" . $config['domain'] . "/admin/index.php"); - require_once APP_ROOT.'/application/footer.php'; + require_once APP_ROOT.'/app/footer.php'; exit; } // 开启tinyfilemanager图片管理 if (!$config['file_manage']) { - require_once APP_ROOT.'/application/header.php'; + require_once APP_ROOT.'/app/header.php'; echo '
    图片管理已关闭~~
    '; header("refresh:3;url=" . $_SERVER["HTTP_REFERER"] . '?manager-closed'); - require_once APP_ROOT.'/application/footer.php'; + require_once APP_ROOT.'/app/footer.php'; exit; } @@ -2108,7 +2108,7 @@ $tableTheme = (FM_THEME == "dark") ? "text-white bg-dark table-dark" : "bg-white if (in_array(strtolower(pathinfo($f, PATHINFO_EXTENSION)), array('gif', 'jpg', 'jpeg', 'png', 'bmp', 'ico', 'svg', 'webp', 'avif'))): ?> - <?php echo fm_enc($f);?> + <?php echo fm_enc($f);?> diff --git a/admin/terms.php b/admin/terms.php index eff98de..e822646 100755 --- a/admin/terms.php +++ b/admin/terms.php @@ -2,7 +2,7 @@ /* * 使用条款页面 */ -require_once __DIR__ . '/../application/header.php'; +require_once __DIR__ . '/../app/header.php'; /** 顶部广告 */ if ($config['ad_top']) echo $config['ad_top_info']; @@ -25,4 +25,4 @@ if ($config['ad_bot']) echo $config['ad_bot_info']; "; -uploaded) { // 源图保护 key值是由crc32加密的hide_key if ($config['hide'] == 1) { - $imageUrl = $config['domain'] . '/application/hide.php?key=' . urlHash($pathIMG, 0, crc32($config['hide_key'])); + $imageUrl = $config['domain'] . '/app/hide.php?key=' . urlHash($pathIMG, 0, crc32($config['hide_key'])); } // 删除文件链接 if ($config['show_user_hash_del']) { - $delUrl = $config['domain'] . '/application/del.php?hash=' . urlHash($pathIMG, 0); + $delUrl = $config['domain'] . '/app/del.php?hash=' . urlHash($pathIMG, 0); } else { $delUrl = "Admin closed user delete"; } // 当设置访问生成缩略图时自动生成 2022-12-30 修正 2023-01-30 - $handleThumb = $config['domain'] . '/application/thumb.php?img=' . $pathIMG; + $handleThumb = $config['domain'] . '/app/thumb.php?img=' . $pathIMG; if ($config['thumbnail'] == 2) { // 自定义缩略图长宽 $handle->image_resize = true; diff --git a/api/public.php b/api/public.php index 2fa77a2..d52613e 100755 --- a/api/public.php +++ b/api/public.php @@ -5,8 +5,8 @@ * 2022年2月22日11:41:38 * @author Icret */ -require_once '../application/function.php'; -require_once '../application/chart.php'; +require_once '../app/function.php'; +require_once '../app/chart.php'; // 检查是否开启查询 if ($config['public'] == 0) die('开放数据接口已关闭!'); diff --git a/application/FtpClient/FtpClient.php b/app/FtpClient/FtpClient.php similarity index 100% rename from application/FtpClient/FtpClient.php rename to app/FtpClient/FtpClient.php diff --git a/application/FtpClient/FtpException.php b/app/FtpClient/FtpException.php similarity index 100% rename from application/FtpClient/FtpException.php rename to app/FtpClient/FtpException.php diff --git a/application/FtpClient/FtpWrapper.php b/app/FtpClient/FtpWrapper.php similarity index 100% rename from application/FtpClient/FtpWrapper.php rename to app/FtpClient/FtpWrapper.php diff --git a/application/TimThumb.php b/app/TimThumb.php old mode 100755 new mode 100644 similarity index 100% rename from application/TimThumb.php rename to app/TimThumb.php diff --git a/application/WaterMask.php b/app/WaterMask.php old mode 100755 new mode 100644 similarity index 97% rename from application/WaterMask.php rename to app/WaterMask.php index db2c735..c75a77b --- a/application/WaterMask.php +++ b/app/WaterMask.php @@ -1,357 +1,357 @@ - false, 'msg' => '请指定$src'); - } - - $temp = pathinfo($src); - # 文件名 - $name = $temp["basename"]; - # 文件所在的文件夹 - $dir = $temp["dirname"]; - # 文件扩展名 - $extension = $temp["extension"]; - # 缩略图保存路径,新的文件名为*.thumb.jpg - $savepath = "{$dir}/thumb_{$name}"; - - # 获取图片的基本信息 - $info = getimagesize($src); - # 获取图片宽度 - $width = $info[0]; - # 获取图片高度 - $height = $info[1]; - if (!empty($w)) { - $temp_w = $w; # 计算原图缩放后的宽度 - $temp_h = intval($height * ($w / $width)); # 计算原图缩放后的高度 - } else { - $temp_w = intval($width * ($h / $height)); # 计算原图缩放后的宽度 - $temp_h = $h; # 计算原图缩放后的高度 - } - - # 创建画布 - $temp_img = imagecreatetruecolor($temp_w, $temp_h); - @imagealphablending($temp_img, false); //这里很重要,意思是不合并颜色,直接用$img图像颜色替换,包括透明色;3-2 - @imagesavealpha($temp_img, true); //这里很重要,意思是不要丢了$thumb图像的透明色;3-3 - switch ($info[2]) { - case 1: - $im = imagecreatefromgif($src); - imagecopyresampled($temp_img, $im, 0, 0, 0, 0, $temp_w, $temp_h, $width, $height); - imagegif($temp_img, $savepath, 100); - break; - case 2: - $im = imagecreatefromjpeg($src); - imagecopyresampled($temp_img, $im, 0, 0, 0, 0, $temp_w, $temp_h, $width, $height); - imagejpeg($temp_img, $savepath, 100); - break; - case 3: - $im = imagecreatefrompng($src); - imagesavealpha($im, true); //这里很重要;3-1 - imagecopyresampled($temp_img, $im, 0, 0, 0, 0, $temp_w, $temp_h, $width, $height); - imagepng($temp_img, $savepath, 100); - break; - case 6: - $im = imagecreatefrombmp($src); - imagesavealpha($im, true); //这里很重要;3-1 - imagecopyresampled($temp_img, $im, 0, 0, 0, 0, $temp_w, $temp_h, $width, $height); - imagebmp($temp_img, $savepath, 100); - break; - case 18: - $im = imagecreatefromwebp($src); - imagesavealpha($im, true); //这里很重要;3-1 - imagecopyresampled($temp_img, $im, 0, 0, 0, 0, $temp_w, $temp_h, $width, $height); - imagewebp($temp_img, $savepath, 100); - break; - } - imagedestroy($im); - return $savepath; - } - - /** - * 图片添加水印 - * @param string $src 1、图片相对路径或绝对路径 2、以逗号隔开的宽高值('800,600') - * @param array 属性值: - * res:水印资源(1、图片相对路径或绝对路径,2、字符串) - * pos:图片水印添加的位置,取值范围:0~9 - * 0:随机位置,在1~8之间随机选取一个位置 - * 1:顶部居左 2:顶部居中 - * 3:顶部居右 4:左边居中 - * 5:图片中心 6:右边居中 - * 7:底部居左 8:底部居中 - * 9:底部居右 - * font: 字体库(相对路径或绝对路径) - * fontSize:文字大小 - * color: 水印文字的字体颜色(255,255,255) - * name: 图片保存名称 - * @return array code:状态、 msg:提示信息、 url:图片地址 - **/ - public static function setWater($src, $arr = array()) - { - if (empty($src)) { - return array('code' => false, 'msg' => '请指定$src'); - } - - $def = array( - 'res' => '小川编程', - 'pos' => 7, - 'font' => './1.ttf', - 'fontSize' => 24, - 'color' => '255,255,255,0', - 'name' => null, - ); - $def = array_merge($def, $arr); - /** - * 判断$src是不是图片,不是就创建画布 - */ - if (!file_exists($src)) { - if (empty($def['name'])) { - return array('code' => false, 'msg' => '请指定图片名称'); - } - - # 计算画布宽高 - $obj = explode(',', $src); - if (count($obj) != 2) { - return array( - 'code' => false, - 'msg' => '请给正确的宽高,或你给的不是一个有效的地址!' - ); - } - - $srcImg_w = is_numeric($obj[0]) ? $obj[0] : 400; - $srcImg_h = is_numeric($obj[1]) ? $obj[1] : 300; - # 创建透明画布 一共3个步骤,在下边有标记 - $dst_img = @imagecreatetruecolor($srcImg_w, $srcImg_h); - @imagealphablending($dst_img, false); //这里很重要,意思是不合并颜色,直接用$img图像颜色替换,包括透明色;3-2 - @imagesavealpha($dst_img, true); //这里很重要,意思是不要丢了$thumb图像的透明色;3-3 - } else { - # 获取图片信息 - $srcInfo = @getimagesize($src); - $srcImg_w = $srcInfo[0]; - $srcImg_h = $srcInfo[1]; - if (empty($def['name'])) { - $def['name'] = $src; - } - - # 动态的把图片导入内存中 - switch ($srcInfo[2]) { - case 1: - $dst_img = imagecreatefromgif($src); - break; - - case 2: - $dst_img = imagecreatefromjpeg($src); - break; - - case 3: - $dst_img = imagecreatefrompng($src); - imagesavealpha($dst_img, true); //这里很重要;3-1 - break; - - case 6: - $dst_img = imagecreatefrombmp($src); - imagesavealpha($dst_img, true); //这里很重要;3-1 - break; - case 18: - $dst_img = imagecreatefromwebp($src); - imagesavealpha($dst_img, true); //这里很重要;3-1 - break; - - default: - return array('code' => false, 'msg' => '目标图片类型错误'); - exit; - } - } - /** - * 计算出水印宽高 - */ - if (!file_exists($def['res'])) { - if (!file_exists($def['font'])) { - return array('code' => false, 'msg' => '字体库不存在'); - } - - $box = @imagettfbbox($def['fontSize'], 0, $def['font'], $def['res']); - $logow = max($box[2], $box[4]) - min($box[0], $box[6]); - $logoh = max($box[1], $box[3]) - min($box[5], $box[7]); - } else { - $resInfo = @getimagesize($def['res']); - $res_w = $resInfo[0]; - $res_h = $resInfo[1]; - if ($srcImg_w < $res_w || $srcImg_h < $res_h) { - return array('code' => false, 'msg' => '水印图片过大'); - } - - # 动态的把图片导入内存中 - switch ($resInfo[2]) { - case 1: - $markim = imagecreatefromgif($def['res']); - break; - case 2: - $markim = imagecreatefromjpeg($def['res']); - break; - case 3: - $markim = imagecreatefrompng($def['res']); - break; - case 6: - $markim = imagecreatefrombmp($def['res']); - break; - case 18: - $markim = imagecreatefromwebp($def['res']); - break; - default: - return array('code' => false, 'msg' => '水印图片类型错误'); - exit; - } - $logow = $res_w; - $logoh = $res_h; - } - /** - * 计算水印显示位置 - */ - if ($def['pos'] == 0) { - $def['pos'] = rand(1, 9); - } - - switch ($def['pos']) { - case 1: - $x = +10; - $y = +10 + $def['fontSize']; - break; - - case 2: - $x = ($srcImg_w - $logow) / 2; - $y = +10 + $def['fontSize']; - break; - - case 3: - $x = $srcImg_w - $logow - 10; - $y = +10 + $def['fontSize']; - break; - - case 4: - $x = +10; - $y = ($srcImg_h - $logoh) / 2 + $def['fontSize']; - break; - - case 5: - $x = ($srcImg_w - $logow) / 2; - $y = ($srcImg_h - $logoh) / 2 + $def['fontSize']; - break; - - case 6: - $x = $srcImg_w - $logow - 10; - $y = ($srcImg_h - $logoh) / 2 + $def['fontSize']; - break; - - case 7: - $x = +10; - $y = $srcImg_h - $logoh + $def['fontSize'] - 10; - break; - - case 8: - $x = ($srcImg_w - $logow) / 2; - $y = $srcImg_h - $logoh + $def['fontSize'] - 10; - break; - - case 9: - $x = $srcImg_w - $logow - 10; - $y = $srcImg_h - $logoh + $def['fontSize'] - 10; - break; - - default: - return array('code' => false, 'msg' => '水印位置不支持'); - exit; - } - /** - * 把图片水印或文字水印,加到目标图片中 - */ - if (file_exists($def['res'])) { - imagecopy($dst_img, $markim, $x, $y, 0, 0, $logow, $logoh); - imagedestroy($markim); - } else { - $rgb = explode(',', $def['color']); - if (count($rgb) != 4) { - return array('code' => false, 'msg' => '请给正确的字体颜色'); - } - - if (!is_numeric($rgb[0]) || !is_numeric($rgb[1]) || !is_numeric($rgb[2]) || !is_numeric($rgb[3])) { - return array('code' => false, 'msg' => '请给正确的字体颜色'); - } - - if ($rgb[0] > 255 || $rgb[1] > 255 || $rgb[2] > 255 || $rgb[3] > 127) { - return array('code' => false, 'msg' => '请给正确的字体颜色'); - } - - // ceil(127 - 127 * $rgb[3]) 将CSS中的Alpha 0-1 转换为PHP Alpha 127-0 并取整 - $def['color'] = imagecolorallocatealpha($dst_img, $rgb[0], $rgb[1], $rgb[2], ceil(127 - 127 * $rgb[3])); - imagettftext( - $dst_img, - $def['fontSize'], - 0, - $x, - $y, - $def['color'], - $def['font'], - $def['res'] - ); - } - /** - * 保存处理过的图片(有水印了的图片) - */ - $name = explode('.', $def['name']); - $num = count($name) - 1; - switch (strtolower($name[$num])) { - case 'jpeg': - imagejpeg($dst_img, $def['name']); - break; - case 'jpg': - imagejpeg($dst_img, $def['name']); - break; - case 'png': - imagepng($dst_img, $def['name']); - break; - case 'gif': - imagegif($dst_img, $def['name']); - break; - case 'bmp': - imagebmp($dst_img, $def['name']); - break; - case 'webp': - imagewebp($dst_img, $def['name']); - break; - default: - return array('code' => false, 'msg' => '保存图片类型有误'); - break; - } - # 销毁图片内存资源 - imagedestroy($dst_img); - return array('code' => true, 'msg' => '添加水印成功', 'url' => $def['name']); - } -} + false, 'msg' => '请指定$src'); + } + + $temp = pathinfo($src); + # 文件名 + $name = $temp["basename"]; + # 文件所在的文件夹 + $dir = $temp["dirname"]; + # 文件扩展名 + $extension = $temp["extension"]; + # 缩略图保存路径,新的文件名为*.thumb.jpg + $savepath = "{$dir}/thumb_{$name}"; + + # 获取图片的基本信息 + $info = getimagesize($src); + # 获取图片宽度 + $width = $info[0]; + # 获取图片高度 + $height = $info[1]; + if (!empty($w)) { + $temp_w = $w; # 计算原图缩放后的宽度 + $temp_h = intval($height * ($w / $width)); # 计算原图缩放后的高度 + } else { + $temp_w = intval($width * ($h / $height)); # 计算原图缩放后的宽度 + $temp_h = $h; # 计算原图缩放后的高度 + } + + # 创建画布 + $temp_img = imagecreatetruecolor($temp_w, $temp_h); + @imagealphablending($temp_img, false); //这里很重要,意思是不合并颜色,直接用$img图像颜色替换,包括透明色;3-2 + @imagesavealpha($temp_img, true); //这里很重要,意思是不要丢了$thumb图像的透明色;3-3 + switch ($info[2]) { + case 1: + $im = imagecreatefromgif($src); + imagecopyresampled($temp_img, $im, 0, 0, 0, 0, $temp_w, $temp_h, $width, $height); + imagegif($temp_img, $savepath, 100); + break; + case 2: + $im = imagecreatefromjpeg($src); + imagecopyresampled($temp_img, $im, 0, 0, 0, 0, $temp_w, $temp_h, $width, $height); + imagejpeg($temp_img, $savepath, 100); + break; + case 3: + $im = imagecreatefrompng($src); + imagesavealpha($im, true); //这里很重要;3-1 + imagecopyresampled($temp_img, $im, 0, 0, 0, 0, $temp_w, $temp_h, $width, $height); + imagepng($temp_img, $savepath, 100); + break; + case 6: + $im = imagecreatefrombmp($src); + imagesavealpha($im, true); //这里很重要;3-1 + imagecopyresampled($temp_img, $im, 0, 0, 0, 0, $temp_w, $temp_h, $width, $height); + imagebmp($temp_img, $savepath, 100); + break; + case 18: + $im = imagecreatefromwebp($src); + imagesavealpha($im, true); //这里很重要;3-1 + imagecopyresampled($temp_img, $im, 0, 0, 0, 0, $temp_w, $temp_h, $width, $height); + imagewebp($temp_img, $savepath, 100); + break; + } + imagedestroy($im); + return $savepath; + } + + /** + * 图片添加水印 + * @param string $src 1、图片相对路径或绝对路径 2、以逗号隔开的宽高值('800,600') + * @param array 属性值: + * res:水印资源(1、图片相对路径或绝对路径,2、字符串) + * pos:图片水印添加的位置,取值范围:0~9 + * 0:随机位置,在1~8之间随机选取一个位置 + * 1:顶部居左 2:顶部居中 + * 3:顶部居右 4:左边居中 + * 5:图片中心 6:右边居中 + * 7:底部居左 8:底部居中 + * 9:底部居右 + * font: 字体库(相对路径或绝对路径) + * fontSize:文字大小 + * color: 水印文字的字体颜色(255,255,255) + * name: 图片保存名称 + * @return array code:状态、 msg:提示信息、 url:图片地址 + **/ + public static function setWater($src, $arr = array()) + { + if (empty($src)) { + return array('code' => false, 'msg' => '请指定$src'); + } + + $def = array( + 'res' => '小川编程', + 'pos' => 7, + 'font' => './1.ttf', + 'fontSize' => 24, + 'color' => '255,255,255,0', + 'name' => null, + ); + $def = array_merge($def, $arr); + /** + * 判断$src是不是图片,不是就创建画布 + */ + if (!file_exists($src)) { + if (empty($def['name'])) { + return array('code' => false, 'msg' => '请指定图片名称'); + } + + # 计算画布宽高 + $obj = explode(',', $src); + if (count($obj) != 2) { + return array( + 'code' => false, + 'msg' => '请给正确的宽高,或你给的不是一个有效的地址!' + ); + } + + $srcImg_w = is_numeric($obj[0]) ? $obj[0] : 400; + $srcImg_h = is_numeric($obj[1]) ? $obj[1] : 300; + # 创建透明画布 一共3个步骤,在下边有标记 + $dst_img = @imagecreatetruecolor($srcImg_w, $srcImg_h); + @imagealphablending($dst_img, false); //这里很重要,意思是不合并颜色,直接用$img图像颜色替换,包括透明色;3-2 + @imagesavealpha($dst_img, true); //这里很重要,意思是不要丢了$thumb图像的透明色;3-3 + } else { + # 获取图片信息 + $srcInfo = @getimagesize($src); + $srcImg_w = $srcInfo[0]; + $srcImg_h = $srcInfo[1]; + if (empty($def['name'])) { + $def['name'] = $src; + } + + # 动态的把图片导入内存中 + switch ($srcInfo[2]) { + case 1: + $dst_img = imagecreatefromgif($src); + break; + + case 2: + $dst_img = imagecreatefromjpeg($src); + break; + + case 3: + $dst_img = imagecreatefrompng($src); + imagesavealpha($dst_img, true); //这里很重要;3-1 + break; + + case 6: + $dst_img = imagecreatefrombmp($src); + imagesavealpha($dst_img, true); //这里很重要;3-1 + break; + case 18: + $dst_img = imagecreatefromwebp($src); + imagesavealpha($dst_img, true); //这里很重要;3-1 + break; + + default: + return array('code' => false, 'msg' => '目标图片类型错误'); + exit; + } + } + /** + * 计算出水印宽高 + */ + if (!file_exists($def['res'])) { + if (!file_exists($def['font'])) { + return array('code' => false, 'msg' => '字体库不存在'); + } + + $box = @imagettfbbox($def['fontSize'], 0, $def['font'], $def['res']); + $logow = max($box[2], $box[4]) - min($box[0], $box[6]); + $logoh = max($box[1], $box[3]) - min($box[5], $box[7]); + } else { + $resInfo = @getimagesize($def['res']); + $res_w = $resInfo[0]; + $res_h = $resInfo[1]; + if ($srcImg_w < $res_w || $srcImg_h < $res_h) { + return array('code' => false, 'msg' => '水印图片过大'); + } + + # 动态的把图片导入内存中 + switch ($resInfo[2]) { + case 1: + $markim = imagecreatefromgif($def['res']); + break; + case 2: + $markim = imagecreatefromjpeg($def['res']); + break; + case 3: + $markim = imagecreatefrompng($def['res']); + break; + case 6: + $markim = imagecreatefrombmp($def['res']); + break; + case 18: + $markim = imagecreatefromwebp($def['res']); + break; + default: + return array('code' => false, 'msg' => '水印图片类型错误'); + exit; + } + $logow = $res_w; + $logoh = $res_h; + } + /** + * 计算水印显示位置 + */ + if ($def['pos'] == 0) { + $def['pos'] = rand(1, 9); + } + + switch ($def['pos']) { + case 1: + $x = +10; + $y = +10 + $def['fontSize']; + break; + + case 2: + $x = ($srcImg_w - $logow) / 2; + $y = +10 + $def['fontSize']; + break; + + case 3: + $x = $srcImg_w - $logow - 10; + $y = +10 + $def['fontSize']; + break; + + case 4: + $x = +10; + $y = ($srcImg_h - $logoh) / 2 + $def['fontSize']; + break; + + case 5: + $x = ($srcImg_w - $logow) / 2; + $y = ($srcImg_h - $logoh) / 2 + $def['fontSize']; + break; + + case 6: + $x = $srcImg_w - $logow - 10; + $y = ($srcImg_h - $logoh) / 2 + $def['fontSize']; + break; + + case 7: + $x = +10; + $y = $srcImg_h - $logoh + $def['fontSize'] - 10; + break; + + case 8: + $x = ($srcImg_w - $logow) / 2; + $y = $srcImg_h - $logoh + $def['fontSize'] - 10; + break; + + case 9: + $x = $srcImg_w - $logow - 10; + $y = $srcImg_h - $logoh + $def['fontSize'] - 10; + break; + + default: + return array('code' => false, 'msg' => '水印位置不支持'); + exit; + } + /** + * 把图片水印或文字水印,加到目标图片中 + */ + if (file_exists($def['res'])) { + imagecopy($dst_img, $markim, $x, $y, 0, 0, $logow, $logoh); + imagedestroy($markim); + } else { + $rgb = explode(',', $def['color']); + if (count($rgb) != 4) { + return array('code' => false, 'msg' => '请给正确的字体颜色'); + } + + if (!is_numeric($rgb[0]) || !is_numeric($rgb[1]) || !is_numeric($rgb[2]) || !is_numeric($rgb[3])) { + return array('code' => false, 'msg' => '请给正确的字体颜色'); + } + + if ($rgb[0] > 255 || $rgb[1] > 255 || $rgb[2] > 255 || $rgb[3] > 127) { + return array('code' => false, 'msg' => '请给正确的字体颜色'); + } + + // ceil(127 - 127 * $rgb[3]) 将CSS中的Alpha 0-1 转换为PHP Alpha 127-0 并取整 + $def['color'] = imagecolorallocatealpha($dst_img, $rgb[0], $rgb[1], $rgb[2], ceil(127 - 127 * $rgb[3])); + imagettftext( + $dst_img, + $def['fontSize'], + 0, + $x, + $y, + $def['color'], + $def['font'], + $def['res'] + ); + } + /** + * 保存处理过的图片(有水印了的图片) + */ + $name = explode('.', $def['name']); + $num = count($name) - 1; + switch (strtolower($name[$num])) { + case 'jpeg': + imagejpeg($dst_img, $def['name']); + break; + case 'jpg': + imagejpeg($dst_img, $def['name']); + break; + case 'png': + imagepng($dst_img, $def['name']); + break; + case 'gif': + imagegif($dst_img, $def['name']); + break; + case 'bmp': + imagebmp($dst_img, $def['name']); + break; + case 'webp': + imagewebp($dst_img, $def['name']); + break; + default: + return array('code' => false, 'msg' => '保存图片类型有误'); + break; + } + # 销毁图片内存资源 + imagedestroy($dst_img); + return array('code' => true, 'msg' => '添加水印成功', 'url' => $def['name']); + } +} diff --git a/application/Zebra_Image.php b/app/Zebra_Image.php similarity index 100% rename from application/Zebra_Image.php rename to app/Zebra_Image.php diff --git a/application/bing.php b/app/bing.php similarity index 90% rename from application/bing.php rename to app/bing.php index b41ca3a..6c72401 100644 --- a/application/bing.php +++ b/app/bing.php @@ -5,12 +5,12 @@ * 作者:mengkun (mkblog.cn) * 日期:2016/12/23 * 修改:Icret - * 修改日期:2023-01-30 + * 修改日期:2023-03-09 */ +include_once __DIR__ . '/function.php'; +include_once APP_ROOT . '/config/config.php'; -include_once '../config/config.php'; - -$path = '..' . $config['path'] . $config['delDir']; // 设置图片缓存文件夹 +$path = APP_ROOT . $config['path'] . $config['delDir']; // 设置图片缓存文件夹 $filename = date("Ymd") . '.jpg'; // 用年月日来命名新的文件名 if (file_exists($path . $filename)) // 如果文件不存在,则说明今天还没有进行缓存 { diff --git a/application/captcha.php b/app/captcha.php old mode 100755 new mode 100644 similarity index 96% rename from application/captcha.php rename to app/captcha.php index a461d9a..038d77b --- a/application/captcha.php +++ b/app/captcha.php @@ -1,61 +1,61 @@ - getFileNumber($total_contents . $count_day[$i])]; - } - - for ($i = 0; $i < count($count_day); $i++) { - // 统计每日占用空间 - $count_contents['chart_disk'][] = [$count_day[$i] => getDirectorySize($total_contents . $count_day[$i])]; - } - - if (!is_dir(APP_ROOT . '/admin/logs/counts/')) { - mkdir(APP_ROOT . '/admin/logs/counts/', 0755, true); - } - - $count_contents = json_encode($count_contents, true); - file_put_contents($chart_total_file, $count_contents); // 存储文件 - -} - -function read_chart_total() -{ - global $chart_total_file; - global $config; - - $cache_freq = $config['cache_freq']; - - if (file_exists($chart_total_file)) { - $read_chart_file = file_get_contents($chart_total_file); - $read_chart_file = json_decode($read_chart_file, true); - } else { - write_chart_total(); - $read_chart_file = file_get_contents($chart_total_file); - $read_chart_file = json_decode($read_chart_file, true); - } - - if ((date('YmdH') - $read_chart_file['date']) > $cache_freq) { - write_chart_total(); - $read_chart_file = file_get_contents($chart_total_file); - $read_chart_file = json_decode($read_chart_file, true); - } - - for ($i = 0; $i < count($read_chart_file['chart_data']); $i++) { - // 读取每日上传数量 - foreach ($read_chart_file['chart_data'][$i] as $key => $value) { - $chart_data_date[] = '"' . $key . '" ,'; - $chart_data_num[] = '"' . $value . '" ,'; - } - foreach ($read_chart_file['chart_disk'][$i] as $value) { - $value = round($value / 1024 / 1024, 2); - $chart_total_disk[] = '"' . $value . '" ,'; - } - } - return array('filename' => $read_chart_file['filename'], 'date' => $chart_data_date, 'number' => $chart_data_num, 'disk' => $chart_total_disk, 'total_time' => $read_chart_file['total_time']); -} + getFileNumber($total_contents . $count_day[$i])]; + } + + for ($i = 0; $i < count($count_day); $i++) { + // 统计每日占用空间 + $count_contents['chart_disk'][] = [$count_day[$i] => getDirectorySize($total_contents . $count_day[$i])]; + } + + if (!is_dir(APP_ROOT . '/admin/logs/counts/')) { + mkdir(APP_ROOT . '/admin/logs/counts/', 0755, true); + } + + $count_contents = json_encode($count_contents, true); + file_put_contents($chart_total_file, $count_contents); // 存储文件 + +} + +function read_chart_total() +{ + global $chart_total_file; + global $config; + + $cache_freq = $config['cache_freq']; + + if (file_exists($chart_total_file)) { + $read_chart_file = file_get_contents($chart_total_file); + $read_chart_file = json_decode($read_chart_file, true); + } else { + write_chart_total(); + $read_chart_file = file_get_contents($chart_total_file); + $read_chart_file = json_decode($read_chart_file, true); + } + + if ((date('YmdH') - $read_chart_file['date']) > $cache_freq) { + write_chart_total(); + $read_chart_file = file_get_contents($chart_total_file); + $read_chart_file = json_decode($read_chart_file, true); + } + + for ($i = 0; $i < count($read_chart_file['chart_data']); $i++) { + // 读取每日上传数量 + foreach ($read_chart_file['chart_data'][$i] as $key => $value) { + $chart_data_date[] = '"' . $key . '" ,'; + $chart_data_num[] = '"' . $value . '" ,'; + } + foreach ($read_chart_file['chart_disk'][$i] as $value) { + $value = round($value / 1024 / 1024, 2); + $chart_total_disk[] = '"' . $value . '" ,'; + } + } + return array('filename' => $read_chart_file['filename'], 'date' => $chart_data_date, 'number' => $chart_data_num, 'disk' => $chart_total_disk, 'total_time' => $read_chart_file['total_time']); +} diff --git a/application/check.php b/app/check.php old mode 100755 new mode 100644 similarity index 96% rename from application/check.php rename to app/check.php index b6ebdf6..c636cbe --- a/application/check.php +++ b/app/check.php @@ -1,92 +1,92 @@ -window.location.href="' . get_whole_url('/') . '/install/index.php"'); -} -/** 检测弹窗 */ -if (is_file(APP_ROOT . '/config/EasyIamge.lock')) return; // 查询锁定弹窗文件是否存在 -file_put_contents(APP_ROOT . '/config/EasyIamge.lock', '安装环境检测锁定文件,如需再次展示请删除此文件!', FILE_APPEND | LOCK_EX); -?> - -'); +} +/** 检测弹窗 */ +if (is_file(APP_ROOT . '/config/EasyIamge.lock')) return; // 查询锁定弹窗文件是否存在 +file_put_contents(APP_ROOT . '/config/EasyIamge.lock', '安装环境检测锁定文件,如需再次展示请删除此文件!', FILE_APPEND | LOCK_EX); +?> + + \ No newline at end of file diff --git a/application/check_admin.inc.php b/app/check_admin.inc.php old mode 100755 new mode 100644 similarity index 96% rename from application/check_admin.inc.php rename to app/check_admin.inc.php index 737fc88..e05dd7b --- a/application/check_admin.inc.php +++ b/app/check_admin.inc.php @@ -1,154 +1,154 @@ - - * 默认情况下41bit的时间戳可以支持该算法使用到2082年,10bit的工作机器id可以支持1023台机器,序列号支持1毫秒产生4095个自增序列id - * @author zhangqi - * @link https://www.cnblogs.com/njccqx/p/13402169.html - */ -class SnowFlake -{ - const EPOCH = 1479533469598; //开始时间,固定一个小于当前时间的毫秒数 - const max12bit = 4095; - const max41bit = 1099511627775; - - static $machineId = 1; // 机器id - - public static function machineId($mId = 0) - { - self::$machineId = $mId; - } - - public static function createOnlyId() - { - // 时间戳 42字节 - $time = floor(microtime(true) * 1000); - // 当前时间 与 开始时间 差值 - $time -= self::EPOCH; - // 二进制的 毫秒级时间戳 - $base = decbin(self::max41bit + $time); - // 机器id 10 字节 - if (!self::$machineId) { - $machineid = self::$machineId; - } else { - $machineid = str_pad(decbin(self::$machineId), 10, "0", STR_PAD_LEFT); - } - // 序列数 12字节 - $random = str_pad(decbin(mt_rand(0, self::max12bit)), 12, "0", STR_PAD_LEFT); - // 拼接 - $base = $base . $machineid . $random; - // 转化为 十进制 返回 - return bindec($base); - } -} -// SnowFlake::machineId("1"); //机器编号 -// echo SnowFlake::createOnlyId();//分布式id + + * 默认情况下41bit的时间戳可以支持该算法使用到2082年,10bit的工作机器id可以支持1023台机器,序列号支持1毫秒产生4095个自增序列id + * @author zhangqi + * @link https://www.cnblogs.com/njccqx/p/13402169.html + */ +class SnowFlake +{ + const EPOCH = 1479533469598; //开始时间,固定一个小于当前时间的毫秒数 + const max12bit = 4095; + const max41bit = 1099511627775; + + static $machineId = 1; // 机器id + + public static function machineId($mId = 0) + { + self::$machineId = $mId; + } + + public static function createOnlyId() + { + // 时间戳 42字节 + $time = floor(microtime(true) * 1000); + // 当前时间 与 开始时间 差值 + $time -= self::EPOCH; + // 二进制的 毫秒级时间戳 + $base = decbin(self::max41bit + $time); + // 机器id 10 字节 + if (!self::$machineId) { + $machineid = self::$machineId; + } else { + $machineid = str_pad(decbin(self::$machineId), 10, "0", STR_PAD_LEFT); + } + // 序列数 12字节 + $random = str_pad(decbin(mt_rand(0, self::max12bit)), 12, "0", STR_PAD_LEFT); + // 拼接 + $base = $base . $machineid . $random; + // 转化为 十进制 返回 + return bindec($base); + } +} +// SnowFlake::machineId("1"); //机器编号 +// echo SnowFlake::createOnlyId();//分布式id diff --git a/application/class.thumb.php b/app/class.thumb.php old mode 100755 new mode 100644 similarity index 100% rename from application/class.thumb.php rename to app/class.thumb.php diff --git a/application/class.upload.php b/app/class.upload.php old mode 100755 new mode 100644 similarity index 100% rename from application/class.upload.php rename to app/class.upload.php diff --git a/application/class.version.php b/app/class.version.php old mode 100755 new mode 100644 similarity index 96% rename from application/class.version.php rename to app/class.version.php index 54b3d6e..6d5b1d5 --- a/application/class.version.php +++ b/app/class.version.php @@ -1,87 +1,87 @@ -url = $url; - $this->dir = __DIR__ . '/../admin/logs/version/'; - $this->fileName = 'version.json'; - $this->filePath = $this->dir . $this->fileName; - $this->fileModifiTime = filemtime($this->filePath); - $this->time = time(); - } - - public function readJson($name = 'tag_name') - { - if (is_file($this->filePath)) { - - if ($this->time - $this->fileModifiTime > 864000) { - $this->downJson(); - } else { - $file = fopen($this->filePath, 'r'); - $test = fread($file, filesize($this->filePath)); - $version = json_decode($test, true); - return $version[$name]; - fclose($file); - } - } else { - $this->downJson(); - } - } - - public function downJson() - { - - if (!is_dir($this->dir)) { - mkdir($this->dir, 0755, true); - } - - $version = $this->geturl($this->url); - $version = json_decode($version, true); - $file = fopen($this->filePath, 'w+'); - fwrite($file, $version); - fclose($file); - } - - public function geturl($url) - { - $headerArray = array("Content-type:application/json;", "Accept:application/json"); - $ch = curl_init(); - curl_setopt($ch, CURLOPT_URL, $url); - curl_setopt($ch, CURLOPT_TIMEOUT_MS, 666); // 超时时间 - curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FALSE); - curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, FALSE); - curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); - curl_setopt($ch, CURLOPT_HTTPHEADER, $headerArray); - curl_setopt($ch, CURLOPT_USERAGENT, 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/86.0.4240.198 Safari/537.36'); - $output = curl_exec($ch); - curl_close($ch); - $output = json_encode($output, true); - return $output; - } -} - -/////////// TEST ///////// -/* -$url = "https://api.github.com/repositories/188228357/releases/latest"; -$test = new getVersion($url); -echo $test->readJson(); +url = $url; + $this->dir = __DIR__ . '/../admin/logs/version/'; + $this->fileName = 'version.json'; + $this->filePath = $this->dir . $this->fileName; + $this->fileModifiTime = filemtime($this->filePath); + $this->time = time(); + } + + public function readJson($name = 'tag_name') + { + if (is_file($this->filePath)) { + + if ($this->time - $this->fileModifiTime > 864000) { + $this->downJson(); + } else { + $file = fopen($this->filePath, 'r'); + $test = fread($file, filesize($this->filePath)); + $version = json_decode($test, true); + return $version[$name]; + fclose($file); + } + } else { + $this->downJson(); + } + } + + public function downJson() + { + + if (!is_dir($this->dir)) { + mkdir($this->dir, 0755, true); + } + + $version = $this->geturl($this->url); + $version = json_decode($version, true); + $file = fopen($this->filePath, 'w+'); + fwrite($file, $version); + fclose($file); + } + + public function geturl($url) + { + $headerArray = array("Content-type:application/json;", "Accept:application/json"); + $ch = curl_init(); + curl_setopt($ch, CURLOPT_URL, $url); + curl_setopt($ch, CURLOPT_TIMEOUT_MS, 666); // 超时时间 + curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FALSE); + curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, FALSE); + curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); + curl_setopt($ch, CURLOPT_HTTPHEADER, $headerArray); + curl_setopt($ch, CURLOPT_USERAGENT, 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/86.0.4240.198 Safari/537.36'); + $output = curl_exec($ch); + curl_close($ch); + $output = json_encode($output, true); + return $output; + } +} + +/////////// TEST ///////// +/* +$url = "https://api.github.com/repositories/188228357/releases/latest"; +$test = new getVersion($url); +echo $test->readJson(); */ \ No newline at end of file diff --git a/application/compress/Imagick/class.Imgcompress.php b/app/compress/Imagick/class.Imgcompress.php old mode 100755 new mode 100644 similarity index 96% rename from application/compress/Imagick/class.Imgcompress.php rename to app/compress/Imagick/class.Imgcompress.php index dabb017..c975e87 --- a/application/compress/Imagick/class.Imgcompress.php +++ b/app/compress/Imagick/class.Imgcompress.php @@ -1,123 +1,123 @@ -src = $src; - $this->percent = $percent; - } - - /** 高清压缩图片 - * @param string $saveName 提供图片名(可不带扩展名,用源图扩展名)用于保存。或不提供文件名直接显示 - */ - public function compressImg($saveName = '') - { - $this->_openImage(); - if (!empty($saveName)) $this->_saveImage($saveName); //保存 - else $this->_showImage(); - } - - /** - * 内部:打开图片 - */ - private function _openImage() - { - list($width, $height, $type, $attr) = getimagesize($this->src); - $this->imageinfo = array( - 'width' => $width, - 'height' => $height, - 'type' => image_type_to_extension($type, false), - 'attr' => $attr - ); - $fun = "imagecreatefrom" . $this->imageinfo['type']; - $this->image = $fun($this->src); - $this->_thumpImage(); - } - - /** - * 内部:操作图片 - */ - private function _thumpImage() - { - $new_width = $this->imageinfo['width'] * $this->percent; - $new_height = $this->imageinfo['height'] * $this->percent; - $image_thump = imagecreatetruecolor($new_width, $new_height); - /** - * 保留图片透明通道 - * 简单图床 EasyImage 2.0 2021-5-9 21:48:59 - * 参考: https://www.imooc.com/wenda/detail/581249 - */ - imagealphablending($image_thump, false); - imagesavealpha($image_thump, true); - - //将原图复制带图片载体上面,并且按照一定比例压缩,极大的保持了清晰度 - imagecopyresampled($image_thump, $this->image, 0, 0, 0, 0, $new_width, $new_height, $this->imageinfo['width'], $this->imageinfo['height']); - - imagedestroy($this->image); - $this->image = $image_thump; - } - - /** - * 输出图片:保存图片则用saveImage() - */ - private function _showImage() - { - header('Content-Type: image/' . $this->imageinfo['type']); - $funcs = "image" . $this->imageinfo['type']; - $funcs($this->image); - } - - /** - * 保存图片到硬盘: - * @param string $dstImgName 1、可指定字符串不带后缀的名称,使用源图扩展名 。2、直接指定目标图片名带扩展名。 - */ - private function _saveImage($dstImgName) - { - if (empty($dstImgName)) return false; - $allowImgs = array('.jpg', '.jpeg', '.png', '.bmp', '.wbmp', '.gif','.webp'); // 如果目标图片名有后缀就用目标图片扩展名 后缀,如果没有,则用源图的扩展名 - $dstExt = strrchr($dstImgName, "."); - $sourseExt = strrchr($this->src, "."); - if (!empty($dstExt)) $dstExt = strtolower($dstExt); - if (!empty($sourseExt)) $sourseExt = strtolower($sourseExt); - - //有指定目标名扩展名 - if (!empty($dstExt) && in_array($dstExt, $allowImgs)) { - $dstName = $dstImgName; - } elseif (!empty($sourseExt) && in_array($sourseExt, $allowImgs)) { - $dstName = $dstImgName . $sourseExt; - } else { - $dstName = $dstImgName . $this->imageinfo['type']; - } - $funcs = "image" . $this->imageinfo['type']; - $funcs($this->image, $dstName); - } - - /** - * 销毁图片 - */ - public function __destruct() - { - imagedestroy($this->image); - } -} +src = $src; + $this->percent = $percent; + } + + /** 高清压缩图片 + * @param string $saveName 提供图片名(可不带扩展名,用源图扩展名)用于保存。或不提供文件名直接显示 + */ + public function compressImg($saveName = '') + { + $this->_openImage(); + if (!empty($saveName)) $this->_saveImage($saveName); //保存 + else $this->_showImage(); + } + + /** + * 内部:打开图片 + */ + private function _openImage() + { + list($width, $height, $type, $attr) = getimagesize($this->src); + $this->imageinfo = array( + 'width' => $width, + 'height' => $height, + 'type' => image_type_to_extension($type, false), + 'attr' => $attr + ); + $fun = "imagecreatefrom" . $this->imageinfo['type']; + $this->image = $fun($this->src); + $this->_thumpImage(); + } + + /** + * 内部:操作图片 + */ + private function _thumpImage() + { + $new_width = $this->imageinfo['width'] * $this->percent; + $new_height = $this->imageinfo['height'] * $this->percent; + $image_thump = imagecreatetruecolor($new_width, $new_height); + /** + * 保留图片透明通道 + * 简单图床 EasyImage 2.0 2021-5-9 21:48:59 + * 参考: https://www.imooc.com/wenda/detail/581249 + */ + imagealphablending($image_thump, false); + imagesavealpha($image_thump, true); + + //将原图复制带图片载体上面,并且按照一定比例压缩,极大的保持了清晰度 + imagecopyresampled($image_thump, $this->image, 0, 0, 0, 0, $new_width, $new_height, $this->imageinfo['width'], $this->imageinfo['height']); + + imagedestroy($this->image); + $this->image = $image_thump; + } + + /** + * 输出图片:保存图片则用saveImage() + */ + private function _showImage() + { + header('Content-Type: image/' . $this->imageinfo['type']); + $funcs = "image" . $this->imageinfo['type']; + $funcs($this->image); + } + + /** + * 保存图片到硬盘: + * @param string $dstImgName 1、可指定字符串不带后缀的名称,使用源图扩展名 。2、直接指定目标图片名带扩展名。 + */ + private function _saveImage($dstImgName) + { + if (empty($dstImgName)) return false; + $allowImgs = array('.jpg', '.jpeg', '.png', '.bmp', '.wbmp', '.gif','.webp'); // 如果目标图片名有后缀就用目标图片扩展名 后缀,如果没有,则用源图的扩展名 + $dstExt = strrchr($dstImgName, "."); + $sourseExt = strrchr($this->src, "."); + if (!empty($dstExt)) $dstExt = strtolower($dstExt); + if (!empty($sourseExt)) $sourseExt = strtolower($sourseExt); + + //有指定目标名扩展名 + if (!empty($dstExt) && in_array($dstExt, $allowImgs)) { + $dstName = $dstImgName; + } elseif (!empty($sourseExt) && in_array($sourseExt, $allowImgs)) { + $dstName = $dstImgName . $sourseExt; + } else { + $dstName = $dstImgName . $this->imageinfo['type']; + } + $funcs = "image" . $this->imageinfo['type']; + $funcs($this->image, $dstName); + } + + /** + * 销毁图片 + */ + public function __destruct() + { + imagedestroy($this->image); + } +} diff --git a/application/compress/TinyImg/TinyImg.php b/app/compress/TinyImg/TinyImg.php old mode 100755 new mode 100644 similarity index 97% rename from application/compress/TinyImg/TinyImg.php rename to app/compress/TinyImg/TinyImg.php index 53b9d8f..cfdadd5 --- a/application/compress/TinyImg/TinyImg.php +++ b/app/compress/TinyImg/TinyImg.php @@ -1,76 +1,76 @@ -getFiles($inputFolder); - if (empty($images)) { - return false; - } - foreach ($images as $image) { - $input = $inputFolder . $image; - $output = $outputFolder . $image; - print($input . " => 源文件
    "); - print($output . " => 成功文件
    "); - $this->compressImg($key, $input, $output); - } - return true; - } - /*Compress one image $input and save as $output*/ - public function compressImg($key, $input, $output) - { - $url = "https://api.tinify.com/shrink"; - $options = array( - "http" => array( - "method" => "POST", - "header" => array( - "Content-type: image/png", - "Authorization: Basic " . base64_encode("api:$key") - ), - "content" => file_get_contents($input) - ), - "ssl" => array( - /* Uncomment below if you have trouble validating our SSL certificate. - Download cacert.pem from: http://curl.haxx.se/ca/cacert.pem */ - "cafile" => __DIR__ . "/cacert.pem", - "verify_peer" => true - ) - ); - - $result = fopen($url, "r", false, stream_context_create($options)); - if ($result) { - /* Compression was successful, retrieve output from Location header. */ - foreach ($http_response_header as $header) { - if (strtolower(substr($header, 0, 10)) === "location: ") { - file_put_contents($output, fopen(substr($header, 10), "rb", false)); - } - } - } else { - /* Something went wrong! */ - print("Compression failed
    "); - } - } - //get all files' fullname in $filedir - public function getFiles($filedir) - { - $files = []; - $dir = @dir($filedir); - while (($file = $dir->read()) != false) { - if ($file != "." and $file != "..") { - $files[] = $file; - } - } - $dir->close(); - return $files; - } -} +getFiles($inputFolder); + if (empty($images)) { + return false; + } + foreach ($images as $image) { + $input = $inputFolder . $image; + $output = $outputFolder . $image; + print($input . " => 源文件
    "); + print($output . " => 成功文件
    "); + $this->compressImg($key, $input, $output); + } + return true; + } + /*Compress one image $input and save as $output*/ + public function compressImg($key, $input, $output) + { + $url = "https://api.tinify.com/shrink"; + $options = array( + "http" => array( + "method" => "POST", + "header" => array( + "Content-type: image/png", + "Authorization: Basic " . base64_encode("api:$key") + ), + "content" => file_get_contents($input) + ), + "ssl" => array( + /* Uncomment below if you have trouble validating our SSL certificate. + Download cacert.pem from: http://curl.haxx.se/ca/cacert.pem */ + "cafile" => __DIR__ . "/cacert.pem", + "verify_peer" => true + ) + ); + + $result = fopen($url, "r", false, stream_context_create($options)); + if ($result) { + /* Compression was successful, retrieve output from Location header. */ + foreach ($http_response_header as $header) { + if (strtolower(substr($header, 0, 10)) === "location: ") { + file_put_contents($output, fopen(substr($header, 10), "rb", false)); + } + } + } else { + /* Something went wrong! */ + print("Compression failed
    "); + } + } + //get all files' fullname in $filedir + public function getFiles($filedir) + { + $files = []; + $dir = @dir($filedir); + while (($file = $dir->read()) != false) { + if ($file != "." and $file != "..") { + $files[] = $file; + } + } + $dir->close(); + return $files; + } +} diff --git a/application/compress/TinyImg/cacert.pem b/app/compress/TinyImg/cacert.pem old mode 100755 new mode 100644 similarity index 100% rename from application/compress/TinyImg/cacert.pem rename to app/compress/TinyImg/cacert.pem diff --git a/application/compress/function.compress.php b/app/compress/function.compress.php old mode 100755 new mode 100644 similarity index 88% rename from application/compress/function.compress.php rename to app/compress/function.compress.php index c187d3d..4652bdf --- a/application/compress/function.compress.php +++ b/app/compress/function.compress.php @@ -1,54 +1,54 @@ -compressImg($boxImg); - echo '
    ' . $boxImg . '

    '; - // 释放 - ob_flush(); - } - } - } - - if ($type == 'TinyPng') { - if (empty($config['TinyPng_key'])) { - exit('请先申请TinyPng key并保存再试!'); - } - $folder = '..' . $config['path'] . $source; - $tinyImg = new TinyImg(); - $key = $config['TinyPng_key']; - $input = $folder; //这个文件夹下的文件会被压缩 - $output = $folder; //压缩的结果会被保存到这个文件夹中 - $tinyImg->compressImgsFolder($key, $input, $output); - } -} - -/* Test -$floder = 'D:/phpStudy/WWW/i/2021/05/09/'; -compress($floder, 'TinyImg'); -echo 666; +compressImg($boxImg); + echo '
    ' . $boxImg . '

    '; + // 释放 + ob_flush(); + } + } + } + + if ($type == 'TinyPng') { + if (empty($config['TinyPng_key'])) { + exit('请先申请TinyPng key并保存再试!'); + } + $folder = '..' . $config['path'] . $source; + $tinyImg = new TinyImg(); + $key = $config['TinyPng_key']; + $input = $folder; //这个文件夹下的文件会被压缩 + $output = $folder; //压缩的结果会被保存到这个文件夹中 + $tinyImg->compressImgsFolder($key, $input, $output); + } +} + +/* Test +$floder = 'D:/phpStudy/WWW/i/2021/05/09/'; +compress($floder, 'TinyImg'); +echo 666; */ \ No newline at end of file diff --git a/application/compressing.php b/app/compressing.php old mode 100755 new mode 100644 similarity index 90% rename from application/compressing.php rename to app/compressing.php index b6d8f82..6de1505 --- a/application/compressing.php +++ b/app/compressing.php @@ -1,69 +1,69 @@ -未登陆~~
    '; - exit(require_once APP_ROOT . '/application/footer.php'); -} -// 文件夹压缩 -if (isset($_POST['folder'])) { - - $getFolder = urldecode($_POST['folder']); - - $source = $_POST['folder']; - - $type = $_POST['type']; - - $folder = '..' . $config['path'] . $getFolder; - - if (!is_dir($folder)) { - exit($folder . ''); - } - - // 压缩前 - $sizeBefor = getDirectorySize($folder); - - compress($folder, $type, $source); - - echo ' - '; -} else { - $folder = 0; - $sizeBefor = 0; -} -// 压缩后 -$sizeAfter = getDirectorySize($folder); -?> -

    压缩完毕

    -

    压缩前:压缩后: -

    -
    -无论使用哪种压缩均为不可逆操作,并且非常占用硬件资源。
    -如机器配置过低可能会导致CPU、内存飙升!
    -Imgcompress 自带压缩为轻微有损压缩图片 此压缩有可能使图片变大,特别是小图片!也有一定概率改变图片方向。
    -Imgcompress 对自身机器要求高,如图片过多会导致脚本崩溃或者超时(已经预处理超时和脚本崩溃处理,但是有概率重现)!
    -TinyPng 是 https://tinify.cn/ 提供的API,需要自行申请,对服务器要求较低,但是对网络要求高!如在国内可能导致非常慢而超时崩溃(已预处理,但是有概率重现)。
    -获取TinyPng key https://tinify.cn/developers 并填入 API 设置->TinyPng Key 文件。
    -
    - -未登陆~~
    '; + exit(require_once APP_ROOT . '/app/footer.php'); +} +// 文件夹压缩 +if (isset($_POST['folder'])) { + + $getFolder = urldecode($_POST['folder']); + + $source = $_POST['folder']; + + $type = $_POST['type']; + + $folder = '..' . $config['path'] . $getFolder; + + if (!is_dir($folder)) { + exit($folder . ''); + } + + // 压缩前 + $sizeBefor = getDirectorySize($folder); + + compress($folder, $type, $source); + + echo ' + '; +} else { + $folder = 0; + $sizeBefor = 0; +} +// 压缩后 +$sizeAfter = getDirectorySize($folder); +?> +

    压缩完毕

    +

    压缩前:压缩后: +

    +
    +无论使用哪种压缩均为不可逆操作,并且非常占用硬件资源。
    +如机器配置过低可能会导致CPU、内存飙升!
    +Imgcompress 自带压缩为轻微有损压缩图片 此压缩有可能使图片变大,特别是小图片!也有一定概率改变图片方向。
    +Imgcompress 对自身机器要求高,如图片过多会导致脚本崩溃或者超时(已经预处理超时和脚本崩溃处理,但是有概率重现)!
    +TinyPng 是 https://tinify.cn/ 提供的API,需要自行申请,对服务器要求较低,但是对网络要求高!如在国内可能导致非常慢而超时崩溃(已预处理,但是有概率重现)。
    +获取TinyPng key https://tinify.cn/developers 并填入 API 设置->TinyPng Key 文件。
    +
    + + - new $.zui.Messager("没有要删除的图片!", { - type: "danger", // 定义颜色主题 - icon: "exclamation-sign" // 定义消息图标 - }).show(); - - '; -} - -$img = rand_imgurl() . '/public/images/404.png'; -if (isset($_GET['url'])) { - $img = strip_tags($_GET['url']); -} - -// 解密删除 -if (isset($_GET['hash'])) { - $delHash = strip_tags($_GET['hash']); - $delHash = urlHash($delHash, 1); - - if ($config['image_recycl']) { - // 如果开启回收站则进入回收站 - if (checkImg($delHash, 3, 'recycle/') == true) { - echo ' - - '; - } else { - echo ' - - '; - } - } else { - // 否则直接删除 - getDel($delHash, 'url'); - } - // FTP - // any_upload($delHash, null, 'delete'); -} - -// 检查登录后再处理url删除请求 -if (is_who_login('admin')) { - - // 广场页面删除 - if (isset($_GET['url'])) { - getDel(strip_tags($_GET['url']), 'url'); - // FTP - // any_upload(parse_url($_GET['url'])['path'], null, 'delete'); - } - - // 从管理页面删除 - if (isset($_GET['url_admin_inc'])) { - $del_url = strip_tags($_GET['url_admin_inc']); - if ($config['hide_path']) { - $del_url = $config['domain'] . $config['path'] . parse_url($del_url)['path']; - } - getDel($del_url, 'url'); - // FTP - // any_upload(parse_url($del_url)['path'], null, 'delete'); - } - // 回收 - if (isset($_GET['recycle_url'])) { - $recycle_url = strip_tags($_GET['recycle_url']); - $recycle_url = parse_url($recycle_url)['path']; - if (file_exists(APP_ROOT . $recycle_url)) { - checkImg($recycle_url, 3); - echo ' - - '; - } else { - echo ' - - '; - } - } -} else { - echo ' - - '; -} -?> -
    - 简单图床-EasyImage - -
    - - -
    - - -
    - - + new $.zui.Messager("没有要删除的图片!", { + type: "danger", // 定义颜色主题 + icon: "exclamation-sign" // 定义消息图标 + }).show(); + + '; +} + +$img = rand_imgurl() . '/public/images/404.png'; +if (isset($_GET['url'])) { + $img = strip_tags($_GET['url']); +} + +// 解密删除 +if (isset($_GET['hash'])) { + $delHash = $_GET['hash']; + $delHash = urlHash($delHash, 1); + + if ($config['image_recycl']) { + // 如果开启回收站则进入回收站 + if (checkImg($delHash, 3, 'recycle/') == true) { + echo ' + + '; + } else { + echo ' + + '; + } + } else { + // 否则直接删除 + getDel($delHash, 'url'); + } +} + +// 检查登录后再处理url删除请求 +if (is_who_login('admin')) { + + // 广场页面删除 + if (isset($_GET['url'])) { + getDel($img, 'url'); + } + + // 从管理页面删除 + if (isset($_GET['url_admin_inc'])) { + $del_url = $_GET['url_admin_inc']; + if ($config['hide_path']) { + $del_url = $config['domain'] . $config['path'] . parse_url($del_url)['path']; + } + getDel($del_url, 'url'); + } + // 回收 + if (isset($_GET['recycle_url'])) { + $recycle_url = $_GET['recycle_url']; + $recycle_url = parse_url($recycle_url)['path']; + if (file_exists(APP_ROOT . $recycle_url)) { + checkImg($recycle_url, 3); + echo ' + + '; + } else { + echo ' + + '; + } + } +} else { + if (isset($_GET['url'])) { + echo ' + + '; + } +} +?> +
    + 简单图床-EasyImage +
    +
    + + +
    + +
    +
    + + 0) : ?> - - - - - -
    - - - - - - - + 0) : ?> + + + + + +
    + + + + + + + \ No newline at end of file diff --git a/application/function.php b/app/function.php old mode 100755 new mode 100644 similarity index 96% rename from application/function.php rename to app/function.php index f686883..32263f1 --- a/application/function.php +++ b/app/function.php @@ -1,1761 +1,1760 @@ -> 1) & 1) ? true : false; - } - fclose($fh); - return $result; - */ -} - -/** - * 判断webp或gif动图是否为动态图片 - * @param $src 图片的绝对路径 - * @return bool 是|否 - */ -function is_Gif_Webp_Animated($src) -{ - $ext = pathinfo($src)['extension']; - - if ($ext == 'webp') { - $webpContents = file_get_contents($src); - $where = strpos($webpContents, "ANMF"); - if ($where !== FALSE) { - // animated - return true; - } - return false; - } - - $fp = fopen($src, 'rb'); - $filecontent = fread($fp, filesize($src)); - fclose($fp); - return strpos($filecontent, chr(0x21) . chr(0xff) . chr(0x0b) . 'NETSCAPE2.0') === FALSE ? false : true; -} - - -/** - * 2023-01-06 校验登录 - * @param $user String 登录用户名 - * @param $password 登录密码 - * 返回参数解析 code=>状态码 200成功,400失败; 登录用户级别level => 0无状态, 1管理员, 2上传者, messege => 提示信息 - */ - -function _login($user = null, $password = null) -{ - global $config; - global $guestConfig; - - // cookie验证 - if ($user === null and $password === null) { - // 无cookie - if (empty($_COOKIE['auth'])) { - return json_encode(array('code' => 400, 'level' => 0, 'messege' => '请登录')); - } - // 存在cookie - if (isset($_COOKIE['auth'])) { - $browser_cookie = json_decode($_COOKIE['auth']); - - // cookie无法读取 - if (!$browser_cookie) return json_encode(array('code' => 400, 'level' => 0, 'messege' => '登录已过期,请重新登录')); - // 判断账号是否存在 - if ($browser_cookie[0] !== $config['user'] && !array_key_exists($browser_cookie[0], $guestConfig)) return json_encode(array('code' => 400, 'level' => 0, 'messege' => '账号不存在')); - // 判断是否管理员 - if ($browser_cookie[0] === $config['user'] && $browser_cookie[1] === $config['password']) return json_encode(array('code' => 200, 'level' => 1, 'messege' => '尊敬的管理员')); - // 判断是否上传者 - if (array_key_exists($browser_cookie[0], $guestConfig) && $browser_cookie[1] === $guestConfig[$browser_cookie[0]]['password']) { - // 判断上车者是否过期 - if ($guestConfig[$browser_cookie[0]]['expired'] < time()) { - // 上传者账户密码正确,但是账户过期 - return json_encode(array('code' => 400, 'level' => 0, 'messege' => $browser_cookie[0] . '账号已过期')); - } - return json_encode(array('code' => 200, 'level' => 2, 'messege' => $browser_cookie[0] . '用户已登录')); - } - // 账号存在,密码错误 - if ($browser_cookie[0] === $config['user'] || array_key_exists($browser_cookie[0], $guestConfig)) return json_encode(array('code' => 400, 'level' => 0, 'messege' => '密码错误')); - } - } - - // 前端验证 - $user = strip_tags($user); - $password = strip_tags($password); - // 是否管理员 - if ($user === $config['user'] && $password === $config['password']) { - // 将账号密码序列化后存储 - $browser_cookie = json_encode(array($user, $password)); - setcookie('auth', $browser_cookie, time() + 3600 * 24 * 14, '/'); - return json_encode(array('code' => 200, 'level' => 1, 'messege' => '管理员登录成功')); - } - // 是否上传者 - if (array_key_exists($user, $guestConfig) && $password === $guestConfig[$user]['password']) { - // 上传者账号过期 - if ($guestConfig[$user]['expired'] < time()) return json_encode(array('code' => 400, 'level' => 0, 'messege' => $user . '账号已过期')); - // 未过期设置cookie - $browser_cookie = json_encode(array($user, $password)); - setcookie('auth', $browser_cookie, time() + 3600 * 24 * 14, '/'); - return json_encode(array('code' => 200, 'level' => 2, 'messege' => $user . '用户登录成功')); - } - // 检查账号是否存在 - if (array_key_exists($user, $guestConfig) || $user === $config['user']) { - // 账号存在,密码错误 - if ($user === $config['user'] || array_key_exists($user, $guestConfig)) return json_encode(array('code' => 400, 'level' => 0, 'messege' => '密码错误')); - } else { - return json_encode(array('code' => 400, 'level' => 0, 'messege' => '账号不存在')); - } - - // 未知错误 - return json_encode(array('code' => 400, 'level' => 0, 'messege' => '未知错误')); -} - -/** - * 校验登录 2023-01-05弃用 - */ -function checkLogin() -{ - global $guestConfig; - global $config; - - // 无cookie - if (empty($_COOKIE['auth'])) { - return 201; - } - - // 存在cookie - if (isset($_COOKIE['auth'])) { - - $getCOK = json_decode($_COOKIE['auth']); - - // 无法读取cookie - if (!$getCOK) { - return 202; - } - - // 密码错误 - if ($getCOK[1] !== $config['password'] && $getCOK[1] !== $guestConfig[$getCOK[0]]['password']) { - return 203; - } - - // 管理员登陆 - if ($getCOK[0] === $config['user'] && $getCOK[1] === $config['password']) { - return 204; - } - - // 上传者账号登陆 - if ($getCOK[1] === $guestConfig[$getCOK[0]]['password']) { - if ($guestConfig[$getCOK[0]]['expired'] < time()) { - // 上传者账号过期 - return 206; - } - return 205; - } - } -} - -/** - * 2023-01-06 仅允许登录上传 - */ -function mustLogin() -{ - global $config; - if ($config['mustLogin']) { - $status = _login(); - $status = json_decode($status, true); - - if ($status['code'] === 200) { - echo ' - '; - } - - if ($status['code'] === 400) { - echo ' - '; - header("refresh:2;url=" . $config['domain'] . "/admin/index.php"); - } - } -} - -/** - * 检查配置文件中目录是否存在是否可写并创建相应目录 - * @param null $path 要创建的路径 - * @return string - */ -function config_path($path = null) -{ - global $config; - - if (empty($path)) { - if (array_key_exists('storage_path', $config)) { - $path = date($config['storage_path']); - } else { - $path = date('Y/m/d/'); - } - } - // 2023-01-06弃用 php5.6 兼容写法: - // $path = isset($path) ? $path : date('Y/m/d/'); - // php7.0 $path = $path ?? date('Y/m/d/'); - - $img_path = $config['path'] . $path; - - if (!is_dir($img_path)) { - @mkdir($img_path, 0755, true); - } - - if (!is_writable($img_path)) { - @chmod($img_path, 0755); - } - - return $img_path; -} - -/** - * 图片命名规则 - * @param null $source 源文件名称 - * @return false|int|string|null - */ -function imgName($source = null) -{ - global $config; - - function create_guid() // guid生成函数 - { - if (function_exists('com_create_guid') === true) { - return trim(com_create_guid(), '{}'); - } - - return sprintf('%04X%04X-%04X-%04X-%04X-%04X%04X%04X', mt_rand(0, 65535), mt_rand(0, 65535), mt_rand(0, 65535), mt_rand(16384, 20479), mt_rand(32768, 49151), mt_rand(0, 65535), mt_rand(0, 65535), mt_rand(0, 65535)); - } - - function uuid() // 生成uuid - { - $chars = md5(uniqid(mt_rand(), true)); - return substr($chars, 0, 8) . '-' . substr($chars, 8, 4) . '-' . substr($chars, 12, 4) . '-' . substr($chars, 16, 4) . '-' . substr($chars, 20, 12); // return $uuid; - } - - switch ($config['imgName']) { - - case "default": - return base_convert(date('His') . mt_rand(1001, 9999), 10, 36); // 将上传时间+随机数转换为36进制 例:vx77yu - break; - case "source": - // 以上传文件名称 例:微信图片_20211228214754 - // 过滤非法名称 $source = preg_replace("/\/|\~|\!|\@|\#|\\$|\%|\^|\&|\*|\(|\)|\_|\+|\{|\}|\:|\<|\>|\?|\[|\]|\,|\.|\/|\;|\'|\`|\-|\=|\\\|\|/","",$source); - return $source; - break; - case "date": - // 以上传时间 例:192704 - return date("His"); - break; - case "unix": - // 以Unix时间 例:1635074840 - return time(); - break; - case "uniqid": - // 基于以微秒计的当前时间 例:6175436c73418 - return uniqid(true); - break; - case "guid": - // 全球唯一标识符 例:6EDAD0CC-AB0C-4F61-BCCA-05FAD65BF0FA - return create_guid(); - break; - case "md5": - // md5加密时间 例:3888aa69eb321a2b61fcc63520bf6c82 - return md5(microtime()); - break; - case "sha1": - // sha1加密微秒 例:654faac01499e0cb5fb0e9d78b21e234c63d842a - return sha1(microtime()); - break; - case "crc32": - // crc32加密微秒 例:2495551279 - return crc32(microtime()); - break; - case "snowflake": - include __DIR__ . '/class.snowflake.php'; - return SnowFlake::createOnlyId(); // 分布式id - break; - case "uuid": - return uuid(); // uuid - break; - default: - return base_convert(date('His') . mt_rand(1001, 9999), 10, 36); // 将上传时间+随机数转换为36进制 例:vx77yu - } -} - -/** - * 静态文件CDN - */ -function static_cdn() -{ - global $config; - if ($config['static_cdn']) { - echo $config['static_cdn_url']; - } else { - echo $config['domain']; - } -} - -/** - * 获取允许上传的扩展名 - */ -function getExtensions() -{ - global $config; - $arr = explode(',', $config['extensions']); - $mime = ''; - for ($i = 0; $i < count($arr); $i++) { - $mime .= $arr . ','; - } - return rtrim($mime, ','); -} - -/** - * 获取目录大小 如果目录文件较多将很费时 - * @param $path string 路径 - * @return int - */ -function getDirectorySize($path) -{ - $bytestotal = 0; - $path = realpath($path); - if ($path !== false && $path != '' && file_exists($path)) { - foreach (new RecursiveIteratorIterator(new RecursiveDirectoryIterator($path, FilesystemIterator::SKIP_DOTS)) as $object) { - $bytestotal += $object->getSize(); - } - } - return $bytestotal; -} - -/** - * 获取指定文件夹文件数量 - * @param $dir 传入一个路径如:/apps/web - * @return int 返回文件数量 - */ -function getFileNumber($dir) -{ - $num = 0; - $arr = glob($dir); - foreach ($arr as $v) { - if (is_file($v)) { - $num++; - } else { - $num += getFileNumber($v . "/*"); - } - } - return $num; -} - -/** - * 图片展示页面 - * getDir()取文件夹列表,getFile()取对应文件夹下面的文件列表,二者的区别在于判断有没有“.”后缀的文件,其他都一样 - * 获取文件目录列表,该方法返回数组 - * @param $dir string 路径 - * @return mixed - * @example getDir("./dir") - */ -function getDirList($dir) -{ - $dirArray[] = NULL; - if (false != ($handle = opendir($dir))) { - $i = 0; - while (false !== ($file = readdir($handle))) { - //去掉"“.”、“..”以及带“.xxx”后缀的文件 - if ($file != "." && $file != ".." && !strpos($file, ".")) { - $dirArray[$i] = $file; - $i++; - } - } - //关闭句柄 - closedir($handle); - } - return $dirArray; -} - -/** - * 获取文件列表 - * @param $dir string 目录 - * @return mixed - */ -function getFile($dir) -{ - $fileArray[] = NULL; - if (is_dir($dir)) { - if (false != ($handle = opendir($dir))) { - $i = 0; - while (false !== ($file = readdir($handle))) { - //去掉"“.”、“..”以及带“.xxx”后缀的文件 - if ($file != "." && $file != ".." && strpos($file, ".")) { - $fileArray[$i] = $file; - if ($i == 1000) { - break; - } - $i++; - } - } - //关闭句柄 - closedir($handle); - } - } - return $fileArray; -} - -/** - * 获取文件夹文件列表或数量 - * @param string $dir_fileName_suffix 获取文件列表:目录+文件名*:全匹配+文件后缀 *: 全匹配 {jpg,png,gif}:匹配指定格式 - * 递归文件数量:目录 - * @example get_file_by_glob(__DIR__ . '/i/cache/*.*', $type = 'list'); // 获取目录文件列表 - * @example get_file_by_glob(__DIR__ . '/i/', $type = 'number'); // 递归获取文件夹数量 - * @param string $type list|number 返回列表还是数量 - * @return array|int 返回数组|数量 - */ -function get_file_by_glob($dir_fileName_suffix, $type = 'list') -{ - global $config; - - // 获取所有文件 - if ($type == 'list') { - $glob = glob($dir_fileName_suffix, GLOB_BRACE); - - if ($glob) { - foreach ($glob as $v) { - if (is_file($v)) $res[] = basename($v); - } - // 排序 - if ($res) { - switch ($config['showSort']) { - case 1: - $res = array_reverse($res); - break; - } - } - } else { - $res = array(); - } - } - - if ($type == 'number') { - $res = 0; - $glob = glob($dir_fileName_suffix); //把该路径下所有的文件存到一个数组里面; - if ($glob) { - foreach ($glob as $v) { - if (is_file($v)) { - $res++; - } else { - $res += get_file_by_glob($v . "/*", $type = 'number'); - } - } - } else { - $res = 0; - } - } - return $res; -} - -/** - * 递归函数实现遍历指定文件下的目录与文件数量 - * 用来统计一个目录下的文件和目录的个数 - * echo "目录数为:{$dirn}
    "; - * echo "文件数为:{$filen}
    "; - * @param $file string 目录 - */ -function getdirnum($file) -{ - $dirn = 0; //目录数 - $filen = 0; //文件数 - $dir = opendir($file); - while ($filename = readdir($dir)) { - if ($filename != "." && $filename != "..") { - $filename = $file . "/" . $filename; - if (is_dir($filename)) { - $dirn++; - getdirnum($filename); - //递归,就可以查看所有子目录 - } else { - $filen++; - } - } - } - closedir($dir); -} - -/** - * 把文件或目录的大小转化为容易读的方式 - * disk_free_space - 磁盘可用空间(比如填写D盘某文件夹,则会现在D盘剩余空间) - * disk_total_space — 磁盘总空间(比如填写D盘某文件夹,则会现在D盘总空间) - * @param $number - * @return string - */ -function getDistUsed($number) -{ - $dw = ''; // 指定文件或目录统计的单位方式 - if ($number > pow(2, 30)) { - $dw = "GB"; - $number = round($number / pow(2, 30), 2); - } else if ($number > pow(2, 20)) { - $dw = "MB"; - $number = round($number / pow(2, 20), 2); - } else if ($number > pow(2, 10)) { - $dw = "KB"; - $number = round($number / pow(2, 10), 2); - } else { - $dw = "bytes"; - } - return $number . $dw; -} - -/** - * 加密/解密图片路径 - * @param string $data 要加密的内容 - * @param int $mode =1或0 1解密 0加密 - * @param String $key 盐 - */ -function urlHash($data, $mode, $key = null) -{ - global $config; - - if (!$key) { - $key = crc32($config['password']); - } - - $iv = 'sciCuBC7orQtDhTO'; - if ($mode) { - return openssl_decrypt(base64_decode($data), "AES-128-XTS", $key, 0, $iv); - } else { - return base64_encode(openssl_encrypt($data, "AES-128-XTS", $key, 0, $iv)); - } -} - -/** - * 删除指定文件 - * @param $url string 文件 - * @param $type string 模式 - */ -function getDel($url, $type) -{ - global $config; - // url本地化 - $url = htmlspecialchars(str_replace($config['domain'], '', $url)); // 过滤html 获取url path - $url = urldecode(trim($url)); - - if ($type == 'url') { - $url = $_SERVER['DOCUMENT_ROOT'] . $url; - } - if ($type == 'hash') { - $url = APP_ROOT . $url; - } - - // 文件是否存在 限制删除目录 - if (is_file($url) && strrpos($url, $config['path'])) { - // 执行删除 - if (@unlink($url)) { - echo ' - - '; - } else { - echo ' - - '; - } - } else { - echo ' - - '; - } - // 清除查询 - clearstatcache(); -} - -/** - * 判断是否此用户登录 - * @param string $user 判断登录者权限 当$user=null 时检查是否登录, 不区分身份 - * @return bool 是|否 - */ -function is_who_login($user) -{ - // 将状态转码 - $status = json_decode(_login(), true); - // 查询是否登录 - if ($user === 'status') if ($status['level'] > 0) return true; - // 是否管理员登录 - if ($user === 'admin') if ($status['level'] == 1) return true; - // 是否上传者登录 - if ($user === 'guest') if ($status['level'] == 2) return true; - - return false; -} - -/** - * 检查PHP缺少简单图床必备的扩展 - * 需检测的扩展:'fileinfo', 'iconv', 'gd', 'mbstring', 'openssl','zip', - * zip 扩展不是必须的,但会影响tinyfilemanager文件压缩(本次不检测)。 - * - * 检测是否更改默认域名 - * - * 检测是否修改默认密码 - * @param $mode bool 是否开启检测 - */ -function checkEnv($mode) -{ - // 初始化安装 - if (!is_file(APP_ROOT . '/config/install.lock') and is_file(APP_ROOT . '/install/install.php')) { - echo ''; - } - - if ($mode) { - require_once __DIR__ . '/check.php'; - } -} - -/** - * 前端改变图片长宽 - * @return string 裁剪参数 - */ -function imgRatio() -{ - global $config; - if ($config['imgRatio']) { - - if ($config['imgRatio_crop'] === 1) { - $imgRatio_crop = 'true'; - } else { - $imgRatio_crop = 'false'; - } - - if ($config['imgRatio_preserve_headers'] === 1) { - $imgRatio_preserve_headers = 'true'; - } else { - $imgRatio_preserve_headers = 'false'; - } - - if ($config['image_x'] != 0) { - $image_x = "width:" . $config['image_x'] . ','; - } else { - $image_x = null; - } - - if ($config['image_y'] != 0) { - $image_y = "height:" . $config['image_y'] . ','; - } else { - $image_y = null; - } - - return ' - resize:{ - ' . $image_x . ' - ' . $image_y . ' - crop: ' . $imgRatio_crop . ', - quality:' . $config['imgRatio_quality'] . ', - preserve_headers: ' . $imgRatio_preserve_headers . ', - }'; - } else { - return "file_data_name:'file'"; - } -} - -/** - * 定时获取GitHub 最新版本 - * @return mixed|null 读取版本信息 - */ -function getVersion($name = 'tag_name') -{ - global $config; - - if ($config['checkEnv']) { - require_once APP_ROOT . '/application/class.version.php'; - $url = "https://api.github.com/repositories/188228357/releases/latest"; // 获取版本地址 - $getVersion = new getVersion($url); - try { - if (!empty($getVersion->readJson($name))) { - return $getVersion->readJson($name); // 返回版本信息 - } else { - return '存在版本文件, 但是内容为空,请等待1小时候后再次更新版本号!'; - } - } catch (Throwable $e) { - $getVersion->downJson(); // 获取版本信息 - return '获取版本文件失败,请检查curl或者网络 错误信息: ' . $e->getMessage(); - } - } else { - return '已关闭环境自检, 当前版本:' . get_current_version(); - } -} - -/** - * 删除非空目录 - * @param $dir string 要删除的目录 - * @return bool true|false - */ -function deldir($dir) -{ - if (file_exists($dir)) { - $files = scandir($dir); - foreach ($files as $file) { - if ($file != '.' && $file != '..') { - $path = $dir . '/' . $file; - if (is_dir($path)) { - deldir($path); - } else { - unlink($path); - } - } - } - rmdir($dir); - return true; - } else { - return false; - } -} - -/** - * 图片监黄curl 访问网站并返回解码过的json信息 - * @param $img string 图片url - * @param null $url 访问的网址 - * @return mixed - */ -function moderatecontent_json($img, $url = null) -{ - global $config; - - if (empty($config['moderatecontent_key'])) { - exit; - } - - $url = 'https://api.moderatecontent.com/moderate/?key=' . $config['moderatecontent_key'] . '&url=' . $img; - $headerArray = array("Content-type:application/json;", "Accept:application/json"); - $ch = curl_init(); - curl_setopt($ch, CURLOPT_URL, $url); - curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FALSE); - curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, FALSE); - curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); - curl_setopt($ch, CURLOPT_HTTPHEADER, $headerArray); - curl_setopt($ch, CURLOPT_TIMEOUT, 30); - curl_setopt($ch, CURLOPT_USERAGENT, 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/86.0.4240.198 Safari/537.36'); - $output = curl_exec($ch); - curl_close($ch); - $output = json_decode($output, true); - return $output; -} - -/** - * 使用curl方式实现get或post请求 - * @param $url 请求的url地址 - * @param $data 发送的post数据 如果为空则为get方式请求 - * return 请求后获取到的数据 - */ - -function nsfwjs_json($url, $data = '') -{ - global $config; - - if (empty($config['nsfwjs_url'])) { - exit; - } - - $ch = curl_init(); - $params[CURLOPT_URL] = $config['nsfwjs_url'] . $url; //请求url地址 - $params[CURLOPT_HEADER] = false; //是否返回响应头信息 - $params[CURLOPT_RETURNTRANSFER] = true; //是否将结果返回 - $params[CURLOPT_FOLLOWLOCATION] = true; //是否重定向 - $params[CURLOPT_TIMEOUT] = 30; //超时时间 - if (!empty($data)) { - $params[CURLOPT_POST] = true; - $params[CURLOPT_POSTFIELDS] = $data; - } - $params[CURLOPT_SSL_VERIFYPEER] = false; //请求https时设置,还有其他解决方案 - $params[CURLOPT_SSL_VERIFYHOST] = false; //请求https时,其他方案查看其他博文 - curl_setopt_array($ch, $params); //传入curl参数 - $content = curl_exec($ch); //执行 - curl_close($ch); //关闭连接 - $content = json_decode($content, true); - return $content; -} - -/** - * 检查图片是否违规 - * @param $imageUrl 图片链接 - * @param int $type 模式: 1|moderatecontent 2|nsfwjs 3|移入回收站 - * @param string $dir 移入的目录 - * @return bool - */ -function checkImg($imageUrl, $type = 1, $dir = 'suspic/') -{ - global $config; - - /** # 使用moderatecontent */ - if ($type == 1) { - $response = moderatecontent_json($imageUrl); - if ($response['rating_index'] == 3 or $response['predictions']['adult'] > $config['checkImg_value']) { // (1 = everyone, 2 = teen, 3 = adult) - $bad_pic = true; - } - } - - /** # 使用nsfwjs */ - if ($type == 2) { - /** - * probability,概率 - * className,类型 - * - * 上传图片后,总共会返回 5 个维度的数值来鉴别该图片的尺度: - * - * 绘画(Drawing)—— 无害的艺术,或艺术绘画; - * 变态(Hentai)—— 色情艺术,不适合大多数工作环境; - * 中立(Neutral)—— 一般,无害的内容; - * 色情(Porn)—— 不雅的内容和行为,通常涉及生殖器; - * 性感(Sexy)—— 不合时宜的挑衅内容。 - * - * 当porn评分超过>=0.6左右,就几乎是一张带有色情性质的图片了。 - */ - - $file = nsfwjs_json($imageUrl); - - // 将获取的值删除className后组建数组 - for ($i = 0; $i <= count($file); $i++) { - if ($file[$i]['className'] == 'Drawing') { - $res['Drawing'] = $file[$i]['probability']; - } - if ($file[$i]['className'] == 'Hentai') { - $res['Hentai'] = $file[$i]['probability']; - } - if ($file[$i]['className'] == 'Neutral') { - $res['Neutral'] = $file[$i]['probability']; - } - if ($file[$i]['className'] == 'Porn') { - $res['Porn'] = $file[$i]['probability']; - } - if ($file[$i]['className'] == 'Sexy') { - $res['Sexy'] = $file[$i]['probability']; - } - } - - // 测试数组是否正确 - // foreach ($file as $k => $v) { - // foreach ($v as $k1 => $v1) { - // echo $k1 . '=>' . $v1 . '
    '; - // } - // } - - if ($res['Sexy'] * 100 > $config['checkImg_value'] or $res['Porn'] * 100 > $config['checkImg_value']) { - $bad_pic = true; - } - } - - // 移入回收站 - if ($type == 3) { - $bad_pic = true; - $dir = 'recycle/'; - } - - /** # 如果违规则移动图片到违规文件夹 */ - if ($bad_pic == true) { - $old_path = APP_ROOT . parse_url($imageUrl)['path']; // 提交网址中的文件路径 /i/2021/10/29/p8vypd.png - $name = parse_url($imageUrl)['path']; // 获得图片的相对地址 - $name = str_replace($config['path'], '', $name); // 去除 path目录 - $name = str_replace('/', '_', $name); // 文件名 2021_10_30_p8vypd.png - $new_path = APP_ROOT . $config['path'] . $dir . $name; // 新路径含文件名 - $suspic_dir = APP_ROOT . $config['path'] . $dir; // suspic路径 - - if (!is_dir($suspic_dir)) { // 创建suspic目录并移动 - mkdir($suspic_dir, 0777, true); - } - if (is_file($old_path)) { - rename($old_path, $new_path); - return true; - } else { - return false; - } - } -} - -/** - * 还原被审查的图片 - * @param $name string 要还原的图片 - */ -function re_checkImg($name, $dir = 'suspic/') -{ - global $config; - - $fileToPath = str_replace('_', '/', $name); // 将图片名称还原为带路径的名称,eg:2021_11_03_pbmn1a.jpg =>2021/11/03/pbmn1a.jpg - $now_path_file = APP_ROOT . $config['path'] . $dir . $name; // 当前图片绝对位置 */i/suspic/2021_10_30_p8vypd.png - if (is_file($now_path_file)) { - $to_file = APP_ROOT . $config['path'] . $fileToPath; // 要还原图片的绝对位置 */i/2021/10/30/p8vypd.png - rename($now_path_file, $to_file); // 移动文件 - return true; - } -} - -/** - * 创建缩略图 - * @param $imgName string 需要创建缩略图的名称 - */ -function creat_thumbnail_images($imgName) -{ - require_once __DIR__ . '/class.thumb.php'; - global $config; - - $old_img_path = APP_ROOT . config_path() . $imgName; // 获取要创建缩略图文件的绝对路径 - $cache_path = APP_ROOT . $config['path'] . 'cache/'; // cache目录的绝对路径 - - if (!is_dir($cache_path)) { // 创建cache目录 - mkdir($cache_path, 0777, true); - } - if (!isGifAnimated($old_img_path)) { // 仅针对非gif创建图片缩略图 - $new_imgName = APP_ROOT . $config['path'] . 'cache/' . date('Y_m_d') . '_' . $imgName; // 缩略图缓存的绝对路径 - Thumb::out($old_img_path, $new_imgName, $config['thumbnail_w'], $config['thumbnail_h']); // 保存缩略图 - } -} - -/** - * 根据请求网址路径返回缩略图网址 - * @param $url string 图片链接 - * @return string - */ -function return_thumbnail_images($url) -{ - global $config; - $cache_image_file = str_replace($config['imgurl'], '', $url); - - if (isGifAnimated(APP_ROOT . $cache_image_file)) { // 仅读取非gif的缩略图 - return $url; // 如果是gif则直接返回url - } else { - $cache_image_file = str_replace($config['path'], '', $cache_image_file); // 将网址中的/i/去除 - $cache_image_file = str_replace('/', '_', $cache_image_file); // 将文件的/转换为_ - $isFile = APP_ROOT . $config['path'] . 'cache/' . $cache_image_file; // 缓存文件的绝对路径 - if (file_exists($isFile)) { // 缓存文件是否存在 - return $config['imgurl'] . $config['path'] . 'cache/' . $cache_image_file; // 存在则返回缓存文件 - } else { - return $url; // 不存在直接返回url - } - } -} - -/** - * 在线输出缩略图 - * @param $imgUrl string 图片链接 - * @return string 缩略图链接 - */ -function get_online_thumbnail($imgUrl) -{ - global $config; - if ($config['thumbnail']) { - $imgUrl = str_replace($config['domain'], '', $imgUrl); - return $config['domain'] . '/application/thumb.php?img=' . $imgUrl; - } - - return $imgUrl; -} - -/** - * 用户浏览广场的时候生成缩略图,由此解决上传生成缩略图时服务器超时响应 - * @param $imgUrl string 源图片网址 - * @return string 缩略图地址 - */ -function creat_thumbnail_by_list($imgUrl) -{ - - global $config; - ini_set('max_execution_time', '300'); // 脚本运行的时间(以秒为单位)0不限制 - - // 过滤非指定格式 - if (!in_array(pathinfo($imgUrl, PATHINFO_EXTENSION), array('png', 'gif', 'jpeg', 'jpg', 'webp', 'bmp'))) { - // ico格式直接返回直链 - if (pathinfo($imgUrl, PATHINFO_EXTENSION) === 'ico') return $imgUrl; - // 其他格式直接返回指定图标 - return '../public/images/file.svg'; - } - - switch ($config['thumbnail']) { - // 输出原图 - case 0: - return $imgUrl; - break; - // 访问生成 - case 1: - return get_online_thumbnail($imgUrl); - break; - } - - // 将网址图片转换为相对路径 - $pathName = parse_url($imgUrl, PHP_URL_PATH); - // 图片绝对路径 - $abPathName = APP_ROOT . $pathName; - // 将网址中的/i/去除 - $pathName = str_replace($config['path'], '', $pathName); - // 将文件的/转换为_ - $thumbnail = str_replace('/', '_', $pathName); - - // 缓存文件是否存在 - if (is_file(APP_ROOT . $config['path'] . 'cache/' . $thumbnail)) { - // 存在则返回缓存文件 - return $config['domain'] . $config['path'] . 'cache/' . $thumbnail; - } else { - - // 如果图像是gif则直接返回网址 - if (isGifAnimated($abPathName)) { - return $imgUrl; - } - // 如果是webp动图则直接返回网址 - if (isWebpAnimated($abPathName)) { - return $imgUrl; - } - - /** 创建缓存文件并输出文件链接 */ - - // thumbnails目录的绝对路径 - $cache_path = APP_ROOT . $config['path'] . 'cache/'; - // 创建cache目录 - if (!is_dir($cache_path)) { - mkdir($cache_path, 0755, true); - } - // 缩略图缓存的绝对路径 $imgName 是不带/i/的相对路径 - $new_imgName = $cache_path . $thumbnail; - // 创建并保存缩略图 - if ($config['thumbnail'] == 2) { - require_once __DIR__ . '/Zebra_Image.php'; - $image = new Zebra_Image(); - $image->source_path = $abPathName; - $image->target_path = $new_imgName; - $image->resize($config['thumbnail_w'], $config['thumbnail_h'], ZEBRA_IMAGE_CROP_CENTER); - } else { - require_once __DIR__ . '/class.thumb.php'; - Thumb::out($abPathName, $new_imgName, $config['thumbnail_w'], $config['thumbnail_h']); - } - - // 输出缩略图 - return $new_imgName; - } -} - -/** - * 获取当前页面完整URL地址 - * https://www.php.cn/php-weizijiaocheng-28181.html - * @param null $search string 返回指定搜索文字之前的内容(不含搜索文字) - * @return false|string 返回读取网址 - */ -function get_whole_url($search = null) -{ - $sys_protocal = isset($_SERVER['SERVER_PORT']) && $_SERVER['SERVER_PORT'] == '443' ? 'https://' : 'http://'; - $php_self = isset($_SERVER['SCRIPT_NAME']) ? $_SERVER['SCRIPT_NAME'] : $_SERVER['SCRIPT_NAME']; - $path_info = isset($_SERVER['PATH_INFO']) ? $_SERVER['PATH_INFO'] : ''; - $relate_url = isset($_SERVER['REQUEST_URI']) ? $_SERVER['REQUEST_URI'] : $php_self . (isset($_SERVER['QUERY_STRING']) ? '?' . $_SERVER['QUERY_STRING'] : $path_info); - $whole_domain = $sys_protocal . (isset($_SERVER['HTTP_HOST']) ? $_SERVER['HTTP_HOST'] : '') . $relate_url; - if ($search) { - // 返回指定符号之前 - return substr($whole_domain, 0, strrpos($whole_domain, $search)); - } - return $whole_domain; -} - -/** - * 配置写入 - * @param $filename string 要存储的源文件名称 - * @param $values array 获取到的数组 - * @param string $var 源文件的数组名称 - * @param bool $format 不知道啥作用 - * @return bool - */ -function cache_write($filename, $values, $var = 'config', $format = false) -{ - $cachefile = $filename; - $cachetext = " $val) { - $key = is_string($key) ? '\'' . addcslashes($key, '\'\\') . '\'' : $key; - $val = !is_array($val) && (!preg_match('/^\-?\d+$/', $val) || strlen($val) > 12) ? '\'' . addcslashes($val, '\'\\') . '\'' : $val; - if (is_array($val)) { - $evaluate .= $comma . $key . '=>' . arrayeval($val, $format, $level + 1); - } else { - $evaluate .= $comma . $key . '=>' . $val; - } - $comma = ',' . $line . $space; - } - $evaluate .= $line . $space . ')'; - return $evaluate; -} - -/** - * 配置写入文件 - * @param $filename string 要写入的文件名 - * @param $writetext array 要写入的文字 - * @param string $openmod 写文件模式 - * @return bool - */ -function writefile($filename, $writetext, $openmod = 'w') -{ - if (false !== $fp = fopen($filename, $openmod)) { - flock($fp, 2); - fwrite($fp, $writetext); - fclose($fp); - return true; - } else { - return false; - } -} - -/** - * 获得用户的真实IP地址 - * 来源:ecshop - * @return mixed|string string - */ -function real_ip() -{ - static $realip = NULL; - if ($realip !== NULL) { - return $realip; - } - if (isset($_SERVER)) { - if (isset($_SERVER['HTTP_X_FORWARDED_FOR'])) { - $arr = explode(',', $_SERVER['HTTP_X_FORWARDED_FOR']); - /* 取X-Forwarded-For中第一个非unknown的有效IP字符串 */ - foreach ($arr as $ip) { - $ip = trim($ip); - - if ($ip != 'unknown') { - $realip = $ip; - - break; - } - } - } elseif (isset($_SERVER['HTTP_CLIENT_IP'])) { - $realip = $_SERVER['HTTP_CLIENT_IP']; - } else { - if (isset($_SERVER['REMOTE_ADDR'])) { - $realip = $_SERVER['REMOTE_ADDR']; - } else { - $realip = '0.0.0.0'; - } - } - } else { - if (getenv('HTTP_X_FORWARDED_FOR')) { - $realip = getenv('HTTP_X_FORWARDED_FOR'); - } elseif (getenv('HTTP_CLIENT_IP')) { - $realip = getenv('HTTP_CLIENT_IP'); - } else { - $realip = getenv('REMOTE_ADDR'); - } - } - // 使用正则验证IP地址的有效性,防止伪造IP地址进行SQL注入攻击 - preg_match("/[\d\.]{7,15}/", $realip, $onlineip); - $realip = !empty($onlineip[0]) ? $onlineip[0] : '0.0.0.0'; - return $realip; -} - -/** - * IP黑白名单检测,支持IP段检测 - * @param string $ipNow 要检测的IP - * @param string|array $ipList 白名单IP或者黑名单IP - * @return boolean false|true true:白名单模式,false:黑名单模式 - * @return bool - */ -function checkIP($ipNow = null, $ipList = null, $model = false) -{ - $ipNow = isset($ipNow) ?: real_ip(); - - // 将IP文本转换为数组 - if (is_string($ipList)) { - $ipList = explode(",", $ipList); - } else { - echo 'IP名单错误'; - } - - $ipregexp = implode('|', str_replace(array('*', '.'), array('\d+', '\.'), $ipList)); - $result = preg_match("/^(" . $ipregexp . ")$/", $ipNow); - - // 白名单模式 - if ($model) { - if (in_array($ipNow, $ipList)) { - return false; - } - } - // 黑名单模式 - if ($result) { - return true; - } -} - -/** - * 测试IP或者url是否可以ping通 - * @param $host string ip或网址 - * @param $port int 端口 - * @param $timeout float 过期时间 - * @return bool true|false - */ -function IP_URL_Ping($host, $port, $timeout) -{ - $errno = 444; - $errstr = 'fSockOpen 错误'; - $fP = fSockOpen($host, $port, $errno, $errstr, $timeout); - if (!$fP) { - return false; - } - return true; -} - -/** - * 生成Token - * @param int $length Token长度 - * @return string 返回Token - */ -function privateToken($length = 32) -{ - $output = ''; - for ($a = 0; $a < $length; $a++) { - $output .= chr(mt_rand(65, 122)); //生成php随机数 - } - return md5($output); -} - -/** - * 检查Token - * @param $token 要检查的Token - * @return string 201 访问成功但是服务端关闭API上传 - * @return string 202 访问成功但是Token错误 - */ -function check_api($token) -{ - global $config; - global $tokenList; - - if (!$config['apiStatus']) { - // 关闭API - $reJson = array( - "result" => 'failed', - 'code' => 201, - 'message' => 'API Closed', - ); - exit(json_encode($reJson, JSON_UNESCAPED_UNICODE)); - } - - if (!in_array($tokenList[$token], $tokenList)) { - // Token 不存在 - $reJson = array( - "result" => 'failed', - 'code' => 202, - 'message' => 'Token Error', - ); - exit(json_encode($reJson, JSON_UNESCAPED_UNICODE)); - } - - if ($tokenList[$token]['expired'] < time()) { - // Token 过期 - $reJson = array( - "result" => 'failed', - 'code' => 203, - 'message' => 'Token Expired', - ); - exit(json_encode($reJson, JSON_UNESCAPED_UNICODE)); - } -} - - -/** - * 根据URL判断是否本地局域网访问(PHP代码函数) - * https://blog.csdn.net/monxinmonxin0/article/details/44854383 - * @param string $url 要判断的网址 - * @return bool 是|否 - */ -function is_local($url) -{ - if (stristr($url, 'localhost') || stristr($url, '127.') || stristr($url, '192.')) { - return true; - } - return false; -} - -/** - * 将图片域名转换为数组并随即输出 - * @param string $text 字符串 - * @return String 随机网址 - */ -function rand_imgurl($text = null) -{ - global $config; - $url = isset($text) ? $text : $config['imgurl']; - $url = explode(',', $url); - return $url[array_rand($url, 1)]; -} - -/** - * 获取当前版本号 | 读取字符串 - * @param String $file 文件相对路径 - * @return String 内容信息 - */ - -function get_current_version($file = '/admin/version.php') -{ - $file = APP_ROOT . $file; - - if (is_file($file)) { - return file_get_contents($file); - } - - return 'file does not exist'; -} - -/** - * 压缩图片 process 模式 - * @param String $absolutePath 图片绝对路径 - */ -function process_compress($absolutePath) -{ - global $config; - - if ($config['compress']) { - if (!is_Gif_Webp_Animated($absolutePath)) { - require_once __DIR__ . '/compress/Imagick/class.Imgcompress.php'; - $percent = $config['compress_ratio'] / 100; // 压缩率 - $img = new Imgcompress($absolutePath, $percent); - $img->compressImg($absolutePath); - // 释放 - ob_flush(); - flush(); - } - } -} - -/** - * 设置水印 process 模式 - * @param String $source 图片路径 - */ -function water($source) -{ - global $config; - - // 文字水印 - if ($config['watermark'] == 1) { - // 过滤gif - if (!is_Gif_Webp_Animated($source)) { - $arr = [ - # 水印图片路径(如果不存在将会被当成是字符串水印) - 'res' => $config['waterText'], - # 水印显示位置 - 'pos' => $config['waterPosition'], - # 不指定name(会覆盖原图,也就是保存成thumb.jpeg) - 'name' => $source, - 'font' => APP_ROOT . $config['textFont'], - 'fontSize' => $config['textSize'], - 'color' => str_replace(array('rgba', '(', ')'), '', $config['textColor']), - ]; - Imgs::setWater($source, $arr); - } - } - - // 图片水印 - if ($config['watermark'] == 2) { - // 过滤gif - if (!is_Gif_Webp_Animated($source)) { - $arr = [ - # 水印图片路径(如果不存在将会被当成是字符串水印) - 'res' => APP_ROOT . $config['waterImg'], - # 水印显示位置 - 'pos' => $config['waterPosition'], - # 不指定name(会覆盖原图,也就是保存成thumb.jpeg) - 'name' => $source, - ]; - Imgs::setWater($source, $arr); - } - } -} -/** - * 图片违规检查 process - * @param String $imgurl 图片链接 - */ -function process_checkImg($imgurl) -{ - global $config; - - if ($config['checkImg'] == 1) { - checkImg($imgurl, 1); - } - - if ($config['checkImg'] == 2) { - checkImg($imgurl, 2); - } -} - -/** - * 写日志 - * - * 格式: - * { - * 上传图片名称{ - * source:源文件名称, - * date:上传日期(Asia/Shanghai), - * ip:上传者IP,port:IP端口, - * user_agent:上传者浏览器信息, - * path:文件相对路径, - * size:文件大小(格式化), - * md5:文件MD5, - * checkImg:鉴黄状态, - * form:上传方式web/API ID - * } - * } - * - * $filePath 文件相对路径 - * $sourceName 源文件名称 - * $absolutePath 图片的绝对路径 - * $fileSize 图片的大小 - * $form 来源如果是网页上传直接显示网页,如果是API上传则显示ID - */ -function write_upload_logs($filePath, $sourceName, $absolutePath, $fileSize, $from = "web") -{ - global $config; - - if (!$config['upload_logs']) { - return null; - } - - $checkImg = $config['checkImg'] == true ? "ON" : "OFF"; - - // $name = trim(basename($filePath), " \t\n\r\0\x0B"); // 当前图片名称 - $log = array(basename($filePath) => array( // 以上传图片名称为Array - 'source' => $sourceName, // 原始文件名称 - 'date' => date('Y-m-d H:i:s'), // 上传日期 - 'ip' => real_ip(), // 上传IP - 'port' => $_SERVER['REMOTE_PORT'], // IP端口 - 'user_agent' => $_SERVER['HTTP_USER_AGENT'], // 浏览器信息 - 'path' => $filePath, // 文件相对路径 - 'size' => getDistUsed($fileSize), // 文件大小(格式化) - 'md5' => md5_file($absolutePath), // 文件的md5 - 'checkImg' => $checkImg, // 鉴黄状态 - 'from' => $from, // 图片上传来源 - )); - - // 创建日志文件夹 - if (!is_dir(APP_ROOT . '/admin/logs/upload/')) { - mkdir(APP_ROOT . '/admin/logs/upload', 0755, true); - } - - // logs文件组成 - $logFileName = APP_ROOT . '/admin/logs/upload/' . date('Y-m') . '.php'; - - // 创建logs文件 - if (!is_file($logFileName)) { - file_put_contents($logFileName, ''); - } - - // 引入logs - include $logFileName; - - // // 写入禁止浏览器直接访问 - // if (filesize($logFileName) == 0) { - // $php_exit = ''; - // file_put_contents($logFileName, $php_exit); - // } - - // $log = json_encode($log, JSON_UNESCAPED_UNICODE); - // file_put_contents($logFileName, PHP_EOL . $log, FILE_APPEND | LOCK_EX); - - $log = array_replace($logs, $log); - cache_write($logFileName, $log, 'logs'); -} - -/** - * IP地址查询 - * @param int $ip IP地址 - */ -function ip2region(String $IP) -{ - $db = __DIR__ . '/ip2region/ip2region.xdb'; - - if (!is_file($db)) { - return 'IP数据库不存在'; - } - - try { - require_once __DIR__ . '/ip2region/Ip2Region.php'; - $ip2region = new Ip2Region(); - $location = $ip2region->memorySearch($IP); - $location = $location['region']; - $location = str_replace(array('0', '||'), '', $location); - return $location; - } catch (Exception $e) { - return '查询失败: ' . $e->getMessage(); - } -} - -/** - * 记录同IP每日上传次数 process - */ -function write_ip_upload_count_logs() -{ - global $config; - - if ($config['ip_upload_counts'] > 0) { - // 上传IP地址 - $ip = real_ip(); - // 日志目录 - $dir = APP_ROOT . '/admin/logs/ipcounts/'; - // 日志文件 - $file = $dir . date('Y-m-d') . '.php'; - // 创建日志目录 - if (!is_dir($dir)) mkdir($dir, 0777); - // 创建日志文件 - if (!is_file($file)) file_put_contents($file, '' . PHP_EOL, FILE_APPEND | LOCK_EX); - // 引入日志 - require $file; - // 获取存在的IP - if (isset($ipcounts[$ip])) { - $info[$ip] = $ipcounts[$ip] + 1; - } else { - $info[$ip] = 1; - } - // 写入日志 - $info = array_replace($ipcounts, $info); - cache_write($file, $info, 'ipcounts'); - } -} -/** - * 限制IP每日上传次数 - * @param Sting $ip IP地址 - */ -function get_ip_upload_log_counts($ip) -{ - global $config; - $file = APP_ROOT . '/admin/logs/ipcounts/' . date('Y-m-d') . '.php'; - - if (!is_file($file)) return true; - require_once $file; - - if (!isset($ipcounts[$ip])) return true; - if ($ipcounts[$ip] >= $config['ip_upload_counts']) return false; - - return true; -} - -/** - * 自动删除 - * 开启自动删除后会先重命名文件夹作为备份 - * 自动删除日期超过定时的2倍时间后再彻底删除重命名的文件夹 - */ -function auto_delete() -{ - global $config; - if ($config['auto_delete'] && $config['storage_path'] == 'Y/m/d/') { - - /** 重命名要删除的文件夹 */ - $Odir = APP_ROOT . $config['path'] . date('Y/m/d', strtotime(-$config['auto_delete'] . 'day')); // 重命名文件夹路径 - $Rdir = APP_ROOT . $config['path'] . date('Y/m/d', strtotime(-$config['auto_delete'] . 'day')) . '_auto_delete'; // 新命名文件夹路径 - if (is_dir($Odir)) { // 执行重命名 - rename($Odir, $Rdir); - $log = $Rdir . ' rename succees ' . date('Y-m-d H:i:s'); - } else { - $log = $Rdir . ' rename failed ' . date('Y-m-d H:i:s'); - } - - /** 以定时的2倍倒叙时间删除已经重命名的文件夹路径 */ - $Ddir = APP_ROOT . $config['path'] . date('Y/m/d', strtotime(-$config['auto_delete'] * 2 . 'day')) . '_auto_delete'; // 文件夹路径 - if (is_dir($Ddir)) { // 执行删除 - try { - if (deldir($Ddir)) { - $log = $Ddir . ' delete succees ' . date('Y-m-d H:i:s'); - } else { - throw new Exception($Ddir . ' delete failed ' . date('Y-m-d H:i:s')); - } - } catch (Exception $e) { - $log = $e->getMessage(); - } - } - - /** 创建日志文件夹及文件 */ - if (!is_dir(APP_ROOT . '/admin/logs/tasks/')) { - mkdir(APP_ROOT . '/admin/logs/tasks/', 0755, true); - } - - if (!is_file(APP_ROOT . '/admin/logs/tasks/auto_delete.php')) { - file_put_contents(APP_ROOT . '/admin/logs/tasks/auto_delete.php', '' . PHP_EOL, FILE_APPEND | LOCK_EX); - } - - // 写入日志 - file_put_contents(APP_ROOT . '/admin/logs/tasks/auto_delete.php', $log . PHP_EOL, FILE_APPEND | LOCK_EX); - return true; - } - return false; -} - -/** - * 记录登录日志 - * @param String $user 登录用户 - * @param String $pass 登录密码 - * @param String $msg 登录提示 - */ - -function write_login_log($user, $pass, $msg) -{ - $log_path = APP_ROOT . '/admin/logs/login/'; - $log_file = $log_path . date('/Y-m-') . 'logs.php'; - - /** 创建日志文件夹及文件 */ - if (!is_dir($log_path)) mkdir($log_path, 0755, true); - if (!is_file($log_file)) file_put_contents($log_file, '' . PHP_EOL, FILE_APPEND | LOCK_EX); - - /** 写入日志 */ - $log = '时间: ' . date('Y-m-d H:i:s') . ' IP: ' . real_ip() . ' 账号: ' . $user . ' 密码: ' . $pass . ' 消息: ' . $msg; - file_put_contents($log_file, $log . PHP_EOL, FILE_APPEND | LOCK_EX); -} - -/** - * 其他上传 - * 支持: FTP - * @param String $remoteFile 远程地址 - * @param String $localFile 本地地址 - * @param String $way 使用方式 upload 上传 | delete 删除 - * - */ - -function any_upload($remoteFile = null, $localFile = null, $way = 'upload') -{ - global $config; - - if (!$config['ftp_status']) exit; - - require_once __DIR__ . '/FtpClient/FtpClient.php'; - require_once __DIR__ . '/FtpClient/FtpException.php'; - require_once __DIR__ . '/FtpClient/FtpWrapper.php'; - - $ftp = new FtpClient(); - // FTP 基本信息 - $ftp->connect($config['ftp_host'], $config['ftp_ssl'], $config['ftp_port'], $config['ftp_time']); - // FTP账号密码 - $ftp->login($config['ftp_user'], $config['ftp_pass']); - // FTP主动|被动 - $ftp->pasv($config['ftp_pasv']); - - switch ($way) { - case 'upload': - // 创建文件夹 - $ftp->mkdir(pathinfo($remoteFile, PATHINFO_DIRNAME), 0755, true); - // 上传文件 远端->本地 - $ftp->put($remoteFile, $localFile); - break; - case 'delete': - $ftp->delete($remoteFile); - return true; - break; - } - $ftp->close(); -} +> 1) & 1) ? true : false; + } + fclose($fh); + return $result; + */ +} + +/** + * 判断webp或gif动图是否为动态图片 + * @param $src 图片的绝对路径 + * @return bool 是|否 + */ +function is_Gif_Webp_Animated($src) +{ + $ext = pathinfo($src)['extension']; + + if ($ext == 'webp') { + $webpContents = file_get_contents($src); + $where = strpos($webpContents, "ANMF"); + if ($where !== FALSE) { + // animated + return true; + } + return false; + } + + $fp = fopen($src, 'rb'); + $filecontent = fread($fp, filesize($src)); + fclose($fp); + return strpos($filecontent, chr(0x21) . chr(0xff) . chr(0x0b) . 'NETSCAPE2.0') === FALSE ? false : true; +} + + +/** + * 2023-01-06 校验登录 + * @param $user String 登录用户名 + * @param $password 登录密码 + * 返回参数解析 code=>状态码 200成功,400失败; 登录用户级别level => 0无状态, 1管理员, 2上传者, messege => 提示信息 + */ + +function _login($user = null, $password = null) +{ + global $config; + global $guestConfig; + + // cookie验证 + if ($user === null and $password === null) { + // 无cookie + if (empty($_COOKIE['auth'])) { + return json_encode(array('code' => 400, 'level' => 0, 'messege' => '请登录')); + } + // 存在cookie + if (isset($_COOKIE['auth'])) { + $browser_cookie = json_decode($_COOKIE['auth']); + + // cookie无法读取 + if (!$browser_cookie) return json_encode(array('code' => 400, 'level' => 0, 'messege' => '登录已过期,请重新登录')); + // 判断账号是否存在 + if ($browser_cookie[0] !== $config['user'] && !array_key_exists($browser_cookie[0], $guestConfig)) return json_encode(array('code' => 400, 'level' => 0, 'messege' => '账号不存在')); + // 判断是否管理员 + if ($browser_cookie[0] === $config['user'] && $browser_cookie[1] === $config['password']) return json_encode(array('code' => 200, 'level' => 1, 'messege' => '尊敬的管理员')); + // 判断是否上传者 + if (array_key_exists($browser_cookie[0], $guestConfig) && $browser_cookie[1] === $guestConfig[$browser_cookie[0]]['password']) { + // 判断上车者是否过期 + if ($guestConfig[$browser_cookie[0]]['expired'] < time()) { + // 上传者账户密码正确,但是账户过期 + return json_encode(array('code' => 400, 'level' => 0, 'messege' => $browser_cookie[0] . '账号已过期')); + } + return json_encode(array('code' => 200, 'level' => 2, 'messege' => $browser_cookie[0] . '用户已登录')); + } + // 账号存在,密码错误 + if ($browser_cookie[0] === $config['user'] || array_key_exists($browser_cookie[0], $guestConfig)) return json_encode(array('code' => 400, 'level' => 0, 'messege' => '密码错误')); + } + } + + // 前端验证 + $user = strip_tags($user); + $password = strip_tags($password); + // 是否管理员 + if ($user === $config['user'] && $password === $config['password']) { + // 将账号密码序列化后存储 + $browser_cookie = json_encode(array($user, $password)); + setcookie('auth', $browser_cookie, time() + 3600 * 24 * 14, '/'); + return json_encode(array('code' => 200, 'level' => 1, 'messege' => '管理员登录成功')); + } + // 是否上传者 + if (array_key_exists($user, $guestConfig) && $password === $guestConfig[$user]['password']) { + // 上传者账号过期 + if ($guestConfig[$user]['expired'] < time()) return json_encode(array('code' => 400, 'level' => 0, 'messege' => $user . '账号已过期')); + // 未过期设置cookie + $browser_cookie = json_encode(array($user, $password)); + setcookie('auth', $browser_cookie, time() + 3600 * 24 * 14, '/'); + return json_encode(array('code' => 200, 'level' => 2, 'messege' => $user . '用户登录成功')); + } + // 检查账号是否存在 + if (array_key_exists($user, $guestConfig) || $user === $config['user']) { + // 账号存在,密码错误 + if ($user === $config['user'] || array_key_exists($user, $guestConfig)) return json_encode(array('code' => 400, 'level' => 0, 'messege' => '密码错误')); + } else { + return json_encode(array('code' => 400, 'level' => 0, 'messege' => '账号不存在')); + } + + // 未知错误 + return json_encode(array('code' => 400, 'level' => 0, 'messege' => '未知错误')); +} + +/** + * 校验登录 2023-01-05弃用 + */ +function checkLogin() +{ + global $guestConfig; + global $config; + + // 无cookie + if (empty($_COOKIE['auth'])) { + return 201; + } + + // 存在cookie + if (isset($_COOKIE['auth'])) { + + $getCOK = json_decode($_COOKIE['auth']); + + // 无法读取cookie + if (!$getCOK) { + return 202; + } + + // 密码错误 + if ($getCOK[1] !== $config['password'] && $getCOK[1] !== $guestConfig[$getCOK[0]]['password']) { + return 203; + } + + // 管理员登陆 + if ($getCOK[0] === $config['user'] && $getCOK[1] === $config['password']) { + return 204; + } + + // 上传者账号登陆 + if ($getCOK[1] === $guestConfig[$getCOK[0]]['password']) { + if ($guestConfig[$getCOK[0]]['expired'] < time()) { + // 上传者账号过期 + return 206; + } + return 205; + } + } +} + +/** + * 2023-01-06 仅允许登录上传 + */ +function mustLogin() +{ + global $config; + if ($config['mustLogin']) { + $status = _login(); + $status = json_decode($status, true); + + if ($status['code'] === 200) { + echo ' + '; + } + + if ($status['code'] === 400) { + echo ' + '; + header("refresh:2;url=" . $config['domain'] . "/admin/index.php"); + } + } +} + +/** + * 检查配置文件中目录是否存在是否可写并创建相应目录 + * @param null $path 要创建的路径 + * @return string + */ +function config_path($path = null) +{ + global $config; + + if (empty($path)) { + if (array_key_exists('storage_path', $config)) { + $path = date($config['storage_path']); + } else { + $path = date('Y/m/d/'); + } + } + // 2023-01-06弃用 php5.6 兼容写法: + // $path = isset($path) ? $path : date('Y/m/d/'); + // php7.0 $path = $path ?? date('Y/m/d/'); + + $img_path = $config['path'] . $path; + + if (!is_dir($img_path)) { + @mkdir($img_path, 0755, true); + } + + if (!is_writable($img_path)) { + @chmod($img_path, 0755); + } + + return $img_path; +} + +/** + * 图片命名规则 + * @param null $source 源文件名称 + * @return false|int|string|null + */ +function imgName($source = null) +{ + global $config; + + function create_guid() // guid生成函数 + { + if (function_exists('com_create_guid') === true) { + return trim(com_create_guid(), '{}'); + } + + return sprintf('%04X%04X-%04X-%04X-%04X-%04X%04X%04X', mt_rand(0, 65535), mt_rand(0, 65535), mt_rand(0, 65535), mt_rand(16384, 20479), mt_rand(32768, 49151), mt_rand(0, 65535), mt_rand(0, 65535), mt_rand(0, 65535)); + } + + function uuid() // 生成uuid + { + $chars = md5(uniqid(mt_rand(), true)); + return substr($chars, 0, 8) . '-' . substr($chars, 8, 4) . '-' . substr($chars, 12, 4) . '-' . substr($chars, 16, 4) . '-' . substr($chars, 20, 12); // return $uuid; + } + + switch ($config['imgName']) { + + case "default": + return base_convert(date('His') . mt_rand(1001, 9999), 10, 36); // 将上传时间+随机数转换为36进制 例:vx77yu + break; + case "source": + // 以上传文件名称 例:微信图片_20211228214754 + // 过滤非法名称 $source = preg_replace("/\/|\~|\!|\@|\#|\\$|\%|\^|\&|\*|\(|\)|\_|\+|\{|\}|\:|\<|\>|\?|\[|\]|\,|\.|\/|\;|\'|\`|\-|\=|\\\|\|/","",$source); + return $source; + break; + case "date": + // 以上传时间 例:192704 + return date("His"); + break; + case "unix": + // 以Unix时间 例:1635074840 + return time(); + break; + case "uniqid": + // 基于以微秒计的当前时间 例:6175436c73418 + return uniqid(true); + break; + case "guid": + // 全球唯一标识符 例:6EDAD0CC-AB0C-4F61-BCCA-05FAD65BF0FA + return create_guid(); + break; + case "md5": + // md5加密时间 例:3888aa69eb321a2b61fcc63520bf6c82 + return md5(microtime()); + break; + case "sha1": + // sha1加密微秒 例:654faac01499e0cb5fb0e9d78b21e234c63d842a + return sha1(microtime()); + break; + case "crc32": + // crc32加密微秒 例:2495551279 + return crc32(microtime()); + break; + case "snowflake": + include __DIR__ . '/class.snowflake.php'; + return SnowFlake::createOnlyId(); // 分布式id + break; + case "uuid": + return uuid(); // uuid + break; + default: + return base_convert(date('His') . mt_rand(1001, 9999), 10, 36); // 将上传时间+随机数转换为36进制 例:vx77yu + } +} + +/** + * 静态文件CDN + */ +function static_cdn() +{ + global $config; + if ($config['static_cdn']) { + echo $config['static_cdn_url']; + } else { + echo $config['domain']; + } +} + +/** + * 获取允许上传的扩展名 + */ +function getExtensions() +{ + global $config; + $arr = explode(',', $config['extensions']); + $mime = ''; + for ($i = 0; $i < count($arr); $i++) { + $mime .= $arr . ','; + } + return rtrim($mime, ','); +} + +/** + * 获取目录大小 如果目录文件较多将很费时 + * @param $path string 路径 + * @return int + */ +function getDirectorySize($path) +{ + $bytestotal = 0; + $path = realpath($path); + if ($path !== false && $path != '' && file_exists($path)) { + foreach (new RecursiveIteratorIterator(new RecursiveDirectoryIterator($path, FilesystemIterator::SKIP_DOTS)) as $object) { + $bytestotal += $object->getSize(); + } + } + return $bytestotal; +} + +/** + * 获取指定文件夹文件数量 + * @param $dir 传入一个路径如:/apps/web + * @return int 返回文件数量 + */ +function getFileNumber($dir) +{ + $num = 0; + $arr = glob($dir); + foreach ($arr as $v) { + if (is_file($v)) { + $num++; + } else { + $num += getFileNumber($v . "/*"); + } + } + return $num; +} + +/** + * 图片展示页面 + * getDir()取文件夹列表,getFile()取对应文件夹下面的文件列表,二者的区别在于判断有没有“.”后缀的文件,其他都一样 + * 获取文件目录列表,该方法返回数组 + * @param $dir string 路径 + * @return mixed + * @example getDir("./dir") + */ +function getDirList($dir) +{ + $dirArray[] = NULL; + if (false != ($handle = opendir($dir))) { + $i = 0; + while (false !== ($file = readdir($handle))) { + //去掉"“.”、“..”以及带“.xxx”后缀的文件 + if ($file != "." && $file != ".." && !strpos($file, ".")) { + $dirArray[$i] = $file; + $i++; + } + } + //关闭句柄 + closedir($handle); + } + return $dirArray; +} + +/** + * 获取文件列表 + * @param $dir string 目录 + * @return mixed + */ +function getFile($dir) +{ + $fileArray[] = NULL; + if (is_dir($dir)) { + if (false != ($handle = opendir($dir))) { + $i = 0; + while (false !== ($file = readdir($handle))) { + //去掉"“.”、“..”以及带“.xxx”后缀的文件 + if ($file != "." && $file != ".." && strpos($file, ".")) { + $fileArray[$i] = $file; + if ($i == 1000) { + break; + } + $i++; + } + } + //关闭句柄 + closedir($handle); + } + } + return $fileArray; +} + +/** + * 获取文件夹文件列表或数量 + * @param string $dir_fileName_suffix 获取文件列表:目录+文件名*:全匹配+文件后缀 *: 全匹配 {jpg,png,gif}:匹配指定格式 + * 递归文件数量:目录 + * @example get_file_by_glob(__DIR__ . '/i/cache/*.*', $type = 'list'); // 获取目录文件列表 + * @example get_file_by_glob(__DIR__ . '/i/', $type = 'number'); // 递归获取文件夹数量 + * @param string $type list|number 返回列表还是数量 + * @return array|int 返回数组|数量 + */ +function get_file_by_glob($dir_fileName_suffix, $type = 'list') +{ + global $config; + + // 获取所有文件 + if ($type == 'list') { + $glob = glob($dir_fileName_suffix, GLOB_BRACE); + + if ($glob) { + foreach ($glob as $v) { + if (is_file($v)) $res[] = basename($v); + } + // 排序 + if ($res) { + switch ($config['showSort']) { + case 1: + $res = array_reverse($res); + break; + } + } + } else { + $res = array(); + } + } + + if ($type == 'number') { + $res = 0; + $glob = glob($dir_fileName_suffix); //把该路径下所有的文件存到一个数组里面; + if ($glob) { + foreach ($glob as $v) { + if (is_file($v)) { + $res++; + } else { + $res += get_file_by_glob($v . "/*", $type = 'number'); + } + } + } else { + $res = 0; + } + } + return $res; +} + +/** + * 递归函数实现遍历指定文件下的目录与文件数量 + * 用来统计一个目录下的文件和目录的个数 + * echo "目录数为:{$dirn}
    "; + * echo "文件数为:{$filen}
    "; + * @param $file string 目录 + */ +function getdirnum($file) +{ + $dirn = 0; //目录数 + $filen = 0; //文件数 + $dir = opendir($file); + while ($filename = readdir($dir)) { + if ($filename != "." && $filename != "..") { + $filename = $file . "/" . $filename; + if (is_dir($filename)) { + $dirn++; + getdirnum($filename); + //递归,就可以查看所有子目录 + } else { + $filen++; + } + } + } + closedir($dir); +} + +/** + * 把文件或目录的大小转化为容易读的方式 + * disk_free_space - 磁盘可用空间(比如填写D盘某文件夹,则会现在D盘剩余空间) + * disk_total_space — 磁盘总空间(比如填写D盘某文件夹,则会现在D盘总空间) + * @param $number + * @return string + */ +function getDistUsed($number) +{ + $dw = ''; // 指定文件或目录统计的单位方式 + if ($number > pow(2, 30)) { + $dw = "GB"; + $number = round($number / pow(2, 30), 2); + } else if ($number > pow(2, 20)) { + $dw = "MB"; + $number = round($number / pow(2, 20), 2); + } else if ($number > pow(2, 10)) { + $dw = "KB"; + $number = round($number / pow(2, 10), 2); + } else { + $dw = "bytes"; + } + return $number . $dw; +} + +/** + * 加密/解密图片路径 + * @param string $data 要加密的内容 + * @param int $mode =1或0 1解密 0加密 + * @param String $key 盐 + */ +function urlHash($data, $mode, $key = null) +{ + global $config; + + if (!$key) { + $key = crc32($config['password']); + } + + $iv = 'sciCuBC7orQtDhTO'; + if ($mode) { + return openssl_decrypt(base64_decode($data), "AES-128-XTS", $key, 0, $iv); + } else { + return base64_encode(openssl_encrypt($data, "AES-128-XTS", $key, 0, $iv)); + } +} + +/** + * 删除指定文件 + * @param $url string 文件 + * @param $type string 模式 + */ +function getDel($url, $type) +{ + global $config; + // url本地化 + $url = htmlspecialchars(str_replace($config['domain'], '', $url)); // 过滤html 获取url path + $url = urldecode(trim($url)); + + if ($type == 'url') { + $url = $_SERVER['DOCUMENT_ROOT'] . $url; + } + if ($type == 'hash') { + $url = APP_ROOT . $url; + } + + // 文件是否存在 限制删除目录 + if (is_file($url) && strrpos($url, $config['path'])) { + // 执行删除 + if (@unlink($url)) { + echo ' + + '; + } else { + echo ' + + '; + } + } else { + echo ' + + '; + } + // 清除查询 + clearstatcache(); +} + +/** + * 判断是否此用户登录 + * @param string $user 判断登录者权限 当$user=null 时检查是否登录, 不区分身份 + * @return bool 是|否 + */ +function is_who_login($user) +{ + // 将状态转码 + $status = json_decode(_login(), true); + // 查询是否登录 + if ($user === 'status') if ($status['level'] > 0) return true; + // 是否管理员登录 + if ($user === 'admin') if ($status['level'] == 1) return true; + // 是否上传者登录 + if ($user === 'guest') if ($status['level'] == 2) return true; + + return false; +} + +/** + * 检查PHP缺少简单图床必备的扩展 + * 需检测的扩展:'fileinfo', 'iconv', 'gd', 'mbstring', 'openssl','zip', + * zip 扩展不是必须的,但会影响tinyfilemanager文件压缩(本次不检测)。 + * + * 检测是否更改默认域名 + * + * 检测是否修改默认密码 + * @param $mode bool 是否开启检测 + */ +function checkEnv($mode) +{ + // 初始化安装 + if (!is_file(APP_ROOT . '/config/install.lock') and is_file(APP_ROOT . '/install/install.php')) { + echo ''; + } + + if ($mode) { + require_once __DIR__ . '/check.php'; + } +} + +/** + * 前端改变图片长宽 + * @return string 裁剪参数 + */ +function imgRatio() +{ + global $config; + if ($config['imgRatio']) { + + if ($config['imgRatio_crop'] === 1) { + $imgRatio_crop = 'true'; + } else { + $imgRatio_crop = 'false'; + } + + if ($config['imgRatio_preserve_headers'] === 1) { + $imgRatio_preserve_headers = 'true'; + } else { + $imgRatio_preserve_headers = 'false'; + } + + if ($config['image_x'] != 0) { + $image_x = "width:" . $config['image_x'] . ','; + } else { + $image_x = null; + } + + if ($config['image_y'] != 0) { + $image_y = "height:" . $config['image_y'] . ','; + } else { + $image_y = null; + } + + return ' + resize:{ + ' . $image_x . ' + ' . $image_y . ' + crop: ' . $imgRatio_crop . ', + quality:' . $config['imgRatio_quality'] . ', + preserve_headers: ' . $imgRatio_preserve_headers . ', + }'; + } else { + return "file_data_name:'file'"; + } +} + +/** + * 定时获取GitHub 最新版本 + * @return mixed|null 读取版本信息 + */ +function getVersion($name = 'tag_name') +{ + global $config; + + if ($config['checkEnv']) { + require_once APP_ROOT . '/app/class.version.php'; + $url = "https://api.github.com/repositories/188228357/releases/latest"; // 获取版本地址 + $getVersion = new getVersion($url); + try { + if (!empty($getVersion->readJson($name))) { + return $getVersion->readJson($name); // 返回版本信息 + } else { + return '存在版本文件, 但是内容为空,请等待1小时候后再次更新版本号!'; + } + } catch (Throwable $e) { + $getVersion->downJson(); // 获取版本信息 + return '获取版本文件失败,请检查curl或者网络 错误信息: ' . $e->getMessage(); + } + } else { + return '已关闭环境自检, 当前版本:' . get_current_version(); + } +} + +/** + * 删除非空目录 + * @param $dir string 要删除的目录 + * @return bool true|false + */ +function deldir($dir) +{ + if (file_exists($dir)) { + $files = scandir($dir); + foreach ($files as $file) { + if ($file != '.' && $file != '..') { + $path = $dir . '/' . $file; + if (is_dir($path)) { + deldir($path); + } else { + unlink($path); + } + } + } + rmdir($dir); + return true; + } else { + return false; + } +} + +/** + * 图片监黄curl 访问网站并返回解码过的json信息 + * @param $img string 图片url + * @param null $url 访问的网址 + * @return mixed + */ +function moderatecontent_json($img, $url = null) +{ + global $config; + + if (empty($config['moderatecontent_key'])) { + exit; + } + + $url = 'https://api.moderatecontent.com/moderate/?key=' . $config['moderatecontent_key'] . '&url=' . $img; + $headerArray = array("Content-type:application/json;", "Accept:application/json"); + $ch = curl_init(); + curl_setopt($ch, CURLOPT_URL, $url); + curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FALSE); + curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, FALSE); + curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); + curl_setopt($ch, CURLOPT_HTTPHEADER, $headerArray); + curl_setopt($ch, CURLOPT_TIMEOUT, 30); + curl_setopt($ch, CURLOPT_USERAGENT, 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/86.0.4240.198 Safari/537.36'); + $output = curl_exec($ch); + curl_close($ch); + $output = json_decode($output, true); + return $output; +} + +/** + * 使用curl方式实现get或post请求 + * @param $url 请求的url地址 + * @param $data 发送的post数据 如果为空则为get方式请求 + * return 请求后获取到的数据 + */ + +function nsfwjs_json($url, $data = '') +{ + global $config; + + if (empty($config['nsfwjs_url'])) { + exit; + } + + $ch = curl_init(); + $params[CURLOPT_URL] = $config['nsfwjs_url'] . $url; //请求url地址 + $params[CURLOPT_HEADER] = false; //是否返回响应头信息 + $params[CURLOPT_RETURNTRANSFER] = true; //是否将结果返回 + $params[CURLOPT_FOLLOWLOCATION] = true; //是否重定向 + $params[CURLOPT_TIMEOUT] = 30; //超时时间 + if (!empty($data)) { + $params[CURLOPT_POST] = true; + $params[CURLOPT_POSTFIELDS] = $data; + } + $params[CURLOPT_SSL_VERIFYPEER] = false; //请求https时设置,还有其他解决方案 + $params[CURLOPT_SSL_VERIFYHOST] = false; //请求https时,其他方案查看其他博文 + curl_setopt_array($ch, $params); //传入curl参数 + $content = curl_exec($ch); //执行 + curl_close($ch); //关闭连接 + $content = json_decode($content, true); + return $content; +} + +/** + * 检查图片是否违规 + * @param $imageUrl 图片链接 + * @param int $type 模式: 1|moderatecontent 2|nsfwjs 3|移入回收站 + * @param string $dir 移入的目录 + * @return bool + */ +function checkImg($imageUrl, $type = 1, $dir = 'suspic/') +{ + global $config; + + /** # 使用moderatecontent */ + if ($type == 1) { + $response = moderatecontent_json($imageUrl); + if ($response['rating_index'] == 3 or $response['predictions']['adult'] > $config['checkImg_value']) { // (1 = everyone, 2 = teen, 3 = adult) + $bad_pic = true; + } + } + + /** # 使用nsfwjs */ + if ($type == 2) { + /** + * probability,概率 + * className,类型 + * + * 上传图片后,总共会返回 5 个维度的数值来鉴别该图片的尺度: + * + * 绘画(Drawing)—— 无害的艺术,或艺术绘画; + * 变态(Hentai)—— 色情艺术,不适合大多数工作环境; + * 中立(Neutral)—— 一般,无害的内容; + * 色情(Porn)—— 不雅的内容和行为,通常涉及生殖器; + * 性感(Sexy)—— 不合时宜的挑衅内容。 + * + * 当porn评分超过>=0.6左右,就几乎是一张带有色情性质的图片了。 + */ + + $file = nsfwjs_json($imageUrl); + + // 将获取的值删除className后组建数组 + for ($i = 0; $i <= count($file); $i++) { + if ($file[$i]['className'] == 'Drawing') { + $res['Drawing'] = $file[$i]['probability']; + } + if ($file[$i]['className'] == 'Hentai') { + $res['Hentai'] = $file[$i]['probability']; + } + if ($file[$i]['className'] == 'Neutral') { + $res['Neutral'] = $file[$i]['probability']; + } + if ($file[$i]['className'] == 'Porn') { + $res['Porn'] = $file[$i]['probability']; + } + if ($file[$i]['className'] == 'Sexy') { + $res['Sexy'] = $file[$i]['probability']; + } + } + + // 测试数组是否正确 + // foreach ($file as $k => $v) { + // foreach ($v as $k1 => $v1) { + // echo $k1 . '=>' . $v1 . '
    '; + // } + // } + + if ($res['Sexy'] * 100 > $config['checkImg_value'] or $res['Porn'] * 100 > $config['checkImg_value']) { + $bad_pic = true; + } + } + + // 移入回收站 + if ($type == 3) { + $bad_pic = true; + $dir = 'recycle/'; + } + + /** # 如果违规则移动图片到违规文件夹 */ + if ($bad_pic == true) { + $old_path = APP_ROOT . parse_url($imageUrl)['path']; // 提交网址中的文件路径 /i/2021/10/29/p8vypd.png + $name = parse_url($imageUrl)['path']; // 获得图片的相对地址 + $name = str_replace($config['path'], '', $name); // 去除 path目录 + $name = str_replace('/', '_', $name); // 文件名 2021_10_30_p8vypd.png + $new_path = APP_ROOT . $config['path'] . $dir . $name; // 新路径含文件名 + $suspic_dir = APP_ROOT . $config['path'] . $dir; // suspic路径 + + if (!is_dir($suspic_dir)) { // 创建suspic目录并移动 + mkdir($suspic_dir, 0777, true); + } + if (is_file($old_path)) { + rename($old_path, $new_path); + return true; + } else { + return false; + } + } +} + +/** + * 还原被审查的图片 + * @param $name string 要还原的图片 + */ +function re_checkImg($name, $dir = 'suspic/') +{ + global $config; + + $fileToPath = str_replace('_', '/', $name); // 将图片名称还原为带路径的名称,eg:2021_11_03_pbmn1a.jpg =>2021/11/03/pbmn1a.jpg + $now_path_file = APP_ROOT . $config['path'] . $dir . $name; // 当前图片绝对位置 */i/suspic/2021_10_30_p8vypd.png + if (is_file($now_path_file)) { + $to_file = APP_ROOT . $config['path'] . $fileToPath; // 要还原图片的绝对位置 */i/2021/10/30/p8vypd.png + rename($now_path_file, $to_file); // 移动文件 + return true; + } +} + +/** + * 创建缩略图 + * @param $imgName string 需要创建缩略图的名称 + */ +function creat_thumbnail_images($imgName) +{ + require_once __DIR__ . '/class.thumb.php'; + global $config; + + $old_img_path = APP_ROOT . config_path() . $imgName; // 获取要创建缩略图文件的绝对路径 + $cache_path = APP_ROOT . $config['path'] . 'cache/'; // cache目录的绝对路径 + + if (!is_dir($cache_path)) { // 创建cache目录 + mkdir($cache_path, 0777, true); + } + if (!isGifAnimated($old_img_path)) { // 仅针对非gif创建图片缩略图 + $new_imgName = APP_ROOT . $config['path'] . 'cache/' . date('Y_m_d') . '_' . $imgName; // 缩略图缓存的绝对路径 + Thumb::out($old_img_path, $new_imgName, $config['thumbnail_w'], $config['thumbnail_h']); // 保存缩略图 + } +} + +/** + * 根据请求网址路径返回缩略图网址 + * @param $url string 图片链接 + * @return string + */ +function return_thumbnail_images($url) +{ + global $config; + $cache_image_file = str_replace($config['imgurl'], '', $url); + + if (isGifAnimated(APP_ROOT . $cache_image_file)) { // 仅读取非gif的缩略图 + return $url; // 如果是gif则直接返回url + } else { + $cache_image_file = str_replace($config['path'], '', $cache_image_file); // 将网址中的/i/去除 + $cache_image_file = str_replace('/', '_', $cache_image_file); // 将文件的/转换为_ + $isFile = APP_ROOT . $config['path'] . 'cache/' . $cache_image_file; // 缓存文件的绝对路径 + if (file_exists($isFile)) { // 缓存文件是否存在 + return $config['imgurl'] . $config['path'] . 'cache/' . $cache_image_file; // 存在则返回缓存文件 + } else { + return $url; // 不存在直接返回url + } + } +} + +/** + * 在线输出缩略图 + * @param $imgUrl string 图片链接 + * @return string 缩略图链接 + */ +function get_online_thumbnail($imgUrl) +{ + global $config; + if ($config['thumbnail']) { + $imgUrl = str_replace($config['domain'], '', $imgUrl); + return $config['domain'] . '/app/thumb.php?img=' . $imgUrl; + } + + return $imgUrl; +} + +/** + * 用户浏览广场的时候生成缩略图,由此解决上传生成缩略图时服务器超时响应 + * @param $imgUrl string 源图片网址 + * @return string 缩略图地址 + */ +function creat_thumbnail_by_list($imgUrl) +{ + + global $config; + ini_set('max_execution_time', '300'); // 脚本运行的时间(以秒为单位)0不限制 + + // 过滤非指定格式 + if (!in_array(pathinfo($imgUrl, PATHINFO_EXTENSION), array('png', 'gif', 'jpeg', 'jpg', 'webp', 'bmp'))) { + // ico格式直接返回直链 + if (pathinfo($imgUrl, PATHINFO_EXTENSION) === 'ico') return $imgUrl; + // 其他格式直接返回指定图标 + return '../public/images/file.svg'; + } + + switch ($config['thumbnail']) { + // 输出原图 + case 0: + return $imgUrl; + break; + // 访问生成 + case 1: + return get_online_thumbnail($imgUrl); + break; + } + + // 将网址图片转换为相对路径 + $pathName = parse_url($imgUrl, PHP_URL_PATH); + // 图片绝对路径 + $abPathName = APP_ROOT . $pathName; + // 将网址中的/i/去除 + $pathName = str_replace($config['path'], '', $pathName); + // 将文件的/转换为_ + $thumbnail = str_replace('/', '_', $pathName); + + // 缓存文件是否存在 + if (is_file(APP_ROOT . $config['path'] . 'cache/' . $thumbnail)) { + // 存在则返回缓存文件 + return $config['domain'] . $config['path'] . 'cache/' . $thumbnail; + } else { + + // 如果图像是gif则直接返回网址 + if (isGifAnimated($abPathName)) { + return $imgUrl; + } + // 如果是webp动图则直接返回网址 + if (isWebpAnimated($abPathName)) { + return $imgUrl; + } + + /** 创建缓存文件并输出文件链接 */ + + // thumbnails目录的绝对路径 + $cache_path = APP_ROOT . $config['path'] . 'cache/'; + // 创建cache目录 + if (!is_dir($cache_path)) { + mkdir($cache_path, 0755, true); + } + // 缩略图缓存的绝对路径 $imgName 是不带/i/的相对路径 + $new_imgName = $cache_path . $thumbnail; + // 创建并保存缩略图 + if ($config['thumbnail'] == 2) { + require_once __DIR__ . '/Zebra_Image.php'; + $image = new Zebra_Image(); + $image->source_path = $abPathName; + $image->target_path = $new_imgName; + $image->resize($config['thumbnail_w'], $config['thumbnail_h'], ZEBRA_IMAGE_CROP_CENTER); + } else { + require_once __DIR__ . '/class.thumb.php'; + Thumb::out($abPathName, $new_imgName, $config['thumbnail_w'], $config['thumbnail_h']); + } + + // 输出缩略图 + return $new_imgName; + } +} + +/** + * 获取当前页面完整URL地址 + * https://www.php.cn/php-weizijiaocheng-28181.html + * @param null $search string 返回指定搜索文字之前的内容(不含搜索文字) + * @return false|string 返回读取网址 + */ +function get_whole_url($search = null) +{ + $sys_protocal = isset($_SERVER['SERVER_PORT']) && $_SERVER['SERVER_PORT'] == '443' ? 'https://' : 'http://'; + $php_self = isset($_SERVER['SCRIPT_NAME']) ? $_SERVER['SCRIPT_NAME'] : $_SERVER['SCRIPT_NAME']; + $path_info = isset($_SERVER['PATH_INFO']) ? $_SERVER['PATH_INFO'] : ''; + $relate_url = isset($_SERVER['REQUEST_URI']) ? $_SERVER['REQUEST_URI'] : $php_self . (isset($_SERVER['QUERY_STRING']) ? '?' . $_SERVER['QUERY_STRING'] : $path_info); + $whole_domain = $sys_protocal . (isset($_SERVER['HTTP_HOST']) ? $_SERVER['HTTP_HOST'] : '') . $relate_url; + if ($search) { + // 返回指定符号之前 + return substr($whole_domain, 0, strrpos($whole_domain, $search)); + } + return $whole_domain; +} + +/** + * 配置写入 + * @param $filename string 要存储的源文件名称 + * @param $values array 获取到的数组 + * @param string $var 源文件的数组名称 + * @param bool $format 不知道啥作用 + * @return bool + */ +function cache_write($filename, $values, $var = 'config', $format = false) +{ + $cachefile = $filename; + $cachetext = " $val) { + $key = is_string($key) ? '\'' . addcslashes($key, '\'\\') . '\'' : $key; + $val = !is_array($val) && (!preg_match('/^\-?\d+$/', $val) || strlen($val) > 12) ? '\'' . addcslashes($val, '\'\\') . '\'' : $val; + if (is_array($val)) { + $evaluate .= $comma . $key . '=>' . arrayeval($val, $format, $level + 1); + } else { + $evaluate .= $comma . $key . '=>' . $val; + } + $comma = ',' . $line . $space; + } + $evaluate .= $line . $space . ')'; + return $evaluate; +} + +/** + * 配置写入文件 + * @param $filename string 要写入的文件名 + * @param $writetext array 要写入的文字 + * @param string $openmod 写文件模式 + * @return bool + */ +function writefile($filename, $writetext, $openmod = 'w') +{ + if (false !== $fp = fopen($filename, $openmod)) { + flock($fp, 2); + fwrite($fp, $writetext); + fclose($fp); + return true; + } else { + return false; + } +} + +/** + * 获得用户的真实IP地址 + * 来源:ecshop + * @return mixed|string string + */ +function real_ip() +{ + static $realip = NULL; + if ($realip !== NULL) { + return $realip; + } + if (isset($_SERVER)) { + if (isset($_SERVER['HTTP_X_FORWARDED_FOR'])) { + $arr = explode(',', $_SERVER['HTTP_X_FORWARDED_FOR']); + /* 取X-Forwarded-For中第一个非unknown的有效IP字符串 */ + foreach ($arr as $ip) { + $ip = trim($ip); + + if ($ip != 'unknown') { + $realip = $ip; + + break; + } + } + } elseif (isset($_SERVER['HTTP_CLIENT_IP'])) { + $realip = $_SERVER['HTTP_CLIENT_IP']; + } else { + if (isset($_SERVER['REMOTE_ADDR'])) { + $realip = $_SERVER['REMOTE_ADDR']; + } else { + $realip = '0.0.0.0'; + } + } + } else { + if (getenv('HTTP_X_FORWARDED_FOR')) { + $realip = getenv('HTTP_X_FORWARDED_FOR'); + } elseif (getenv('HTTP_CLIENT_IP')) { + $realip = getenv('HTTP_CLIENT_IP'); + } else { + $realip = getenv('REMOTE_ADDR'); + } + } + // 使用正则验证IP地址的有效性,防止伪造IP地址进行SQL注入攻击 + preg_match("/[\d\.]{7,15}/", $realip, $onlineip); + $realip = !empty($onlineip[0]) ? $onlineip[0] : '0.0.0.0'; + return $realip; +} + +/** + * IP黑白名单检测,支持IP段检测 + * @param string $ipNow 要检测的IP + * @param string|array $ipList 白名单IP或者黑名单IP + * @return boolean false|true true:白名单模式,false:黑名单模式 + * @return bool + */ +function checkIP($ipNow = null, $ipList = null, $model = false) +{ + $ipNow = isset($ipNow) ?: real_ip(); + + // 将IP文本转换为数组 + if (is_string($ipList)) { + $ipList = explode(",", $ipList); + } else { + echo 'IP名单错误'; + } + + $ipregexp = implode('|', str_replace(array('*', '.'), array('\d+', '\.'), $ipList)); + $result = preg_match("/^(" . $ipregexp . ")$/", $ipNow); + + // 白名单模式 + if ($model) { + if (in_array($ipNow, $ipList)) { + return false; + } + } + // 黑名单模式 + if ($result) { + return true; + } +} + +/** + * 测试IP或者url是否可以ping通 + * @param $host string ip或网址 + * @param $port int 端口 + * @param $timeout float 过期时间 + * @return bool true|false + */ +function IP_URL_Ping($host, $port, $timeout) +{ + $errno = 444; + $errstr = 'fSockOpen 错误'; + $fP = fSockOpen($host, $port, $errno, $errstr, $timeout); + if (!$fP) { + return false; + } + return true; +} + +/** + * 生成Token + * @param int $length Token长度 + * @return string 返回Token + */ +function privateToken($length = 32) +{ + $output = ''; + for ($a = 0; $a < $length; $a++) { + $output .= chr(mt_rand(65, 122)); //生成php随机数 + } + return md5($output); +} + +/** + * 检查Token + * @param $token 要检查的Token + * @return string 201 访问成功但是服务端关闭API上传 + * @return string 202 访问成功但是Token错误 + */ +function check_api($token) +{ + global $config; + global $tokenList; + + if (!$config['apiStatus']) { + // 关闭API + $reJson = array( + "result" => 'failed', + 'code' => 201, + 'message' => 'API Closed', + ); + exit(json_encode($reJson, JSON_UNESCAPED_UNICODE)); + } + + if (!in_array($tokenList[$token], $tokenList)) { + // Token 不存在 + $reJson = array( + "result" => 'failed', + 'code' => 202, + 'message' => 'Token Error', + ); + exit(json_encode($reJson, JSON_UNESCAPED_UNICODE)); + } + + if ($tokenList[$token]['expired'] < time()) { + // Token 过期 + $reJson = array( + "result" => 'failed', + 'code' => 203, + 'message' => 'Token Expired', + ); + exit(json_encode($reJson, JSON_UNESCAPED_UNICODE)); + } +} + + +/** + * 根据URL判断是否本地局域网访问(PHP代码函数) + * https://blog.csdn.net/monxinmonxin0/article/details/44854383 + * @param string $url 要判断的网址 + * @return bool 是|否 + */ +function is_local($url) +{ + if (stristr($url, 'localhost') || stristr($url, '127.') || stristr($url, '192.')) { + return true; + } + return false; +} + +/** + * 将图片域名转换为数组并随即输出 + * @param string $text 字符串 + * @return String 随机网址 + */ +function rand_imgurl($text = null) +{ + global $config; + $url = isset($text) ? $text : $config['imgurl']; + $url = explode(',', $url); + return $url[array_rand($url, 1)]; +} + +/** + * 获取当前版本号 | 读取字符串 + * @param String $file 文件相对路径 + * @return String 内容信息 + */ + +function get_current_version($file = '/admin/version.php') +{ + $file = APP_ROOT . $file; + + if (is_file($file)) { + return file_get_contents($file); + } + + return 'file does not exist'; +} + +/** + * 压缩图片 process 模式 + * @param String $absolutePath 图片绝对路径 + */ +function process_compress($absolutePath) +{ + global $config; + + if ($config['compress']) { + if (!is_Gif_Webp_Animated($absolutePath)) { + require_once __DIR__ . '/compress/Imagick/class.Imgcompress.php'; + $percent = $config['compress_ratio'] / 100; // 压缩率 + $img = new Imgcompress($absolutePath, $percent); + $img->compressImg($absolutePath); + // 释放 + ob_flush(); + flush(); + } + } +} + +/** + * 设置水印 process 模式 + * @param String $source 图片路径 + */ +function water($source) +{ + global $config; + + // 文字水印 + if ($config['watermark'] == 1) { + // 过滤gif + if (!is_Gif_Webp_Animated($source)) { + $arr = [ + # 水印图片路径(如果不存在将会被当成是字符串水印) + 'res' => $config['waterText'], + # 水印显示位置 + 'pos' => $config['waterPosition'], + # 不指定name(会覆盖原图,也就是保存成thumb.jpeg) + 'name' => $source, + 'font' => APP_ROOT . $config['textFont'], + 'fontSize' => $config['textSize'], + 'color' => str_replace(array('rgba', '(', ')'), '', $config['textColor']), + ]; + Imgs::setWater($source, $arr); + } + } + + // 图片水印 + if ($config['watermark'] == 2) { + // 过滤gif + if (!is_Gif_Webp_Animated($source)) { + $arr = [ + # 水印图片路径(如果不存在将会被当成是字符串水印) + 'res' => APP_ROOT . $config['waterImg'], + # 水印显示位置 + 'pos' => $config['waterPosition'], + # 不指定name(会覆盖原图,也就是保存成thumb.jpeg) + 'name' => $source, + ]; + Imgs::setWater($source, $arr); + } + } +} +/** + * 图片违规检查 process + * @param String $imgurl 图片链接 + */ +function process_checkImg($imgurl) +{ + global $config; + + if ($config['checkImg'] == 1) { + checkImg($imgurl, 1); + } + + if ($config['checkImg'] == 2) { + checkImg($imgurl, 2); + } +} + +/** + * 写日志 + * + * 格式: + * { + * 上传图片名称{ + * source:源文件名称, + * date:上传日期(Asia/Shanghai), + * ip:上传者IP,port:IP端口, + * user_agent:上传者浏览器信息, + * path:文件相对路径, + * size:文件大小(格式化), + * md5:文件MD5, + * checkImg:鉴黄状态, + * form:上传方式web/API ID + * } + * } + * + * $filePath 文件相对路径 + * $sourceName 源文件名称 + * $absolutePath 图片的绝对路径 + * $fileSize 图片的大小 + * $form 来源如果是网页上传直接显示网页,如果是API上传则显示ID + */ +function write_upload_logs($filePath, $sourceName, $absolutePath, $fileSize, $from = "web") +{ + global $config; + + if (!$config['upload_logs']) { + return null; + } + + $checkImg = $config['checkImg'] == true ? "ON" : "OFF"; + + // $name = trim(basename($filePath), " \t\n\r\0\x0B"); // 当前图片名称 + $log = array(basename($filePath) => array( // 以上传图片名称为Array + 'source' => $sourceName, // 原始文件名称 + 'date' => date('Y-m-d H:i:s'), // 上传日期 + 'ip' => real_ip(), // 上传IP + 'port' => $_SERVER['REMOTE_PORT'], // IP端口 + 'user_agent' => $_SERVER['HTTP_USER_AGENT'], // 浏览器信息 + 'path' => $filePath, // 文件相对路径 + 'size' => getDistUsed($fileSize), // 文件大小(格式化) + 'md5' => md5_file($absolutePath), // 文件的md5 + 'checkImg' => $checkImg, // 鉴黄状态 + 'from' => $from, // 图片上传来源 + )); + + // 创建日志文件夹 + if (!is_dir(APP_ROOT . '/admin/logs/upload/')) { + mkdir(APP_ROOT . '/admin/logs/upload', 0755, true); + } + + // logs文件组成 + $logFileName = APP_ROOT . '/admin/logs/upload/' . date('Y-m') . '.php'; + + // 创建logs文件 + if (!is_file($logFileName)) { + file_put_contents($logFileName, ''); + } + + // 引入logs + include $logFileName; + + // // 写入禁止浏览器直接访问 + // if (filesize($logFileName) == 0) { + // $php_exit = ''; + // file_put_contents($logFileName, $php_exit); + // } + + // $log = json_encode($log, JSON_UNESCAPED_UNICODE); + // file_put_contents($logFileName, PHP_EOL . $log, FILE_APPEND | LOCK_EX); + + $log = array_replace($logs, $log); + cache_write($logFileName, $log, 'logs'); +} + +/** + * IP地址查询 + * @param int $ip IP地址 + */ +function ip2region(String $IP) +{ + $db = __DIR__ . '/ip2region/ip2region.xdb'; + + if (!is_file($db)) { + return 'IP数据库不存在'; + } + + try { + require_once __DIR__ . '/ip2region/Ip2Region.php'; + $ip2region = new Ip2Region(); + $location = $ip2region->memorySearch($IP); + $location = $location['region']; + $location = str_replace(array('0', '||'), '', $location); + return $location; + } catch (Exception $e) { + return '查询失败: ' . $e->getMessage(); + } +} + +/** + * 记录同IP每日上传次数 process + */ +function write_ip_upload_count_logs() +{ + global $config; + + if ($config['ip_upload_counts'] > 0) { + // 上传IP地址 + $ip = real_ip(); + // 日志目录 + $dir = APP_ROOT . '/admin/logs/ipcounts/'; + // 日志文件 + $file = $dir . date('Y-m-d') . '.php'; + // 创建日志目录 + if (!is_dir($dir)) mkdir($dir, 0777); + // 创建日志文件 + if (!is_file($file)) file_put_contents($file, '' . PHP_EOL, FILE_APPEND | LOCK_EX); + // 引入日志 + require $file; + // 获取存在的IP + if (isset($ipcounts[$ip])) { + $info[$ip] = $ipcounts[$ip] + 1; + } else { + $info[$ip] = 1; + } + // 写入日志 + $info = array_replace($ipcounts, $info); + cache_write($file, $info, 'ipcounts'); + } +} +/** + * 限制IP每日上传次数 + * @param Sting $ip IP地址 + */ +function get_ip_upload_log_counts($ip) +{ + global $config; + $file = APP_ROOT . '/admin/logs/ipcounts/' . date('Y-m-d') . '.php'; + + if (!is_file($file)) return true; + require_once $file; + + if (!isset($ipcounts[$ip])) return true; + if ($ipcounts[$ip] >= $config['ip_upload_counts']) return false; + + return true; +} + +/** + * 自动删除 + * 开启自动删除后会先重命名文件夹作为备份 + * 自动删除日期超过定时的2倍时间后再彻底删除重命名的文件夹 + */ +function auto_delete() +{ + global $config; + if ($config['auto_delete'] && $config['storage_path'] == 'Y/m/d/') { + + /** 重命名要删除的文件夹 */ + $Odir = APP_ROOT . $config['path'] . date('Y/m/d', strtotime(-$config['auto_delete'] . 'day')); // 重命名文件夹路径 + $Rdir = APP_ROOT . $config['path'] . date('Y/m/d', strtotime(-$config['auto_delete'] . 'day')) . '_auto_delete'; // 新命名文件夹路径 + if (is_dir($Odir)) { // 执行重命名 + rename($Odir, $Rdir); + $log = $Rdir . ' rename succees ' . date('Y-m-d H:i:s'); + } else { + $log = $Rdir . ' rename failed ' . date('Y-m-d H:i:s'); + } + + /** 以定时的2倍倒叙时间删除已经重命名的文件夹路径 */ + $Ddir = APP_ROOT . $config['path'] . date('Y/m/d', strtotime(-$config['auto_delete'] * 2 . 'day')) . '_auto_delete'; // 文件夹路径 + if (is_dir($Ddir)) { // 执行删除 + try { + if (deldir($Ddir)) { + $log = $Ddir . ' delete succees ' . date('Y-m-d H:i:s'); + } else { + throw new Exception($Ddir . ' delete failed ' . date('Y-m-d H:i:s')); + } + } catch (Exception $e) { + $log = $e->getMessage(); + } + } + + /** 创建日志文件夹及文件 */ + if (!is_dir(APP_ROOT . '/admin/logs/tasks/')) { + mkdir(APP_ROOT . '/admin/logs/tasks/', 0755, true); + } + + if (!is_file(APP_ROOT . '/admin/logs/tasks/auto_delete.php')) { + file_put_contents(APP_ROOT . '/admin/logs/tasks/auto_delete.php', '' . PHP_EOL, FILE_APPEND | LOCK_EX); + } + + // 写入日志 + file_put_contents(APP_ROOT . '/admin/logs/tasks/auto_delete.php', $log . PHP_EOL, FILE_APPEND | LOCK_EX); + return true; + } + return false; +} + +/** + * 记录登录日志 + * @param String $user 登录用户 + * @param String $pass 登录密码 + * @param String $msg 登录提示 + */ + +function write_login_log($user, $pass, $msg) +{ + $log_path = APP_ROOT . '/admin/logs/login/'; + $log_file = $log_path . date('/Y-m-') . 'logs.php'; + + /** 创建日志文件夹及文件 */ + if (!is_dir($log_path)) mkdir($log_path, 0755, true); + if (!is_file($log_file)) file_put_contents($log_file, '' . PHP_EOL, FILE_APPEND | LOCK_EX); + + /** 写入日志 */ + $log = '时间: ' . date('Y-m-d H:i:s') . ' IP: ' . real_ip() . ' 账号: ' . $user . ' 密码: ' . $pass . ' 消息: ' . $msg; + file_put_contents($log_file, $log . PHP_EOL, FILE_APPEND | LOCK_EX); +} + +/** + * 其他上传 + * 支持: FTP + * @param String $remoteFile 远程地址 + * @param String $localFile 本地地址 + * @param String $way 使用方式 upload 上传 | delete 删除 + */ + +function any_upload($remoteFile = null, $localFile = null, $way = 'upload') +{ + global $config; + + if (!$config['ftp_status']) exit; + + require_once __DIR__ . '/FtpClient/FtpClient.php'; + require_once __DIR__ . '/FtpClient/FtpException.php'; + require_once __DIR__ . '/FtpClient/FtpWrapper.php'; + + $ftp = new FtpClient(); + // FTP 基本信息 + $ftp->connect($config['ftp_host'], $config['ftp_ssl'], $config['ftp_port'], $config['ftp_time']); + // FTP账号密码 + $ftp->login($config['ftp_user'], $config['ftp_pass']); + // FTP主动|被动 + $ftp->pasv($config['ftp_pasv']); + + switch ($way) { + case 'upload': + // 创建文件夹 + $ftp->mkdir(pathinfo($remoteFile, PATHINFO_DIRNAME), 0755, true); + // 上传文件 远端->本地 + $ftp->put($remoteFile, $localFile); + break; + case 'delete': + $ftp->delete($remoteFile); + return true; + break; + } + $ftp->close(); +} diff --git a/application/header.php b/app/header.php old mode 100755 new mode 100644 similarity index 86% rename from application/header.php rename to app/header.php index ac7aadc..6dd3dd3 --- a/application/header.php +++ b/app/header.php @@ -1,59 +1,59 @@ - - - - - - - - - - - - <?php echo $config['title']; ?> - - - - - - - - - - - - - + + + + + + + + + + + + <?php echo $config['title']; ?> + + + + + + + + + + + + + \ No newline at end of file diff --git a/application/hide.php b/app/hide.php old mode 100755 new mode 100644 similarity index 95% rename from application/hide.php rename to app/hide.php index 1d7d3f5..8a87fd0 --- a/application/hide.php +++ b/app/hide.php @@ -1,33 +1,33 @@ - array('source' => '日志文件不存在, 请在图床安全中开启上传日志!', 'date' => '日志文件不存在, 请在图床安全中开启上传日志!', 'ip' => '0.0.0.0', 'port' => '0', 'user_agent' => '日志文件不存在, 请在图床安全中开启上传日志!', 'path' => '日志文件不存在, 请在图床安全中开启上传日志!', 'size' => '日志文件不存在, 请在图床安全中开启上传日志!', 'md5' => '日志文件不存在, 请在图床安全中开启上传日志!', 'checkImg' => '日志文件不存在, 请在图床安全中开启上传日志!', 'from' => '日志文件不存在, 请在图床安全中开启上传日志!')); -} -if (empty($logs[$logsName])) { - $logs = array($logsName => array('source' => '日志不存在', 'date' => '日志不存在', 'ip' => '0.0.0.0', 'port' => '0', 'user_agent' => '日志不存在', 'path' => '日志不存在', 'size' => '日志不存在', 'md5' => '日志不存在', 'checkImg' => '日志不存在', 'from' => '日志不存在')); -} -// 图片真实路径 -$imgABPath = APP_ROOT . $getIMG; -// 图片是否存在 -if (!is_file($imgABPath)) { - $imgABPath = APP_ROOT . "/public/images/404.png"; - $img_url = $config['domain'] . "/public/images/404.png"; -} - -// 图片尺寸 -$imgSize = filesize($imgABPath); -// 上传时间 -$upTime = filemtime($imgABPath); -// 广告 -if ($config['ad_top']) echo $config['ad_top_info']; -?> -
    -
    - <?php echo $img_url; ?> -
    -
    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    图片名称
    图片大小
    图片类型image/
    图片宽高px
    上传时间
    原始名称
    原始大小
    上传者IP
    上传地址
    监黄状态
    上传方式
    文件路径
    文件MD5
    文件操作 - 查看 - 刷新 - 下载 - - 举报 - - - 回收 - 删除 - -
    -

    此图片来自网友上传, 不代表本站立场, 若有侵权, 请举报或联系管理员!

    -
    -
    -
    -
    -
    - 直 链          - - -
    -
    -
    -
    - 论坛代码    - - -
    -
    -
    -
    -
    -
    - MarkDown - - -
    -
    -
    -
    - HTML         - - -
    -
    -
    - - - -
    -

    当月随机图片:

    -
    - - - - -

    本月没有上传图片或上传日志不存在~~

    - -
    -
    - - - - - array('source' => '请在图床安全中开启上传日志!', 'date' => '请在图床安全中开启上传日志!', 'ip' => '0.0.0.0', 'port' => '0', 'user_agent' => '请在图床安全中开启上传日志!', 'path' => '请在图床安全中开启上传日志!', 'size' => '请在图床安全中开启上传日志!', 'md5' => '请在图床安全中开启上传日志!', 'checkImg' => '请在图床安全中开启上传日志!', 'from' => '请在图床安全中开启上传日志!')); +} +if (empty($logs[$logsName])) { + $logs = array($logsName => array('source' => '日志不存在', 'date' => '日志不存在', 'ip' => '0.0.0.0', 'port' => '0', 'user_agent' => '日志不存在', 'path' => '日志不存在', 'size' => '日志不存在', 'md5' => '日志不存在', 'checkImg' => '日志不存在', 'from' => '日志不存在')); +} +// 图片真实路径 +$imgABPath = APP_ROOT . $getIMG; +// 图片是否存在 +if (!is_file($imgABPath)) { + $imgABPath = APP_ROOT . "/public/images/404.png"; + $img_url = $config['domain'] . "/public/images/404.png"; +} + +// 图片尺寸 +$imgSize = filesize($imgABPath); +// 上传时间 +$upTime = filemtime($imgABPath); +// 广告 +if ($config['ad_top']) echo $config['ad_top_info']; +?> +
    +
    + <?php echo $img_url; ?> +
    +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    图片名称
    图片大小
    图片类型image/
    图片宽高px
    上传时间
    原始名称
    原始大小
    上传者IP
    上传地址
    监黄状态
    上传方式
    文件路径
    文件MD5
    文件操作 + 查看 + 刷新 + 下载 + + 举报 + + + 回收 + 删除 + +
    +

    此图片来自网友上传, 不代表本站立场, 若有侵权, 请举报或联系管理员!

    +
    +
    +
    +
    +
    + 直 链          + + +
    +
    +
    +
    + 论坛代码    + + +
    +
    +
    +
    +
    +
    + MarkDown + + +
    +
    +
    +
    + HTML         + + +
    +
    +
    + + + +
    +

    当月随机图片:

    +
    + + + + +

    本月没有上传图片或上传日志不存在~~

    + +
    +
    + + + + + -
    -
    - -
    管理员关闭了预览哦~~
    - - - new $.zui.Messager("已超出浏览页数, 返回今日上传列表", { - type: "info", // 定义颜色主题 - icon: "exclamation-sign" // 定义消息图标 - }).show(); - '; - } else { - $path = $_GET['date']; // 如果不小于则返回当前GET日期 - } - } - - $path = preg_replace("/^d{4}-d{2}-d{2} d{2}:d{2}:d{2}$/s", "", trim($path)); // 过滤非日期,删除空格 - $keyNum = isset($_GET['num']) ? $_GET['num'] : $config['listNumber']; // 获取指定浏览数量 - $keyNum = preg_replace("/[\W]/", "", trim($keyNum)); // 过滤非数字,删除空格 - // $fileArr = getFile(APP_ROOT . config_path($path)); // 获取当日上传列表 - $fileType = isset($_GET['search']) ? '*.' . preg_replace("/[\W]/", "", $_GET['search']) : '*.*'; // 按照图片格式 - $fileArr = get_file_by_glob(APP_ROOT . config_path($path) . $fileType, 'list'); // 获取当日上传列表 - $allUploud = isset($_GET['date']) ? $_GET['date'] : date('Y/m/d/'); - $allUploud = get_file_by_glob(APP_ROOT . $config['path'] . $allUploud, 'number'); // 当前日期全部上传 - $httpUrl = array('date' => $path, 'num' => getFileNumber(APP_ROOT . config_path($path))); // 组合url - - // 隐藏path目录获取图片复制与原图地址 - if ($config['hide_path']) { - $config_path = str_replace($config['path'], '/', config_path($path)); - } else { - $config_path = config_path($path); - } - - if (empty($fileArr[0])) : ?> -
    今天还没有上传的图片哟~~
    快来上传第一张吧~!
    - - - -
    -
    -
    -
    -
    -
    - 当前 - 今日 - ">昨日 - ' . date('j号', strtotime("-$x day")) . ''; - ?> -
    - - - -
    -
    - - -
    -
    - JPG - PNG - GIF - Webp -
    -
    - -
    -
    -
    - - - - - -
    -
    - -
    -
    -
    - - - - - - - - - - - - +
    +
    + +
    管理员关闭了预览哦~~
    + + + new $.zui.Messager("已超出浏览页数, 返回今日上传列表", { + type: "info", // 定义颜色主题 + icon: "exclamation-sign" // 定义消息图标 + }).show(); + '; + } else { + $path = $_GET['date']; // 如果不小于则返回当前GET日期 + } + } + + $path = preg_replace("/^d{4}-d{2}-d{2} d{2}:d{2}:d{2}$/s", "", trim($path)); // 过滤非日期,删除空格 + $keyNum = isset($_GET['num']) ? $_GET['num'] : $config['listNumber']; // 获取指定浏览数量 + $keyNum = preg_replace("/[\W]/", "", trim($keyNum)); // 过滤非数字,删除空格 + // $fileArr = getFile(APP_ROOT . config_path($path)); // 获取当日上传列表 + $fileType = isset($_GET['search']) ? '*.' . preg_replace("/[\W]/", "", $_GET['search']) : '*.*'; // 按照图片格式 + $fileArr = get_file_by_glob(APP_ROOT . config_path($path) . $fileType, 'list'); // 获取当日上传列表 + $allUploud = isset($_GET['date']) ? $_GET['date'] : date('Y/m/d/'); + $allUploud = get_file_by_glob(APP_ROOT . $config['path'] . $allUploud, 'number'); // 当前日期全部上传 + $httpUrl = array('date' => $path, 'num' => getFileNumber(APP_ROOT . config_path($path))); // 组合url + + // 隐藏path目录获取图片复制与原图地址 + if ($config['hide_path']) { + $config_path = str_replace($config['path'], '/', config_path($path)); + } else { + $config_path = config_path($path); + } + + if (empty($fileArr[0])) : ?> +
    今天还没有上传的图片哟~~
    快来上传第一张吧~!
    + +
      +
      + $value) { + if ($key < $keyNum) { + $relative_path = config_path($path) . $value; // 相对路径 + $imgUrl = $config['domain'] . $relative_path; // 图片地址 + $linkUrl = rand_imgurl() . $config_path . $value; // 图片复制与原图地址 + ?> +
      +
      +
    • 简单图床-EasyImage
    • +
      + + + + + + + + + + + + + + +
      +
      +
      + +
      +
    + +
    +
    +
    +
    +
    +
    + 当前 + 今日 + ">昨日 + ' . date('j号', strtotime("-$x day")) . ''; + ?> +
    + + + +
    +
    + + +
    +
    + JPG + PNG + GIF + Webp +
    +
    + +
    +
    +
    + + + + + +
    +
    + +
    +
    +
    + + + + + + + + + + + +

    忘记账号可以打开/config/config.php文件找到user对应的键值->填入

    -

    忘记密码请将密码转换成SHA256(转换网址)->打开/config/config.php文件->找到password对应的键值->填入

    +

    忘记密码请将密码转换成SHA256(转换网址)->打开/config/config.php文件->找到password对应的键值->填入

    更改后会立即生效并重新登录,请务必牢记账号和密码!

    diff --git a/application/thumb.php b/app/thumb.php old mode 100755 new mode 100644 similarity index 97% rename from application/thumb.php rename to app/thumb.php index 4304016..3297bd8 --- a/application/thumb.php +++ b/app/thumb.php @@ -1,133 +1,133 @@ - $totalJsonMD5, // 统计文件名称 - 'date' => date('YmdH'), // 识别日期格式 - 'total_time' => date('Y-m-d H:i:s'), // 统计时间 - 'dirnum' => $dirn, // 文件夹数量 - 'filenum' => $filen, // 文件数量 - 'usage_space' => $usage_space, // 占用空间 - 'todayUpload' => $todayUpload, // 今日上传数量 - 'yestUpload' => $yestUpload // 昨日上传数量 - ]; - $totalJsonInfo = json_encode($totalJsonInfo, true); - if (is_dir(APP_ROOT . '/admin/logs/counts/')) { - file_put_contents($totalJsonName, $totalJsonInfo); - } else { - mkdir(APP_ROOT . '/admin/logs/counts/', 0777, true); // 创建cache目录 - file_put_contents($totalJsonName, $totalJsonInfo); - } -} -function read_total_json($total) // 读取json文件 -{ - global $totalJsonFile; - global $totalJsonName; - global $config; - $cache_freq = $config['cache_freq']; - - if (file_exists($totalJsonName)) { - $totalJsonFile = file_get_contents($totalJsonName); - $totalJsonFile = json_decode($totalJsonFile, true); - } else { - creat_json(); - $totalJsonFile = file_get_contents($totalJsonName); - $totalJsonFile = json_decode($totalJsonFile, true); - } - - if ((date('YmdH') - $totalJsonFile['date']) > $cache_freq) { - creat_json(); - $totalJsonFile = file_get_contents($totalJsonName); - $totalJsonFile = json_decode($totalJsonFile, true); - } - - return $totalJsonFile[$total]; -} + $totalJsonMD5, // 统计文件名称 + 'date' => date('YmdH'), // 识别日期格式 + 'total_time' => date('Y-m-d H:i:s'), // 统计时间 + 'dirnum' => $dirn, // 文件夹数量 + 'filenum' => $filen, // 文件数量 + 'usage_space' => $usage_space, // 占用空间 + 'todayUpload' => $todayUpload, // 今日上传数量 + 'yestUpload' => $yestUpload // 昨日上传数量 + ]; + $totalJsonInfo = json_encode($totalJsonInfo, true); + if (is_dir(APP_ROOT . '/admin/logs/counts/')) { + file_put_contents($totalJsonName, $totalJsonInfo); + } else { + mkdir(APP_ROOT . '/admin/logs/counts/', 0777, true); // 创建cache目录 + file_put_contents($totalJsonName, $totalJsonInfo); + } +} +function read_total_json($total) // 读取json文件 +{ + global $totalJsonFile; + global $totalJsonName; + global $config; + $cache_freq = $config['cache_freq']; + + if (file_exists($totalJsonName)) { + $totalJsonFile = file_get_contents($totalJsonName); + $totalJsonFile = json_decode($totalJsonFile, true); + } else { + creat_json(); + $totalJsonFile = file_get_contents($totalJsonName); + $totalJsonFile = json_decode($totalJsonFile, true); + } + + if ((date('YmdH') - $totalJsonFile['date']) > $cache_freq) { + creat_json(); + $totalJsonFile = file_get_contents($totalJsonName); + $totalJsonFile = json_decode($totalJsonFile, true); + } + + return $totalJsonFile[$total]; +} diff --git a/application/upload.php b/app/upload.php old mode 100755 new mode 100644 similarity index 92% rename from application/upload.php rename to app/upload.php index 02a86f7..2d98612 --- a/application/upload.php +++ b/app/upload.php @@ -1,235 +1,235 @@ - "failed", - "code" => 401, - "message" => "本站已开启登陆上传,您尚未登陆", - ))); - } -} - -// 无文件 -if (empty($_FILES['file'])) { - exit(json_encode( - array( - "result" => "failed", - "code" => 204, - "message" => "没有选择上传的文件", - ) - )); -} - -// sign -if (empty($_REQUEST['sign']) || $_REQUEST['sign'] !== date('YmdH')) { - exit(json_encode(array( - "result" => "failed", - "code" => 403, - "message" => "签名错误,请刷新重试", - ))); -} - -// 黑/白IP名单上传 -if ($config['check_ip']) { - if (checkIP(null, $config['check_ip_list'], $config['check_ip_model'])) { - // 上传错误 code:403 未授权IP - exit(json_encode(array( - "result" => "failed", - "code" => 403, - "message" => "黑名单内或白名单外用户不允许上传", - ))); - } -} - -// 根据IP限制游客每日上传数量 -if ($config['ip_upload_counts'] > 0 && !is_who_login('status')) { - if (false == get_ip_upload_log_counts(real_ip())) { - exit(json_encode( - array( - "result" => "failed", - "code" => 403, - "message" => sprintf("游客限制每日上传 %d 张", $config['ip_upload_counts']), - ) - )); - } -} - -$handle = new Upload($_FILES['file'], 'zh_CN'); - -if ($handle->uploaded) { - // 允许上传的mime类型 - if ($config['allowed'] === 1) { - $handle->allowed = array('image/*'); - } - - // 检查svg是否存在script和a标签代码 - if ($handle->file_src_name_ext === 'svg') { - $svg = file_get_contents($handle->file_src_pathname); - if (preg_match('//', $svg) || stripos($svg, 'href=')) { - exit(json_encode( - array( - "result" => "failed", - "code" => 205, - "message" => "请勿上传非法文件", - ) - )); - } - } - - // 文件命名 - $handle->file_new_name_body = imgName($handle->file_src_name_body); - - // 最大上传限制 - $handle->file_max_size = $config['maxSize']; - // 最大宽度 - $handle->image_max_width = $config['maxWidth']; - // 最大高度 - $handle->image_max_height = $config['maxHeight']; - // 最小宽度 - $handle->image_min_width = $config['minWidth']; - // 最小高度 - $handle->image_min_height = $config['minHeight']; - // 2023-01-06 转换图片为指定格式 只转换非webp格式和非动态图片 - if ($handle->file_src_name_ext !== 'webp' && !isGifAnimated($handle->file_src_pathname)) { - $handle->image_convert = $config['imgConvert']; - } - // 2023-01-06 PNG 图像的压缩级别,介于 1(快速但大文件)和 9(慢但较小文件)之间 - $handle->png_compression = 9 - round($config['compress_ratio'] / 11.2); - // WEBP 图像的压缩质量 1-100 - $handle->webp_quality = $config['compress_ratio']; - // JPEG 图像的压缩质量 1-100 - $handle->jpeg_quality = $config['compress_ratio']; - - /* 等比例缩减图片 放到前端了*/ - /* - if ($config['imgRatio']) { - $handle->image_resize = true; - $handle->image_x = $config['image_x']; - $handle->image_y = $config['image_y']; - // 如果调整后的图像大于原始图像,则取消调整大小,以防止放大 - $handle->image_no_enlarging = true; - } - */ - - /** - * 为管理员和登陆用户创建自定义上传目录 - * 管理员上传目录为自定义目录 - * 上传者目录为其用户名 - * 2022年5月1日 - */ - - // 默认目录 - $Img_path = config_path(); - - // 开启管理员自定义目录 - if ($config['admin_path_status']) { - if (checkLogin() == 204) { - $Img_path = config_path($config['admin_path'] . date('/Y/m/d/')); - } - } - - // 开启上传者单独目录 - if ($config['guest_path_status']) { - if (checkLogin() == 205) { - $getCok = json_decode($_COOKIE['auth']); - $Img_path = config_path($getCok[0] . date('/Y/m/d/')); - } - } - - // 存储图片路径:i/201807/ - $handle->process(APP_ROOT . $Img_path); - - // 图片完整相对路径:/i/2021/05/03/k88e7p.jpg - if ($handle->processed) { - header('Content-type:text/json'); - - // 图片相对路径 - $pathIMG = $Img_path . $handle->file_dst_name; - // 图片访问网址 - $imageUrl = rand_imgurl() . $pathIMG; - // 后续处理地址 - $processUrl = $config['domain'] . $pathIMG; - - // 隐藏config文件中的path目录,需要搭配网站设置 - if ($config['hide_path'] == 1) { - $imageUrl = str_replace($config['path'], '/', $imageUrl); - } - - // 源图保护 key值是由crc32加密的hide_key - // $hide_original = $config['hide'] == 1 ? $config['domain'] . '/application/hide.php?key=' . urlHash($pathIMG, 0, crc32($config['hide_key'])) : $imageUrl; - if ($config['hide'] == 1) { - $imageUrl = $config['domain'] . '/application/hide.php?key=' . urlHash($pathIMG, 0, crc32($config['hide_key'])); - } - - // 删除文件链接 - if ($config['show_user_hash_del']) { - $delUrl = $config['domain'] . '/application/del.php?hash=' . urlHash($pathIMG, 0); - } else { - $delUrl = "Admin closed user delete"; - } - - // 当设置访问生成缩略图时自动生成 2022-12-30 修正 2023-01-30 - $handleThumb = $config['domain'] . '/application/thumb.php?img=' . $pathIMG; - if ($config['thumbnail'] == 2) { - // 自定义缩略图长宽 - $handle->image_resize = true; - $handle->image_x = $config['thumbnail_w']; - $handle->image_y = $config['thumbnail_h']; - // 如果调整后的图像大于原始图像,则取消调整大小,以防止放大 - $handle->image_no_enlarging = true; - $handle->file_new_name_body = date('Y_m_d_') . $handle->file_dst_name_body; - $handle->process(APP_ROOT . $config['path'] . 'cache/'); - $handleThumb = $config['domain'] . $config['path'] . 'cache/' . $handle->file_dst_name; - } - - // 上传成功后返回json数据 - $reJson = array( - "result" => "success", - "code" => 200, - "url" => $imageUrl, - "srcName" => $handle->file_src_name_body, - "thumb" => $handleThumb, - "del" => $delUrl, - // "memory" => getDistUsed(memory_get_peak_usage()), // 占用内存 2023-02-12 - ); - echo json_encode($reJson); - $handle->clean(); // 如果取消上传生成缩略图需要恢复此选项功能 - } else { - // 上传错误 code:206 客户端文件有问题 - $reJson = array( - "result" => "failed", - "code" => 206, - "message" => $handle->error, - "memory" => getDistUsed(memory_get_peak_usage()), // 占用内存 2023-02-12 - // 'log' => $handle->log, // 仅用作调试用 - ); - unset($handle); - header('Content-Type:application/json; charset=utf-8'); - exit(json_encode($reJson, JSON_UNESCAPED_UNICODE)); - } - - /** 后续处理 */ - // 使用fastcgi_finish_request操作 - if (function_exists('fastcgi_finish_request')) fastcgi_finish_request(); - // 同IP上传日志 - @write_ip_upload_count_logs(); - // 日志 - @write_upload_logs($pathIMG, $handle->file_src_name, $handle->file_dst_pathname, $handle->file_src_size); - // 鉴黄 - @process_checkImg($processUrl); - // 水印 - @water($handle->file_dst_pathname); - // 压缩 - @process_compress($handle->file_dst_pathname); - // 上传至其他位置 - // @any_upload($pathIMG, APP_ROOT . $pathIMG, 'upload'); - - unset($handle); -} + "failed", + "code" => 401, + "message" => "本站已开启登陆上传,您尚未登陆", + ))); + } +} + +// 无文件 +if (empty($_FILES['file'])) { + exit(json_encode( + array( + "result" => "failed", + "code" => 204, + "message" => "没有选择上传的文件", + ) + )); +} + +// sign +if (empty($_REQUEST['sign']) || $_REQUEST['sign'] !== date('YmdH')) { + exit(json_encode(array( + "result" => "failed", + "code" => 403, + "message" => "签名错误,请刷新重试", + ))); +} + +// 黑/白IP名单上传 +if ($config['check_ip']) { + if (checkIP(null, $config['check_ip_list'], $config['check_ip_model'])) { + // 上传错误 code:403 未授权IP + exit(json_encode(array( + "result" => "failed", + "code" => 403, + "message" => "黑名单内或白名单外用户不允许上传", + ))); + } +} + +// 根据IP限制游客每日上传数量 +if ($config['ip_upload_counts'] > 0 && !is_who_login('status')) { + if (false == get_ip_upload_log_counts(real_ip())) { + exit(json_encode( + array( + "result" => "failed", + "code" => 403, + "message" => sprintf("游客限制每日上传 %d 张", $config['ip_upload_counts']), + ) + )); + } +} + +$handle = new Upload($_FILES['file'], 'zh_CN'); + +if ($handle->uploaded) { + // 允许上传的mime类型 + if ($config['allowed'] === 1) { + $handle->allowed = array('image/*'); + } + + // 检查svg是否存在script和a标签代码 + if ($handle->file_src_name_ext === 'svg') { + $svg = file_get_contents($handle->file_src_pathname); + if (preg_match('//', $svg) || stripos($svg, 'href=')) { + exit(json_encode( + array( + "result" => "failed", + "code" => 205, + "message" => "请勿上传非法文件", + ) + )); + } + } + + // 文件命名 + $handle->file_new_name_body = imgName($handle->file_src_name_body); + + // 最大上传限制 + $handle->file_max_size = $config['maxSize']; + // 最大宽度 + $handle->image_max_width = $config['maxWidth']; + // 最大高度 + $handle->image_max_height = $config['maxHeight']; + // 最小宽度 + $handle->image_min_width = $config['minWidth']; + // 最小高度 + $handle->image_min_height = $config['minHeight']; + // 2023-01-06 转换图片为指定格式 只转换非webp格式和非动态图片 + if ($handle->file_src_name_ext !== 'webp' && !isGifAnimated($handle->file_src_pathname)) { + $handle->image_convert = $config['imgConvert']; + } + // 2023-01-06 PNG 图像的压缩级别,介于 1(快速但大文件)和 9(慢但较小文件)之间 + $handle->png_compression = 9 - round($config['compress_ratio'] / 11.2); + // WEBP 图像的压缩质量 1-100 + $handle->webp_quality = $config['compress_ratio']; + // JPEG 图像的压缩质量 1-100 + $handle->jpeg_quality = $config['compress_ratio']; + + /* 等比例缩减图片 放到前端了*/ + /* + if ($config['imgRatio']) { + $handle->image_resize = true; + $handle->image_x = $config['image_x']; + $handle->image_y = $config['image_y']; + // 如果调整后的图像大于原始图像,则取消调整大小,以防止放大 + $handle->image_no_enlarging = true; + } + */ + + /** + * 为管理员和登陆用户创建自定义上传目录 + * 管理员上传目录为自定义目录 + * 上传者目录为其用户名 + * 2022年5月1日 + */ + + // 默认目录 + $Img_path = config_path(); + + // 开启管理员自定义目录 + if ($config['admin_path_status']) { + if (checkLogin() == 204) { + $Img_path = config_path($config['admin_path'] . date('/Y/m/d/')); + } + } + + // 开启上传者单独目录 + if ($config['guest_path_status']) { + if (checkLogin() == 205) { + $getCok = json_decode($_COOKIE['auth']); + $Img_path = config_path($getCok[0] . date('/Y/m/d/')); + } + } + + // 存储图片路径:i/201807/ + $handle->process(APP_ROOT . $Img_path); + + // 图片完整相对路径:/i/2021/05/03/k88e7p.jpg + if ($handle->processed) { + header('Content-type:text/json'); + + // 图片相对路径 + $pathIMG = $Img_path . $handle->file_dst_name; + // 图片访问网址 + $imageUrl = rand_imgurl() . $pathIMG; + // 后续处理地址 + $processUrl = $config['domain'] . $pathIMG; + + // 隐藏config文件中的path目录,需要搭配网站设置 + if ($config['hide_path'] == 1) { + $imageUrl = str_replace($config['path'], '/', $imageUrl); + } + + // 源图保护 key值是由crc32加密的hide_key + // $hide_original = $config['hide'] == 1 ? $config['domain'] . '/app/hide.php?key=' . urlHash($pathIMG, 0, crc32($config['hide_key'])) : $imageUrl; + if ($config['hide'] == 1) { + $imageUrl = $config['domain'] . '/app/hide.php?key=' . urlHash($pathIMG, 0, crc32($config['hide_key'])); + } + + // 删除文件链接 + if ($config['show_user_hash_del']) { + $delUrl = $config['domain'] . '/app/del.php?hash=' . urlHash($pathIMG, 0); + } else { + $delUrl = "Admin closed user delete"; + } + + // 当设置访问生成缩略图时自动生成 2022-12-30 修正 2023-01-30 + $handleThumb = $config['domain'] . '/app/thumb.php?img=' . $pathIMG; + if ($config['thumbnail'] == 2) { + // 自定义缩略图长宽 + $handle->image_resize = true; + $handle->image_x = $config['thumbnail_w']; + $handle->image_y = $config['thumbnail_h']; + // 如果调整后的图像大于原始图像,则取消调整大小,以防止放大 + $handle->image_no_enlarging = true; + $handle->file_new_name_body = date('Y_m_d_') . $handle->file_dst_name_body; + $handle->process(APP_ROOT . $config['path'] . 'cache/'); + $handleThumb = $config['domain'] . $config['path'] . 'cache/' . $handle->file_dst_name; + } + + // 上传成功后返回json数据 + $reJson = array( + "result" => "success", + "code" => 200, + "url" => $imageUrl, + "srcName" => $handle->file_src_name_body, + "thumb" => $handleThumb, + "del" => $delUrl, + // "memory" => getDistUsed(memory_get_peak_usage()), // 占用内存 2023-02-12 + ); + echo json_encode($reJson); + $handle->clean(); // 如果取消上传生成缩略图需要恢复此选项功能 + } else { + // 上传错误 code:206 客户端文件有问题 + $reJson = array( + "result" => "failed", + "code" => 206, + "message" => $handle->error, + "memory" => getDistUsed(memory_get_peak_usage()), // 占用内存 2023-02-12 + // 'log' => $handle->log, // 仅用作调试用 + ); + unset($handle); + header('Content-Type:application/json; charset=utf-8'); + exit(json_encode($reJson, JSON_UNESCAPED_UNICODE)); + } + + /** 后续处理 */ + // 使用fastcgi_finish_request操作 + if (function_exists('fastcgi_finish_request')) fastcgi_finish_request(); + // 同IP上传日志 + @write_ip_upload_count_logs(); + // 日志 + @write_upload_logs($pathIMG, $handle->file_src_name, $handle->file_dst_pathname, $handle->file_src_size); + // 鉴黄 + @process_checkImg($processUrl); + // 水印 + @water($handle->file_dst_pathname); + // 压缩 + @process_compress($handle->file_dst_pathname); + // 上传至其他位置 + // @any_upload($pathIMG, APP_ROOT . $pathIMG, 'upload'); + + unset($handle); +} diff --git a/application/viewlog.php b/app/viewlog.php similarity index 92% rename from application/viewlog.php rename to app/viewlog.php index bfc7d21..45f2d58 100644 --- a/application/viewlog.php +++ b/app/viewlog.php @@ -24,7 +24,7 @@ if (isset($_GET['login_log'])) { } // 上传日志 -require_once APP_ROOT . '/application/header.php'; +require_once APP_ROOT . '/app/header.php'; if (isset($_POST['logDate'])) { $logFile = APP_ROOT . '/admin/logs/upload/' . $_POST['logDate'] . '.php'; @@ -43,7 +43,7 @@ try { } } catch (Exception $e) { echo $e->getMessage(); - require_once APP_ROOT . '/application/footer.php'; + require_once APP_ROOT . '/app/footer.php'; exit; } ?> @@ -155,7 +155,7 @@ try { size: '', checkImg: '', from: '', - manage: "", + manage: "", }, ] @@ -191,4 +191,4 @@ try { document.title = "月上传日志 - " 'month' ), 'language'=>0, - 'login_bg'=>'../application/bing.php', + 'login_bg'=>'../app/bing.php', 'report'=>'', 'image_recycl'=>1, 'tinyfilemanager'=>1, diff --git a/docs/update.md b/docs/update.md index bbc6d04..9b63110 100644 --- a/docs/update.md +++ b/docs/update.md @@ -1,6 +1,7 @@ * 2023-03-06 v2.7.8 - 增加WEB端上传签名 -- 修复一处漏洞 +- 修改目录命名 `applicaton->app` +- 修复两处漏洞 * 2023-03-05 v2.7.7 - 增加登录日志 diff --git a/i/manag.php b/i/manag.php index c784a20..adc4ad7 100644 --- a/i/manag.php +++ b/i/manag.php @@ -7,15 +7,15 @@ session_start(); /**开始 - 自定义修改 */ -require_once __DIR__ . '/../application/function.php'; +require_once __DIR__ . '/../app/function.php'; require_once APP_ROOT . '/config/config.php'; // 开启tinyfilemanager文件管理 if (!$config['file_manage']) { - require_once APP_ROOT . '/application/header.php'; + require_once APP_ROOT . '/app/header.php'; echo '

    文件管理已关闭~~

    '; header("refresh:3;url=" . $config['domain'] . '?manag-closed'); - require_once APP_ROOT . '/application/footer.php'; + require_once APP_ROOT . '/app/footer.php'; exit; } @@ -215,7 +215,7 @@ class RExplorer if (RexHelper::file_catetory($srpath) == 'image') { echo ' - 查看原图 + 查看原图 '; } else { echo ' @@ -328,7 +328,7 @@ class RExplorer return; case 'image': echo ' - + @@ -1080,8 +1080,8 @@ class ZipHelper } /** 环境检测 */ -if ($config['checkEnv']) require_once APP_ROOT . '/application/check.php'; +if ($config['checkEnv']) require_once APP_ROOT . '/app/check.php'; /** 底部广告 */ if ($config['ad_bot']) echo $config['ad_bot_info']; /** 引入底部 */ -require_once APP_ROOT . '/application/footer.php'; +require_once APP_ROOT . '/app/footer.php'; diff --git a/index.php b/index.php index 2ebcdcf..6937636 100755 --- a/index.php +++ b/index.php @@ -1,5 +1,5 @@
    -
    +
    @@ -117,7 +117,7 @@ mustLogin(); // 自动上传 autoUpload: false, // 文件上传提交地址 - url: './application/upload.php', + url: './app/upload.php', // 最大支持的上传文件 max_file_size: , // 分片上传 0为不分片 分片容易使图片上传失败 @@ -187,8 +187,8 @@ mustLogin();