first commit
This commit is contained in:
13
common/CommonHelper.php
Normal file
13
common/CommonHelper.php
Normal file
@ -0,0 +1,13 @@
|
||||
<?php
|
||||
|
||||
namespace app\common;
|
||||
|
||||
class CommonHelper
|
||||
{
|
||||
public static function getYear(string $title)
|
||||
{
|
||||
preg_match('/([0-9]+)/', $title, $y);
|
||||
|
||||
return $y[1] ?? date('Y');
|
||||
}
|
||||
}
|
||||
167
common/CurlApp.php
Normal file
167
common/CurlApp.php
Normal file
@ -0,0 +1,167 @@
|
||||
<?php
|
||||
|
||||
namespace app\common;
|
||||
|
||||
class CurlApp
|
||||
{
|
||||
private $ch = null;
|
||||
|
||||
private array $options = [];
|
||||
|
||||
private string $headerContentType = '';
|
||||
|
||||
private string $error = '';
|
||||
|
||||
const METHOD_POST = 'POST';
|
||||
|
||||
const METHOD_GET = 'GET';
|
||||
|
||||
const CONTENT_TYPE_JSON = 'Content-Type: application/json';
|
||||
|
||||
const CONTENT_TYPE_FORM_URLENCODED = 'Content-Type: application/x-www-form-urlencoded';
|
||||
|
||||
public function __construct()
|
||||
{
|
||||
$this->ch = curl_init();
|
||||
$this->options[CURLOPT_CONNECTTIMEOUT] = 30;
|
||||
$this->options[CURLOPT_TIMEOUT] = 30;
|
||||
}
|
||||
|
||||
public function setUrl(string $url)
|
||||
{
|
||||
$this->options[CURLOPT_URL] = $url;
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function setCookie(string $cookie)
|
||||
{
|
||||
$this->options[CURLOPT_COOKIE] = $cookie;
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function setReturnTransfer(bool $isReturn = true)
|
||||
{
|
||||
$this->options[CURLOPT_RETURNTRANSFER] = $isReturn;
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function setPostData($data)
|
||||
{
|
||||
$this->options[CURLOPT_POSTFIELDS] = $data;
|
||||
if ($this->headerContentType === self::CONTENT_TYPE_FORM_URLENCODED) {
|
||||
if (is_array($data)) {
|
||||
$this->options[CURLOPT_POSTFIELDS] = http_build_query($data);
|
||||
}
|
||||
} elseif ($this->headerContentType === self::CONTENT_TYPE_JSON) {
|
||||
if (is_array($data)) {
|
||||
$this->options[CURLOPT_POSTFIELDS] = json_encode($data);
|
||||
} else {
|
||||
$this->options[CURLOPT_POSTFIELDS] = ($data);
|
||||
}
|
||||
}
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function setHttpHeader(array $header = [])
|
||||
{
|
||||
foreach ($header as $key => $value) {
|
||||
$this->options[CURLOPT_HTTPHEADER][$key] = $value;
|
||||
}
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function setProxy($ip, $port)
|
||||
{
|
||||
// 基本代理
|
||||
$this->options[CURLOPT_PROXY] = "{$ip}:{$port}";
|
||||
// 指定代理类型(可选:HTTP、SOCKS4、SOCKS5)
|
||||
$this->options[CURLOPT_PROXYTYPE] = CURLPROXY_HTTP;
|
||||
}
|
||||
|
||||
public function setContentType($contentType)
|
||||
{
|
||||
$this->headerContentType = $contentType;
|
||||
$this->options[CURLOPT_HTTPHEADER][] = $contentType;
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function setMethod($method = 'GET')
|
||||
{
|
||||
$this->options[CURLOPT_POST] = !(strtolower($method) == 'get');
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function execMulti($urls = []): array
|
||||
{
|
||||
$multiHandle = curl_multi_init();
|
||||
$handles = [];
|
||||
$responses = [];
|
||||
|
||||
foreach ($urls as $key => $url) {
|
||||
$ch = curl_init();
|
||||
$this->options[CURLOPT_CONNECTTIMEOUT] = 60;
|
||||
$this->options[CURLOPT_TIMEOUT] = 60;
|
||||
// 继承当前 CurlApp 的 options
|
||||
$options = $this->options;
|
||||
|
||||
$options[CURLOPT_URL] = $url;
|
||||
$options[CURLOPT_RETURNTRANSFER] = true;
|
||||
|
||||
curl_setopt_array($ch, $options);
|
||||
|
||||
curl_multi_add_handle($multiHandle, $ch);
|
||||
$handles[$key] = $ch;
|
||||
}
|
||||
|
||||
// 执行
|
||||
$running = null;
|
||||
do {
|
||||
$status = curl_multi_exec($multiHandle, $running);
|
||||
if ($running) {
|
||||
curl_multi_select($multiHandle, 1);
|
||||
}
|
||||
} while ($running && $status === CURLM_OK);
|
||||
|
||||
// 收集结果
|
||||
foreach ($handles as $key => $ch) {
|
||||
$responses[$key] = curl_multi_getcontent($ch);
|
||||
curl_multi_remove_handle($multiHandle, $ch);
|
||||
curl_close($ch);
|
||||
}
|
||||
|
||||
curl_multi_close($multiHandle);
|
||||
|
||||
return $responses;
|
||||
|
||||
}
|
||||
|
||||
public function exec()
|
||||
{
|
||||
$defaultOptions = [
|
||||
CURLOPT_RETURNTRANSFER => true,
|
||||
CURLOPT_SSL_VERIFYHOST => false,
|
||||
];
|
||||
|
||||
foreach ($defaultOptions as $key => $val) {
|
||||
if (!isset($this->options[$key])) {
|
||||
$this->options[$key] = $val;
|
||||
}
|
||||
}
|
||||
|
||||
curl_setopt_array($this->ch, $this->options);
|
||||
$resp = curl_exec($this->ch);
|
||||
|
||||
if (curl_errno($this->ch)) {
|
||||
$this->error = curl_error($this->ch);
|
||||
return false;
|
||||
}
|
||||
|
||||
curl_close($this->ch);
|
||||
return $resp;
|
||||
}
|
||||
|
||||
public function getError()
|
||||
{
|
||||
return $this->error;
|
||||
}
|
||||
}
|
||||
283
common/FileHelper.php
Normal file
283
common/FileHelper.php
Normal 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;
|
||||
}
|
||||
}
|
||||
16
common/ImageHelper.php
Normal file
16
common/ImageHelper.php
Normal file
@ -0,0 +1,16 @@
|
||||
<?php
|
||||
|
||||
namespace app\common;
|
||||
|
||||
class ImageHelper
|
||||
{
|
||||
public static function imageMogr2H480(string $imageUrl): string
|
||||
{
|
||||
return "{$imageUrl}-h480";
|
||||
}
|
||||
|
||||
public static function imageMogr2H1080(string $imageUrl): string
|
||||
{
|
||||
return "{$imageUrl}-h1080";
|
||||
}
|
||||
}
|
||||
18
common/MobileHelper.php
Normal file
18
common/MobileHelper.php
Normal file
@ -0,0 +1,18 @@
|
||||
<?php
|
||||
|
||||
namespace app\common;
|
||||
|
||||
class MobileHelper
|
||||
{
|
||||
public static function isValidChinaMobile($remarkDict): bool
|
||||
{
|
||||
if (is_string($remarkDict) && $remarkDict) {
|
||||
$val = json_decode($remarkDict, true);
|
||||
if (isset($val['是否为隐私号']) && $val['是否为隐私号'] == '是') {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
93
common/PaginationHelper.php
Normal file
93
common/PaginationHelper.php
Normal file
@ -0,0 +1,93 @@
|
||||
<?php
|
||||
|
||||
|
||||
namespace app\common;
|
||||
|
||||
|
||||
use yii\data\ActiveDataProvider;
|
||||
use yii\data\ArrayDataProvider;
|
||||
use yii\db\ActiveQuery;
|
||||
use yii\db\QueryInterface;
|
||||
use yii\di\NotInstantiableException;
|
||||
|
||||
class PaginationHelper
|
||||
{
|
||||
|
||||
/**
|
||||
*
|
||||
* @param \yii\db\ActiveQuery $query
|
||||
* @param int $limit
|
||||
* @param string $pageParam
|
||||
* @param string $pageSizeParam
|
||||
*
|
||||
* @return \yii\data\ActiveDataProvider
|
||||
*/
|
||||
public static function createDataProvider($query, $limit = 10, $pageParam = 'page', $pageSizeParam = 'per_page')
|
||||
{
|
||||
$dataProvider = new ActiveDataProvider([
|
||||
'query' => $query,
|
||||
'pagination' => [
|
||||
//分页大小
|
||||
'pageSize' => \Yii::$app->request->get($pageSizeParam) ?: $limit,
|
||||
//设置地址栏当前页数参数名
|
||||
'pageParam' => $pageParam,
|
||||
//设置地址栏分页大小参数名
|
||||
'pageSizeParam' => $pageSizeParam,
|
||||
],
|
||||
]);
|
||||
|
||||
return $dataProvider;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $query
|
||||
* @param int $limit
|
||||
* @param string $pageParam
|
||||
* @param string $pageSizeParam
|
||||
*
|
||||
* @return \yii\db\QueryInterface
|
||||
* @throws \yii\di\NotInstantiableException
|
||||
*/
|
||||
public static function createQueryProvider($query, $limit = 10, $pageParam = 'page', $pageSizeParam = 'limit')
|
||||
{
|
||||
$param = \Yii::$app->request->get();
|
||||
$pageSize = $param['limit'] ?: $param[$pageSizeParam];
|
||||
|
||||
if ($query instanceof QueryInterface) {
|
||||
return $query->limit($pageSize)->offset(($param[$pageParam] - 1) * $pageSize);
|
||||
}
|
||||
throw new NotInstantiableException('not instanceof QueryInterFace');
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $array
|
||||
* @param int $limit
|
||||
* @param string $pageParam
|
||||
* @param string $pageSizeParam
|
||||
* @param array $orderFields
|
||||
*
|
||||
* @return ArrayDataProvider
|
||||
*/
|
||||
public static function createArrayDataProvider($array = [], $orderFields = [], $limit = 10, $pageParam = 'page', $pageSizeParam = 'limit')
|
||||
{
|
||||
$attributes = array_keys($orderFields);
|
||||
$order = $orderFields;
|
||||
$dataProvider = new ArrayDataProvider([
|
||||
'allModels' => $array,
|
||||
'sort' => [
|
||||
'attributes' => $attributes,
|
||||
'defaultOrder' => $order
|
||||
],
|
||||
'pagination' => [
|
||||
//分页大小
|
||||
'pageSize' => \Yii::$app->request->get($pageSizeParam, 10),
|
||||
//设置地址栏当前页数参数名
|
||||
'pageParam' => $pageParam,
|
||||
//设置地址栏分页大小参数名
|
||||
'pageSizeParam' => $pageSizeParam,
|
||||
],
|
||||
]);
|
||||
|
||||
return $dataProvider;
|
||||
}
|
||||
}
|
||||
11
common/SaltHelper.php
Normal file
11
common/SaltHelper.php
Normal file
@ -0,0 +1,11 @@
|
||||
<?php
|
||||
|
||||
namespace app\common;
|
||||
|
||||
class SaltHelper
|
||||
{
|
||||
public static function addSalt(string $data)
|
||||
{
|
||||
return $data . \Yii::$app->params['salt'];
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user