first commit

This commit is contained in:
2026-01-25 18:18:09 +08:00
commit 509312e604
8136 changed files with 2349298 additions and 0 deletions

283
common/FileHelper.php Normal file
View File

@ -0,0 +1,283 @@
<?php
namespace app\common;
use yii\helpers\BaseFileHelper;
use Yii;
/**
* Class FileHelper
* @package common\helpers
* @author jianyan74 <751393839@qq.com>
*/
class FileHelper extends BaseFileHelper
{
public $_speed = 0;
/**
* 检测目录并循环创建目录
*
* @param $catalogue
*/
public static function mkdirs($catalogue)
{
if (!file_exists($catalogue)) {
self::mkdirs(dirname($catalogue));
mkdir($catalogue, 0777);
exec('chown -R www.www '.$catalogue);
}
return true;
}
/**
* 写入日志
*
* @param $path
* @param $content
* @return bool|int
*/
public static function writeLog($path, $content)
{
$use_num = self::sysProbe();
// $use_num = Yii::$app->redis->get(CacheKeyEnum::SYSTEM_PROBE);
if ($use_num > 98) {
return false;
}
self::mkdirs(dirname($path));
return file_put_contents($path, date('Y-m-d H:i:s') . ">>>" . $content . "\r\n", FILE_APPEND);
}
/**
* 检测磁盘空间
* @return bool|int|string
*/
public static function sysProbe()
{
$total = round(@disk_total_space(".") / (1024 * 1024 * 1024), 2);
$free = round(@disk_free_space(".") / (1024 * 1024 * 1024), 2);
$use_num = intval($total - $free) ? : 1;
// exec("df -h", $systemInfo);
// $disk = $systemInfo[5] ?? $systemInfo[1]; //没有找到其他磁盘就默认第一个
// $use_num = 1;
// if ($disk) {
// $use_num = trim(substr($disk, -10, -7)) ? : 1; //媒介保后端服务器磁盘用量
// }
// Yii::$app->redis->setex(CacheKeyEnum::SYSTEM_PROBE, 3600, $use_num);
return $use_num;
}
/**
* 获取文件夹大小
*
* @param string $dir 根文件夹路径
* @return int
*/
public static function getDirSize($dir)
{
$handle = opendir($dir);
$sizeResult = 0;
while (false !== ($FolderOrFile = readdir($handle))) {
if ($FolderOrFile != "." && $FolderOrFile != "..") {
if (is_dir("$dir/$FolderOrFile")) {
$sizeResult += self::getDirSize("$dir/$FolderOrFile");
}
else {
$sizeResult += filesize("$dir/$FolderOrFile");
}
}
}
closedir($handle);
return $sizeResult;
}
/**
* 基于数组创建目录
*
* @param $files
*/
public static function createDirOrFiles($files)
{
foreach ($files as $key => $value) {
if (substr($value, -1) == '/') {
mkdir($value);
}
else {
file_put_contents($value, '');
}
}
}
/**
* 文件大小字节转换对应的单位
* @param $size
* @return string
*/
public static function convert($size)
{
$unit = array('b','kb','MB','GB','tb','pb');
return round($size / pow(1024, ($i = floor(log($size, 1024)))), 2) . '' . $unit[$i];
}
public static function downloadVideo($url)
{
// $is_url = Url::isUrl($url);
// if (!$is_url) {
// exit('不是正确的链接地址'); //exit掉下载下来打开会显示无法播放格式不支持文件已损坏等
// }
//获取文件信息
// $fileExt = pathinfo($url);
//获取文件的扩展名
// $allowDownExt = array ('mp4', 'mov');
//检测文件类型是否允许下载
// if (!in_array($fileExt['extension'], $allowDownExt)) {
// exit('不支持该格式');
// }
// 设置浏览器下载的文件名,这里还以原文件名一样
$filename = basename($url);
// 获取远程文件大小
// 注意filesize()无法获取远程文件大小
$headers = get_headers($url, 1);
$fileSize = $headers['Content-Length'];
if (ini_get('zlib.output_compression')) {
ini_set('zlib.output_compression', 'Off');
}
header_remove('Content-Encoding');
// 设置header头
// 因为不知道文件是什么类型的,告诉浏览器输出的是字节流
header('Content-Type: application/octet-stream');
// 告诉浏览器返回的文件大小类型是字节
header('Accept-Ranges:bytes');
// 告诉浏览器返回的文件大小
header('Content-Length: ' . $fileSize);
// 告诉浏览器文件作为附件处理并且设定最终下载完成的文件名称
header('Content-Disposition: attachment; filename="' . $filename . '"');
//针对大文件规定每次读取文件的字节数为4096字节直接输出数据
$read_buffer = 4096; //4096
$handle = fopen($url, 'rb');
//总的缓冲的字节数
$sum_buffer = 0;
//只要没到文件尾,就一直读取
while (!feof($handle) && $sum_buffer < $fileSize) {
echo fread($handle, $read_buffer);
$sum_buffer += $read_buffer;
}
fclose($handle);
exit;
}
/**
* @param String $file 要下载的文件路径
* @param String $name 文件名称,为空则与下载的文件名称一样
* @param boolean $reload 是否开启断点续传
* @return string
*/
public static function downloadFile($file, $name = '', $reload = false)
{
$log_path = Yii::getAlias('@runtime') . '/api/' . date('Ym') . '/' . date('d') . '/download.txt';
FileHelper::writeLog($log_path, $file);
$fp = fopen($file, 'rb');
if ($fp) {
if ($name == '') {
$name = basename($file);
}
$header_array = get_headers($file, true);
// 下载本地文件,获取文件大小
if (!$header_array) {
$file_size = filesize($file);
} else {
$file_size = $header_array['Content-Length'];
}
FileHelper::writeLog($log_path, json_encode($_SERVER, JSON_UNESCAPED_UNICODE));
if (isset($_SERVER['HTTP_RANGE']) && !empty($_SERVER['HTTP_RANGE'])) {
$ranges = self::getRange($file_size);
} else {
//第一次连接
$size2 = $file_size - 1;
header("Content-Range: bytes 0-$size2/$file_size"); //Content-Range: bytes 0-4988927/4988928
header("Content-Length: " . $file_size); //输出总长
}
$ua = $_SERVER["HTTP_USER_AGENT"];//判断是什么类型浏览器
header('cache-control:public');
header('content-type:application/octet-stream');
$encoded_filename = urlencode($name);
$encoded_filename = str_replace("+", "%20", $encoded_filename);
//解决下载文件名乱码
if (preg_match("/MSIE/", $ua) || preg_match("/Trident/", $ua)) {
header('Content-Disposition: attachment; filename="' . $encoded_filename . '"');
} else if (preg_match("/Firefox/", $ua)) {
header('Content-Disposition: attachment; filename*="utf8\'\'' . $name . '"');
} else if (preg_match("/Chrome/", $ua)) {
header('Content-Disposition: attachment; filename="' . $encoded_filename . '"');
} else {
header('Content-Disposition: attachment; filename="' . $name . '"');
}
//header('Content-Disposition: attachment; filename="' . $name . '"');
if ($reload && $ranges != null) { // 使用续传
header('HTTP/1.1 206 Partial Content');
header('Accept-Ranges:bytes');
// 剩余长度
header(sprintf('content-length:%u', $ranges['end'] - $ranges['start']));
// range信息
header(sprintf('content-range:bytes %s-%s/%s', $ranges['start'], $ranges['end'], $file_size));
FileHelper::writeLog($log_path, sprintf('content-length:%u', $ranges['end'] - $ranges['start']));
// fp指针跳到断点位置
fseek($fp, sprintf('%u', $ranges['start']));
} else {
header('HTTP/1.1 200 OK');
header('content-length:' . $file_size);
}
while (!feof($fp)) {
echo fread($fp, 4096);
ob_flush();
}
($fp != null) && fclose($fp);
} else {
return '';
}
}
/** 设置下载速度
* @param int $speed
*/
public function setSpeed($speed)
{
if (is_numeric($speed) && $speed > 16 && $speed < 4096) {
$this->_speed = $speed;
}
}
/** 获取header range信息
* @param int $file_size 文件大小
* @return Array
*/
private static function getRange($file_size)
{
if (isset($_SERVER['HTTP_RANGE']) && !empty($_SERVER['HTTP_RANGE'])) {
$range = $_SERVER['HTTP_RANGE'];
$range = preg_replace('/[\s|,].*/', '', $range);
$range = explode('-', substr($range, 6));
if (count($range) < 2) {
$range[1] = $file_size;
}
$range = array_combine(array('start','end'), $range);
if (empty($range['start'])) {
$range['start'] = 0;
}
if (empty($range['end'])) {
$range['end'] = $file_size;
}
return $range;
}
return null;
}
}