优化插件
This commit is contained in:
parent
a54e206e00
commit
108083fca2
@ -577,6 +577,4 @@ abstract class BaseController
|
|||||||
return $content;
|
return $content;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -3,53 +3,52 @@ namespace app\admin\controller;
|
|||||||
|
|
||||||
use app\common\controller\AdminController;
|
use app\common\controller\AdminController;
|
||||||
use app\common\lib\SqlFile;
|
use app\common\lib\SqlFile;
|
||||||
|
use app\common\lib\Zip;
|
||||||
use think\Exception;
|
use think\Exception;
|
||||||
use think\facade\View;
|
use think\facade\View;
|
||||||
use think\facade\Request;
|
use think\facade\Request;
|
||||||
use think\facade\Config;
|
use think\facade\Config;
|
||||||
use app\admin\model\Addons as AddonsModel;
|
|
||||||
use taoler\com\Files;
|
|
||||||
use taoler\com\Api;
|
|
||||||
use app\common\lib\Zip;
|
|
||||||
use think\response\Json;
|
|
||||||
use app\admin\model\AuthRule;
|
use app\admin\model\AuthRule;
|
||||||
|
use app\admin\model\Addons as AddonsModel;
|
||||||
|
use think\response\Json;
|
||||||
use Symfony\Component\VarExporter\VarExporter;
|
use Symfony\Component\VarExporter\VarExporter;
|
||||||
|
use taoler\com\Files;
|
||||||
|
use app\common\lib\facade\HttpHelper;
|
||||||
|
|
||||||
class Addons extends AdminController
|
class Addons extends AdminController
|
||||||
{
|
{
|
||||||
/**
|
/**
|
||||||
* @return string
|
*
|
||||||
*/
|
*/
|
||||||
public function index()
|
public function index()
|
||||||
{
|
{
|
||||||
|
if(Request::isAjax()) {
|
||||||
|
$data = Request::param();
|
||||||
|
if(!isset($data['type'])) $data['type'] = 'onlineAddons';
|
||||||
|
if(!isset($data['selector'])) $data['selector'] = 'all';
|
||||||
|
return $this->getList($data);
|
||||||
|
}
|
||||||
return View::fetch();
|
return View::fetch();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 插件动态列表
|
* 插件动态列表
|
||||||
|
* @param $data
|
||||||
* @return Json
|
* @return Json
|
||||||
*/
|
*/
|
||||||
public function addonsList()
|
public function getList($data)
|
||||||
{
|
{
|
||||||
$data = Request::param();
|
|
||||||
$res = [];
|
$res = [];
|
||||||
//本地插件列表
|
//本地插件列表
|
||||||
$addonsList = Files::getDirName('../addons/');
|
$addonsList = Files::getDirName('../addons/');
|
||||||
$url = $this->getSystem()['api_url'].'/v1/addons';
|
$response = HttpHelper::withHost()->get('/v1/addons');
|
||||||
$addons = Api::urlGet($url);
|
$addons = $response->toJson();
|
||||||
|
|
||||||
switch($data['type']){
|
switch($data['type']){
|
||||||
//已安装
|
//已安装
|
||||||
case 'installed':
|
case 'installed':
|
||||||
if($addonsList){
|
if($addonsList){
|
||||||
$res = ['code'=>0,'msg'=>'','count'=>5];
|
$res = ['code'=>0,'msg'=>'','count'=>5];
|
||||||
foreach($addonsList as $v){
|
|
||||||
$info_file = '../addons/'.$v.'/info.ini';
|
|
||||||
$info = parse_ini_file($info_file);
|
|
||||||
$info['show'] = $info['status'] ? '启用' : '禁用';
|
|
||||||
$info['install'] = $info['status'] ? '是' : '否';
|
|
||||||
$res['data'][] = $info;
|
|
||||||
}
|
|
||||||
$res['col'] = [
|
$res['col'] = [
|
||||||
['type' => 'numbers'],
|
['type' => 'numbers'],
|
||||||
['field' => 'name','title'=> '插件', 'width'=> 120],
|
['field' => 'name','title'=> '插件', 'width'=> 120],
|
||||||
@ -62,14 +61,40 @@ class Addons extends AdminController
|
|||||||
['field' => 'status','title'=> '状态', 'width'=> 95, 'templet' => '#buttonStatus'],
|
['field' => 'status','title'=> '状态', 'width'=> 95, 'templet' => '#buttonStatus'],
|
||||||
['title' => '操作', 'width'=> 150, 'align'=>'center', 'toolbar'=> '#addons-installed-tool']
|
['title' => '操作', 'width'=> 150, 'align'=>'center', 'toolbar'=> '#addons-installed-tool']
|
||||||
];
|
];
|
||||||
|
|
||||||
|
// $data数据
|
||||||
|
foreach($addonsList as $v){
|
||||||
|
$info_file = '../addons/'.$v.'/info.ini';
|
||||||
|
$info = parse_ini_file($info_file);
|
||||||
|
$info['show'] = $info['status'] ? '启用' : '禁用';
|
||||||
|
$info['install'] = $info['status'] ? '是' : '否';
|
||||||
|
$res['data'][] = $info;
|
||||||
|
}
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
$res = ['code'=>-1,'msg'=>'没有安装任何插件'];
|
$res = ['code'=>-1,'msg'=>'没有安装任何插件'];
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
//在线全部
|
//在线全部
|
||||||
case 'onlineAddons':
|
case 'onlineAddons':
|
||||||
if( $addons->code !== -1){
|
if($response->ok()) {
|
||||||
// 与本地文件对比
|
|
||||||
|
$res['code'] = 0;
|
||||||
|
$res['msg'] = '';
|
||||||
|
$res['count'] = count($addons->data);
|
||||||
|
$res['col'] = [
|
||||||
|
['type' => 'numbers'],
|
||||||
|
['field' => 'title','title'=> '插件', 'width'=> 200],
|
||||||
|
['field' => 'description','title'=> '简介', 'minWidth'=> 200],
|
||||||
|
['field' => 'author','title'=> '作者', 'width'=> 100],
|
||||||
|
['field' => 'price','title'=> '价格(元)','width'=> 85],
|
||||||
|
['field' => 'downloads','title'=> '下载', 'width'=> 70],
|
||||||
|
['field' => 'version','title'=> '版本', 'templet' => '<div>{{d.version}} {{# if(d.have_newversion == 1){ }}<span class="layui-badge-dot"></span>{{# } }}</div>','width'=> 75],
|
||||||
|
['field' => 'status','title'=> '在线', 'width'=> 70],
|
||||||
|
['title' => '操作', 'width'=> 150, 'align'=>'center', 'toolbar'=> '#addons-tool']
|
||||||
|
];
|
||||||
|
|
||||||
|
// $data数据 与本地文件对比
|
||||||
foreach($addons->data as $v){
|
foreach($addons->data as $v){
|
||||||
switch ($data['selector']) {
|
switch ($data['selector']) {
|
||||||
case 'free':
|
case 'free':
|
||||||
@ -112,21 +137,8 @@ class Addons extends AdminController
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
$res['code'] = 0;
|
|
||||||
$res['msg'] = '';
|
|
||||||
$res['col'] = [
|
|
||||||
['type' => 'numbers'],
|
|
||||||
['field' => 'title','title'=> '插件', 'width'=> 200],
|
|
||||||
['field' => 'description','title'=> '简介', 'minWidth'=> 200],
|
|
||||||
['field' => 'author','title'=> '作者', 'width'=> 100],
|
|
||||||
['field' => 'price','title'=> '价格(元)','width'=> 85],
|
|
||||||
['field' => 'downloads','title'=> '下载', 'width'=> 70],
|
|
||||||
['field' => 'version','title'=> '版本', 'templet' => '<div>{{d.version}} {{# if(d.have_newversion == 1){ }}<span class="layui-badge-dot"></span>{{# } }}</div>','width'=> 75],
|
|
||||||
['field' => 'status','title'=> '在线', 'width'=> 70],
|
|
||||||
['title' => '操作', 'width'=> 150, 'align'=>'center', 'toolbar'=> '#addons-tool']
|
|
||||||
];
|
|
||||||
} else {
|
} else {
|
||||||
$res = ['code'=>-1,'msg'=>'未获取到服务器信息'];
|
$res = ['code' => -1, 'msg' => '未获取到服务器信息'];
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -192,20 +204,20 @@ class Addons extends AdminController
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 安装插件
|
* 安装&升级,
|
||||||
|
* @param array $data
|
||||||
|
* @param bool $type true执行sql,false升级不执行sql
|
||||||
* @return Json
|
* @return Json
|
||||||
* @throws \Exception
|
|
||||||
*/
|
*/
|
||||||
public function install()
|
public function install(array $data = [], bool $type = true)
|
||||||
{
|
{
|
||||||
$data = Request::param();
|
$data = Request::only(['name','version','uid','token']) ?? $data;
|
||||||
$url = $this->getSystem()['api_url'].'/v1/getaddons';
|
// $data = ['name' => $name, 'version' => $version, 'uid' => $uid, 'token' => $token];
|
||||||
$data = ['name'=>$data['name'], 'version'=>$data['version'], 'uid'=>$data['uid'], 'token'=>$data['token']];
|
|
||||||
$addons = Api::urlPost($url,$data);
|
// 接口
|
||||||
if( $addons->code < 0) {
|
$response = HttpHelper::withHost()->post('/v1/getaddons',$data)->toJson();
|
||||||
return json(['code'=>$addons->code,'msg'=>$addons->msg]);
|
if($response->code < 0) return json($response);
|
||||||
}
|
|
||||||
//$this->pay($name,$extend);
|
|
||||||
//版本判断,是否能够安装?
|
//版本判断,是否能够安装?
|
||||||
$addInstalledVersion = get_addons_info($data['name']);
|
$addInstalledVersion = get_addons_info($data['name']);
|
||||||
if(!empty($addInstalledVersion)){
|
if(!empty($addInstalledVersion)){
|
||||||
@ -216,7 +228,7 @@ class Addons extends AdminController
|
|||||||
//$tpl_ver_res = version_compare($addInstalledVersion['template_version'], config('taoler.template_version'),'<');
|
//$tpl_ver_res = version_compare($addInstalledVersion['template_version'], config('taoler.template_version'),'<');
|
||||||
}
|
}
|
||||||
|
|
||||||
$file_url = $addons->addons_src;
|
$file_url = $response->addons_src;
|
||||||
//判断远程文件是否可用存在
|
//判断远程文件是否可用存在
|
||||||
$header = get_headers($file_url, true);
|
$header = get_headers($file_url, true);
|
||||||
if(!isset($header[0]) && (strpos($header[0], '200') || strpos($header[0], '304'))){
|
if(!isset($header[0]) && (strpos($header[0], '200') || strpos($header[0], '304'))){
|
||||||
@ -265,15 +277,19 @@ class Addons extends AdminController
|
|||||||
if($cpData['code'] == -1) return json(['code'=>-1,'msg'=>$cpData['msg']]);
|
if($cpData['code'] == -1) return json(['code'=>-1,'msg'=>$cpData['msg']]);
|
||||||
|
|
||||||
$class = get_addons_instance($data['name']);
|
$class = get_addons_instance($data['name']);
|
||||||
//添加数据库
|
try {
|
||||||
|
if($type) {
|
||||||
|
// 执行数据库
|
||||||
$sqlInstallFile = root_path().'addons/'.$data['name'].'/install.sql';
|
$sqlInstallFile = root_path().'addons/'.$data['name'].'/install.sql';
|
||||||
if(file_exists($sqlInstallFile)) {
|
if(file_exists($sqlInstallFile)) {
|
||||||
SqlFile::dbExecute($sqlInstallFile);
|
SqlFile::dbExecute($sqlInstallFile);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
//安装菜单
|
//安装菜单
|
||||||
$menu = get_addons_menu($data['name']);
|
$menu = get_addons_menu($data['name']);
|
||||||
if(!empty($menu)){
|
if(!empty($menu)){
|
||||||
if(isset($menu['is_nav']) && $menu['is_nav']==1){
|
if(isset($menu['is_nav']) && $menu['is_nav'] == 1){
|
||||||
$pid = 0;
|
$pid = 0;
|
||||||
}else{
|
}else{
|
||||||
$pid = AuthRule::where('name','addons')->value('id');
|
$pid = AuthRule::where('name','addons')->value('id');
|
||||||
@ -283,6 +299,10 @@ class Addons extends AdminController
|
|||||||
}
|
}
|
||||||
//执行插件安装
|
//执行插件安装
|
||||||
$class->install();
|
$class->install();
|
||||||
|
set_addons_info($data['name'],['status' => 1,'install' => 1]);
|
||||||
|
} catch (\Exception $e) {
|
||||||
|
return json(['code'=>-1,'msg'=> $e->getMessage()]);
|
||||||
|
}
|
||||||
|
|
||||||
Files::delDirAndFile('../runtime/addons/'.$data['name'] . DS);
|
Files::delDirAndFile('../runtime/addons/'.$data['name'] . DS);
|
||||||
|
|
||||||
@ -295,23 +315,23 @@ class Addons extends AdminController
|
|||||||
public function uninstall()
|
public function uninstall()
|
||||||
{
|
{
|
||||||
$name = input('name');
|
$name = input('name');
|
||||||
//执行插件卸载
|
// 执行插件卸载
|
||||||
$class = get_addons_instance($name);
|
$class = get_addons_instance($name);
|
||||||
$class->uninstall();
|
$class->uninstall();
|
||||||
//卸载菜单
|
// 卸载菜单
|
||||||
$menu = get_addons_menu($name);
|
$menu = get_addons_menu($name);
|
||||||
if(!empty($menu)){
|
if(!empty($menu)){
|
||||||
$menu_arr[] = $menu['menu'];
|
$menu_arr[] = $menu['menu'];
|
||||||
$this->delAddonMenu($menu_arr);
|
$this->delAddonMenu($menu_arr);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
//卸载插件数据库
|
//卸载插件数据库
|
||||||
$sqlUninstallFile = root_path().'addons/'.$name.'/uninstall.sql';
|
$sqlUninstallFile = root_path().'addons/'.$name.'/uninstall.sql';
|
||||||
if(file_exists($sqlUninstallFile)) {
|
if(file_exists($sqlUninstallFile)) {
|
||||||
SqlFile::dbExecute($sqlUninstallFile);
|
SqlFile::dbExecute($sqlUninstallFile);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// 插件addons下目录
|
// 插件addons下目录
|
||||||
$addonsDir = root_path() . 'addons' . DS . $name . DS;
|
$addonsDir = root_path() . 'addons' . DS . $name . DS;
|
||||||
// 插件管理后台目录
|
// 插件管理后台目录
|
||||||
@ -322,7 +342,6 @@ class Addons extends AdminController
|
|||||||
// 插件静态资源目录
|
// 插件静态资源目录
|
||||||
$addon_public = public_path() . 'addons' . DS . $name . DS;
|
$addon_public = public_path() . 'addons' . DS . $name . DS;
|
||||||
|
|
||||||
try {
|
|
||||||
if(file_exists($addonsDir)) Files::delDir($addonsDir);
|
if(file_exists($addonsDir)) Files::delDir($addonsDir);
|
||||||
if(file_exists($admin_controller)) Files::delDir($admin_controller);
|
if(file_exists($admin_controller)) Files::delDir($admin_controller);
|
||||||
if(file_exists($admin_model)) Files::delDir($admin_model);
|
if(file_exists($admin_model)) Files::delDir($admin_model);
|
||||||
@ -337,6 +356,43 @@ class Addons extends AdminController
|
|||||||
return json(['code' => 0, 'msg' => '插件卸载成功']);
|
return json(['code' => 0, 'msg' => '插件卸载成功']);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 升级插件
|
||||||
|
* @return Json
|
||||||
|
* @throws \Exception
|
||||||
|
*/
|
||||||
|
public function upgrade()
|
||||||
|
{
|
||||||
|
$data = Request::only(['name','version','uid','token']);
|
||||||
|
// 获取配置信息
|
||||||
|
$config = get_addons_config($data['name']);
|
||||||
|
// 卸载插件
|
||||||
|
$class = get_addons_instance($data['name']);
|
||||||
|
$class->uninstall();
|
||||||
|
// 卸载菜单
|
||||||
|
$menu = get_addons_menu($data['name']);
|
||||||
|
if(!empty($menu)){
|
||||||
|
$menu_arr[] = $menu['menu'];
|
||||||
|
$this->delAddonMenu($menu_arr);
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
// 升级安装,第二个参数为false
|
||||||
|
$this->install($data,false);
|
||||||
|
// 升级sql
|
||||||
|
$sqlUpdateFile = root_path().'addons/'.$data['name'].'/update.sql';
|
||||||
|
if(file_exists($sqlUpdateFile)) {
|
||||||
|
SqlFile::dbExecute($sqlUpdateFile);
|
||||||
|
}
|
||||||
|
// 恢复配置
|
||||||
|
set_addons_config($data['name'],$config);
|
||||||
|
} catch (\Exception $e) {
|
||||||
|
return json(['code' => -1, 'msg' => $e->getMessage()]);
|
||||||
|
}
|
||||||
|
|
||||||
|
return json(['code' => 0, 'msg' => '升级成功']);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 启用禁用插件
|
* 启用禁用插件
|
||||||
* @return Json
|
* @return Json
|
||||||
@ -478,14 +534,8 @@ class Addons extends AdminController
|
|||||||
*/
|
*/
|
||||||
public function userLogin()
|
public function userLogin()
|
||||||
{
|
{
|
||||||
$data = Request::param();
|
$response = HttpHelper::withHost()->post('/v1/user/login', Request::param())->toJson();
|
||||||
$url = $this->getSystem()['api_url'].'/v1/user/login';
|
return json($response);
|
||||||
$user = Api::urlPost($url,$data);
|
|
||||||
if($user->code == 0) {
|
|
||||||
return $user;
|
|
||||||
} else {
|
|
||||||
return json(['code'=>-1,'msg'=>$user->msg]);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -495,15 +545,17 @@ class Addons extends AdminController
|
|||||||
public function pay()
|
public function pay()
|
||||||
{
|
{
|
||||||
$data = Request::only(['id','name','version','uid','price']);
|
$data = Request::only(['id','name','version','uid','price']);
|
||||||
$url = $this->getSystem()['api_url'].'/v1/createOrder';
|
// $url = $this->getSystem()['api_url'].'/v1/createOrder';
|
||||||
$order = Api::urlPost($url,$data);
|
// $order = Api::urlPost($url,$data);
|
||||||
|
|
||||||
if ($order->code == 0) {
|
$response = HttpHelper::withHost()->post('/v1/createOrder', $data);
|
||||||
$orderData = json_decode(json_encode($order->data),TRUE);
|
|
||||||
View::assign('orderData',$orderData);
|
if ($response->ok()) {
|
||||||
|
// $orderData = json_decode(json_encode($response->toJson()->data),TRUE);
|
||||||
|
View::assign('orderData',$response->toArray()['data']);
|
||||||
return View::fetch();
|
return View::fetch();
|
||||||
} else {
|
} else {
|
||||||
return json(['code'=>-1,'msg'=>$order->msg]);
|
return json($response->toJson());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -514,18 +566,12 @@ class Addons extends AdminController
|
|||||||
public function isPay()
|
public function isPay()
|
||||||
{
|
{
|
||||||
$param = Request::only(['name','userinfo']);
|
$param = Request::only(['name','userinfo']);
|
||||||
//halt($data);
|
|
||||||
$data = [
|
$data = [
|
||||||
'name'=>$param['name'],
|
'name'=>$param['name'],
|
||||||
'uid'=> $param['userinfo']['uid'],
|
'uid'=> $param['userinfo']['uid'],
|
||||||
];
|
];
|
||||||
$url = $this->getSystem()['api_url'].'/v1/ispay';
|
$response = HttpHelper::withHost()->post('/v1/ispay', $data)->toJson();
|
||||||
$res = Api::urlPost($url,$data);
|
return json($response);
|
||||||
if($res->code == 0) {
|
|
||||||
return json(['code'=>0,'msg'=>'payed']);
|
|
||||||
} else {
|
|
||||||
return json(['code'=>-1,'msg'=>'no pay']);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -4,22 +4,24 @@
|
|||||||
<div class="layui-fluid">
|
<div class="layui-fluid">
|
||||||
<div class="layui-card">
|
<div class="layui-card">
|
||||||
<div class="layui-card-body">
|
<div class="layui-card-body">
|
||||||
|
|
||||||
<table id="addons-list" lay-filter="addons-list"></table>
|
<table id="addons-list" lay-filter="addons-list"></table>
|
||||||
|
|
||||||
<script type="text/html" id="toolbar">
|
<script type="text/html" id="toolbar">
|
||||||
<div class="layui-btn-group" style="padding-bottom: 10px;">
|
<div class="layui-btn-group" style="padding-bottom: 10px;">
|
||||||
<a href="#denable" type="button" class="layui-btn layui-btn-sm" lay-event="allAddons">全部</a>
|
<a type="button" class="layui-btn layui-btn-sm" lay-event="allAddons" data-url="{:url('addons/index',['type'=>'onlineAddons','selector'=>'all'])}">全部</a>
|
||||||
<a type="button" class="layui-btn layui-btn-sm" lay-event="freeAddons">免费</a>
|
<a type="button" class="layui-btn layui-btn-sm" lay-event="freeAddons" data-url="{:url('addons/index',['type'=>'onlineAddons','selector'=>'free'])}">免费</a>
|
||||||
<a type="button" class="layui-btn layui-btn-sm" lay-event="payAddons">付费</a>
|
<a type="button" class="layui-btn layui-btn-sm" lay-event="payAddons" data-url="{:url('addons/index',['type'=>'onlineAddons','selector'=>'pay'])}">付费</a>
|
||||||
<a href="#enable" type="button" class="layui-btn layui-btn-normal layui-btn-sm" lay-event="installed">已安装</a>
|
<a type="button" class="layui-btn layui-btn-normal layui-btn-sm" lay-event="installed" data-url="{:url('addons/index',['type'=>'installed','selector'=>''])}">已安装</a>
|
||||||
</div>
|
</div>
|
||||||
<div class="layui-btn-group" style="padding-bottom: 10px;">
|
<div class="layui-btn-group" style="padding-bottom: 10px;">
|
||||||
<button class="layui-btn layui-btn-danger layui-btn-sm layuiadmin-btn-admin" data-type="add">离线安装</button>
|
<button class="layui-btn layui-btn-danger layui-btn-sm layuiadmin-btn-admin" data-type="add">离线安装</button>
|
||||||
</div>
|
</div>
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<script type="text/html" id="addons-tool">
|
<script type="text/html" id="addons-tool">
|
||||||
{{# if(d.have_newversion === 1){ }}
|
{{# if(d.have_newversion === 1){ }}
|
||||||
<a class="layui-btn layui-btn-danger layui-btn-xs" lay-event="install" data-url="{:url('Addons/install')}"><i class="layui-icon layui-icon-edit"></i>升级</a>
|
<a class="layui-btn layui-btn-danger layui-btn-xs" lay-event="install" data-url="{:url('Addons/upgrade')}" data-userlogin="{:url('Addons/userLogin')}" data-ispay="{:url('Addons/isPay')}"><i class="layui-icon layui-icon-edit"></i>升级</a>
|
||||||
{{# } else { }}
|
{{# } else { }}
|
||||||
{{# if(d.isInstall ===1) { }}
|
{{# if(d.isInstall ===1) { }}
|
||||||
<a class="layui-btn layui-btn-normal layui-btn-xs" lay-event="config" data-url="{:url('Addons/config')}"><i class="layui-icon layui-icon-set"></i>设置</a>
|
<a class="layui-btn layui-btn-normal layui-btn-xs" lay-event="config" data-url="{:url('Addons/config')}"><i class="layui-icon layui-icon-set"></i>设置</a>
|
||||||
@ -48,8 +50,7 @@
|
|||||||
{block name="js"}
|
{block name="js"}
|
||||||
<script src="/static/notify.js"></script>
|
<script src="/static/notify.js"></script>
|
||||||
<script>
|
<script>
|
||||||
var addonsList = "{:url('Addons/addonsList')}";
|
var addonList = "{:url('Addons/index')}";
|
||||||
|
|
||||||
layui.config({
|
layui.config({
|
||||||
base: '/static/admin/' //静态资源所在路径
|
base: '/static/admin/' //静态资源所在路径
|
||||||
}).extend({
|
}).extend({
|
||||||
|
@ -25,19 +25,17 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="layui-row">
|
<div class="layui-row">
|
||||||
<div class="layui-col-xs6 layui-col-md6">
|
<div class="layui-col-md6">
|
||||||
<div class="pay-type">
|
<div class="pay-type">
|
||||||
<div style="padding: 5px;"><a ><img src="/static/res/images/alipay.jpg" style="height:80px;"></a></div>
|
<div style="padding: 5px; text-align: center;"><a><img src="/static/res/images/alipay.jpg" style="height:80px;"></a></div>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
<div class="soft-info">
|
<div class="soft-info">
|
||||||
<div>不支持退款</div>
|
<div>不支持退款</div>
|
||||||
<br />
|
<br />
|
||||||
<div>软件协议:本软件为原作者拥有版权权限,购买软件可以商用,禁止第三方出售行为。</div>
|
<div>软件协议:本软件为原作者拥有版权权限,购买软件可以商用,禁止第三方出售行为。</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
<div class="layui-col-xs6 layui-col-md6">
|
<div class="layui-col-md6">
|
||||||
<div class="qrcode" data-text="{$orderData.qr_code_img}">
|
<div class="qrcode" data-text="{$orderData.qr_code_img}">
|
||||||
<img src="{$orderData.qr_code_img}">
|
<img src="{$orderData.qr_code_img}">
|
||||||
</div>
|
</div>
|
||||||
|
107
app/common/lib/HttpHelper.php
Normal file
107
app/common/lib/HttpHelper.php
Normal file
@ -0,0 +1,107 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace app\common\lib;
|
||||||
|
|
||||||
|
use yzh52521\EasyHttp\Http;
|
||||||
|
use yzh52521\EasyHttp\Request;
|
||||||
|
use yzh52521\EasyHttp\Response;
|
||||||
|
use yzh52521\EasyHttp\RequestException;
|
||||||
|
|
||||||
|
class HttpHelper
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* @var Http;
|
||||||
|
*/
|
||||||
|
protected $http;
|
||||||
|
|
||||||
|
protected $response;
|
||||||
|
|
||||||
|
public function __construct(){
|
||||||
|
// $this->http = new Http();
|
||||||
|
if(!$this->http) {
|
||||||
|
$this->http = new Request();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 携带指定接口
|
||||||
|
* @param string $url
|
||||||
|
* @return $this
|
||||||
|
*/
|
||||||
|
public function withHost(string $url = 'http://api.aieok.com'): HttpHelper
|
||||||
|
{
|
||||||
|
$this->http = $this->http->withHost($url);
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 添加请求头
|
||||||
|
* @param array $data
|
||||||
|
* @return $this
|
||||||
|
*/
|
||||||
|
public function withHeaders(array $data = []): HttpHelper
|
||||||
|
{
|
||||||
|
$this->http = $this->http->withHeaders($data);
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* get请求
|
||||||
|
* @param string $url
|
||||||
|
* @param array $data
|
||||||
|
* @return $this
|
||||||
|
*/
|
||||||
|
public function get(string $url, array $data = []): HttpHelper
|
||||||
|
{
|
||||||
|
$this->response = $this->http->get($url, $data);
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* POST请求
|
||||||
|
* @param string $url
|
||||||
|
* @param array $data
|
||||||
|
* @return $this
|
||||||
|
*/
|
||||||
|
public function post(string $url, array $data = [])
|
||||||
|
{
|
||||||
|
$this->response = $this->http->post($url, $data);
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 返回JSON数据
|
||||||
|
* @return mixed
|
||||||
|
*/
|
||||||
|
public function toJson()
|
||||||
|
{
|
||||||
|
if($this->ok()) {
|
||||||
|
return $this->response->json();
|
||||||
|
} else {
|
||||||
|
// return json(['code' => -1, 'msg' => 'server failed']);
|
||||||
|
return json_decode('{"code": -1, "msg": "server failed"}');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 返回ARRAY数据
|
||||||
|
* @return array
|
||||||
|
*/
|
||||||
|
public function toArray()
|
||||||
|
{
|
||||||
|
if($this->ok()) {
|
||||||
|
return $this->response->array();
|
||||||
|
} else {
|
||||||
|
return ['code' => -1, 'msg' => 'server failed'];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return bool
|
||||||
|
*/
|
||||||
|
public function ok() : bool
|
||||||
|
{
|
||||||
|
return $this->response->status() === 200;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
29
app/common/lib/facade/HttpHelper.php
Normal file
29
app/common/lib/facade/HttpHelper.php
Normal file
@ -0,0 +1,29 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace app\common\lib\facade;
|
||||||
|
|
||||||
|
use think\Facade;
|
||||||
|
use think\response\Json;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @method static \app\common\lib\HttpHelper withHost(string $url = 'http://api.aieok.com') 携带指定接口
|
||||||
|
* @method static \app\common\lib\HttpHelper withHeaders(array $data = []) 携带请求头
|
||||||
|
* @method static \app\common\lib\HttpHelper get(string $url, array $data = []) GET请求
|
||||||
|
* @method static \app\common\lib\HttpHelper post(string $url, array $data = []) POST请求
|
||||||
|
* @method static array toArray() 返回ARRAY数据
|
||||||
|
* @method static bool ok() 服务器200
|
||||||
|
*/
|
||||||
|
class HttpHelper extends Facade
|
||||||
|
{
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取当前Facade对应类名(或者已经绑定的容器对象标识)
|
||||||
|
* @access protected
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
protected static function getFacadeClass()
|
||||||
|
{
|
||||||
|
return 'app\common\lib\HttpHelper';
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -12,11 +12,9 @@ declare (strict_types = 1);
|
|||||||
|
|
||||||
namespace app\listener;
|
namespace app\listener;
|
||||||
|
|
||||||
use think\facade\Db;
|
|
||||||
use think\facade\Log;
|
use think\facade\Log;
|
||||||
use app\common\model\User;
|
use app\common\model\User;
|
||||||
use think\facade\Lang;
|
use app\common\lib\facade\HttpHelper;
|
||||||
use taoler\com\Api;
|
|
||||||
|
|
||||||
class UserLogin
|
class UserLogin
|
||||||
{
|
{
|
||||||
@ -35,15 +33,16 @@ class UserLogin
|
|||||||
if($type == 'log'){
|
if($type == 'log'){
|
||||||
//$name = $user->user['name'];
|
//$name = $user->user['name'];
|
||||||
$ip = request()->ip();
|
$ip = request()->ip();
|
||||||
|
|
||||||
$url = 'http://ip-api.com/json/' . $ip . '?lang=zh-CN&fields=57361';
|
$url = 'http://ip-api.com/json/' . $ip . '?lang=zh-CN&fields=57361';
|
||||||
$ipJson = Api::urlGetRespond($url);
|
$city = 'earth';
|
||||||
$res = $ipJson->getData();
|
try{
|
||||||
|
$ipInfo = HttpHelper::get($url)->toJson();
|
||||||
$data = json_decode($res['data']);
|
if($ipInfo->status == 'success')
|
||||||
$city ='earth';
|
{
|
||||||
if($res['code'] == 0 && !$data->status){
|
$city = $ipInfo->city;
|
||||||
$city = $data->city;
|
}
|
||||||
|
} catch (\Exception $e) {
|
||||||
|
// echo $e->getMessage();
|
||||||
}
|
}
|
||||||
|
|
||||||
//国内查询,接口已失效
|
//国内查询,接口已失效
|
||||||
@ -75,7 +74,7 @@ class UserLogin
|
|||||||
}
|
}
|
||||||
|
|
||||||
if($type == 'logError'){
|
if($type == 'logError'){
|
||||||
$res = $u->allowField(['login_error_num','login_error_time'])->save(['login_error_num'=>$u->login_error_num+1,'login_error_time'=>time()]);
|
$res = $u->allowField(['login_error_num','login_error_time'])->save(['login_error_num'=>$u->login_error_num + 1,'login_error_time'=>time()]);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -38,7 +38,8 @@
|
|||||||
"php-di/php-di": "^6.4",
|
"php-di/php-di": "^6.4",
|
||||||
"workerman/phpsocket.io": "^1.1",
|
"workerman/phpsocket.io": "^1.1",
|
||||||
"jaeger/querylist": "^4.2",
|
"jaeger/querylist": "^4.2",
|
||||||
"symfony/var-exporter": "^5.4"
|
"symfony/var-exporter": "^5.4",
|
||||||
|
"yzh52521/easyhttp": "^1.0"
|
||||||
},
|
},
|
||||||
"require-dev": {
|
"require-dev": {
|
||||||
"symfony/var-dumper": "^4.2",
|
"symfony/var-dumper": "^4.2",
|
||||||
|
54
composer.lock
generated
54
composer.lock
generated
@ -4,7 +4,7 @@
|
|||||||
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
|
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
|
||||||
"This file is @generated automatically"
|
"This file is @generated automatically"
|
||||||
],
|
],
|
||||||
"content-hash": "775d0e3963da1506fb878faca1e62b31",
|
"content-hash": "20e9c0c21d94d1cbf1c29c69868ebe38",
|
||||||
"packages": [
|
"packages": [
|
||||||
{
|
{
|
||||||
"name": "bacon/bacon-qr-code",
|
"name": "bacon/bacon-qr-code",
|
||||||
@ -3271,6 +3271,58 @@
|
|||||||
"source": "https://github.com/yansongda/supports"
|
"source": "https://github.com/yansongda/supports"
|
||||||
},
|
},
|
||||||
"time": "2022-03-28T10:25:04+00:00"
|
"time": "2022-03-28T10:25:04+00:00"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "yzh52521/easyhttp",
|
||||||
|
"version": "v1.0.3",
|
||||||
|
"source": {
|
||||||
|
"type": "git",
|
||||||
|
"url": "https://github.com/yzh52521/easyhttp.git",
|
||||||
|
"reference": "aa7f805cfed6ce613f10045aff564b05e62e944c"
|
||||||
|
},
|
||||||
|
"dist": {
|
||||||
|
"type": "zip",
|
||||||
|
"url": "https://api.github.com/repos/yzh52521/easyhttp/zipball/aa7f805cfed6ce613f10045aff564b05e62e944c",
|
||||||
|
"reference": "aa7f805cfed6ce613f10045aff564b05e62e944c",
|
||||||
|
"shasum": ""
|
||||||
|
},
|
||||||
|
"require": {
|
||||||
|
"guzzlehttp/guzzle": "^6.0|^7.0",
|
||||||
|
"php": "^7.2.5|^8.0",
|
||||||
|
"psr/log": "^1.0|^2.0|^3.0"
|
||||||
|
},
|
||||||
|
"type": "library",
|
||||||
|
"autoload": {
|
||||||
|
"psr-4": {
|
||||||
|
"yzh52521\\EasyHttp\\": "src/"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"notification-url": "https://packagist.org/downloads/",
|
||||||
|
"license": [
|
||||||
|
"MIT"
|
||||||
|
],
|
||||||
|
"authors": [
|
||||||
|
{
|
||||||
|
"name": "yzh52521",
|
||||||
|
"email": "396751927@qq.com"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"description": "EasyHttp 是一个轻量级、语义化、对IDE友好的HTTP客户端,支持常见的HTTP请求、异步请求和并发请求,让你可以快速地使用 HTTP 请求与其他 Web 应用进行通信。",
|
||||||
|
"homepage": "https://github.com/yzh52521/easyhttp",
|
||||||
|
"keywords": [
|
||||||
|
"EasyHttp",
|
||||||
|
"curl",
|
||||||
|
"easy-http",
|
||||||
|
"http",
|
||||||
|
"php",
|
||||||
|
"php-http",
|
||||||
|
"phphttp"
|
||||||
|
],
|
||||||
|
"support": {
|
||||||
|
"issues": "https://github.com/yzh52521/easyhttp/issues",
|
||||||
|
"source": "https://github.com/yzh52521/easyhttp/tree/v1.0.3"
|
||||||
|
},
|
||||||
|
"time": "2022-10-13T06:56:42+00:00"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"packages-dev": [
|
"packages-dev": [
|
||||||
|
@ -16,7 +16,7 @@ return [
|
|||||||
// 应用名,此项不可更改
|
// 应用名,此项不可更改
|
||||||
'appname' => 'TaoLer',
|
'appname' => 'TaoLer',
|
||||||
// 版本配置
|
// 版本配置
|
||||||
'version' => '2.0.5',
|
'version' => '2.0.6',
|
||||||
// 加盐
|
// 加盐
|
||||||
'salt' => 'taoler',
|
'salt' => 'taoler',
|
||||||
// 数据库备份目录
|
// 数据库备份目录
|
||||||
|
@ -7,30 +7,70 @@ layui.define(["table", "form", "upload","notify","hxNav"], function (exports) {
|
|||||||
upload = layui.upload;
|
upload = layui.upload;
|
||||||
var notify = layui.notify;
|
var notify = layui.notify;
|
||||||
|
|
||||||
function getAddonsList(type,selector ) {
|
|
||||||
$.ajax({
|
|
||||||
type: "post",
|
|
||||||
url: addonsList,
|
|
||||||
data: { type: type, selector: selector },
|
|
||||||
dataType: "json",
|
|
||||||
success: function (res) {
|
|
||||||
//渲染表格
|
//渲染表格
|
||||||
table.render({
|
table.render({
|
||||||
elem: "#addons-list",
|
elem: "#addons-list",
|
||||||
toolbar: "#toolbar",
|
toolbar: "#toolbar",
|
||||||
defaultToolbar: [],
|
defaultToolbar: [],
|
||||||
url: addonsList + "?type=" + type + "&selector=" + selector,
|
url: addonList,
|
||||||
cols: [res["col"]],
|
cols: [[
|
||||||
|
{type: 'checkbox'},
|
||||||
|
{title: '序号', type: 'numbers'},
|
||||||
|
{field: 'title', title: '插件', width: 200},
|
||||||
|
{field: 'description', title: '简介', minWidth: 200},
|
||||||
|
{field: 'author', title: '作者', width: 100},
|
||||||
|
{field: 'price', title: '价格(元)', width: 85},
|
||||||
|
{field: 'downloads', title: '下载', width: 70},
|
||||||
|
{field: 'version', title: '版本', templet: '<div>{{d.version}} {{# if(d.have_newversion == 1){ }}<span class="layui-badge-dot"></span>{{# } }}</div>', width: 75},
|
||||||
|
{field: 'status', title: '在线', width: 70},
|
||||||
|
{title: '操作', width: 165, align: 'center', toolbar: '#addons-tool'}
|
||||||
|
]],
|
||||||
page: true,
|
page: true,
|
||||||
limit: 10,
|
limit: 15,
|
||||||
height: "full-220",
|
height: "full-220",
|
||||||
text: "对不起,加载出现异常!",
|
text: "对不起,加载出现异常!",
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// 重载数据
|
||||||
|
var addonReload = function (type,selector) {
|
||||||
|
$.ajax({
|
||||||
|
type: "post",
|
||||||
|
url: addonList,
|
||||||
|
data: { type: type, selector: selector },
|
||||||
|
dataType: "json",
|
||||||
|
success: function (res) {
|
||||||
|
//渲染表格
|
||||||
|
table.reload('addons-list',{
|
||||||
|
url: addonList,
|
||||||
|
where: {
|
||||||
|
type: type, selector: selector
|
||||||
|
},
|
||||||
|
cols: [res["col"]],
|
||||||
|
});
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
getAddonsList("onlineAddons","all");
|
//头工具栏事件
|
||||||
|
table.on("toolbar(addons-list)", function (obj) {
|
||||||
|
var checkStatus = table.checkStatus(obj.config.id);
|
||||||
|
var url = $(this).data(url);
|
||||||
|
|
||||||
|
switch (obj.event) {
|
||||||
|
case "installed":
|
||||||
|
addonReload("installed","all");
|
||||||
|
break;
|
||||||
|
case "allAddons":
|
||||||
|
addonReload("onlineAddons","all");
|
||||||
|
break;
|
||||||
|
case "freeAddons":
|
||||||
|
addonReload("onlineAddons","free");
|
||||||
|
break;
|
||||||
|
case "payAddons":
|
||||||
|
addonReload("onlineAddons","pay");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
var api = {
|
var api = {
|
||||||
userinfo: {
|
userinfo: {
|
||||||
@ -48,25 +88,6 @@ layui.define(["table", "form", "upload","notify","hxNav"], function (exports) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//头工具栏事件
|
|
||||||
table.on("toolbar(addons-list)", function (obj) {
|
|
||||||
var checkStatus = table.checkStatus(obj.config.id);
|
|
||||||
switch (obj.event) {
|
|
||||||
case "installed":
|
|
||||||
getAddonsList("installed",'');
|
|
||||||
break;
|
|
||||||
case "allAddons":
|
|
||||||
getAddonsList("onlineAddons","all");
|
|
||||||
break;
|
|
||||||
case "freeAddons":
|
|
||||||
getAddonsList("onlineAddons","free");
|
|
||||||
break;
|
|
||||||
case "payAddons":
|
|
||||||
getAddonsList("onlineAddons","pay");
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
//监听工具条
|
//监听工具条
|
||||||
table.on("tool(addons-list)", function (obj) {
|
table.on("tool(addons-list)", function (obj) {
|
||||||
var data = obj.data;
|
var data = obj.data;
|
||||||
@ -85,12 +106,12 @@ layui.define(["table", "form", "upload","notify","hxNav"], function (exports) {
|
|||||||
layer.close(index);
|
layer.close(index);
|
||||||
layer.open({
|
layer.open({
|
||||||
type: 2,
|
type: 2,
|
||||||
area: ['700px', '650px'],
|
area: ['80%', '90%'],
|
||||||
fixed: false, //不固定
|
fixed: false, //不固定
|
||||||
maxmin: true,
|
maxmin: true,
|
||||||
content: 'pay.html'+ "?id=" + data.id+ "&name=" + data.name + "&version=" + data.version + "&uid=" + userinfo.uid + "&price=" + data.price,
|
content: 'pay.html'+ "?id=" + data.id+ "&name=" + data.name + "&version=" + data.version + "&uid=" + userinfo.uid + "&price=" + data.price,
|
||||||
success: function (layero, index){
|
success: function (layero, index){
|
||||||
// 订单沦陷
|
// 订单轮询
|
||||||
var intervalPay = setInterval(function() {
|
var intervalPay = setInterval(function() {
|
||||||
$.post(userIsPayUrl,{name:data.name, userinfo:userinfo},function (res){
|
$.post(userIsPayUrl,{name:data.name, userinfo:userinfo},function (res){
|
||||||
if(res.code === 0) {
|
if(res.code === 0) {
|
||||||
@ -113,6 +134,8 @@ layui.define(["table", "form", "upload","notify","hxNav"], function (exports) {
|
|||||||
layer.close(index);
|
layer.close(index);
|
||||||
notify.error(res.msg, "topRight");
|
notify.error(res.msg, "topRight");
|
||||||
}
|
}
|
||||||
|
// 重载
|
||||||
|
table.reloadData("addons-list",{},'deep');
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
@ -149,7 +172,6 @@ layui.define(["table", "form", "upload","notify","hxNav"], function (exports) {
|
|||||||
notify.success("登录成功", function (){
|
notify.success("登录成功", function (){
|
||||||
location.reload();
|
location.reload();
|
||||||
});
|
});
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
notify.alert(res.msg);
|
notify.alert(res.msg);
|
||||||
}
|
}
|
||||||
@ -163,18 +185,14 @@ layui.define(["table", "form", "upload","notify","hxNav"], function (exports) {
|
|||||||
},
|
},
|
||||||
success: function (layero, index) {
|
success: function (layero, index) {
|
||||||
$(".layui-layer-btn1", layero).prop("href", "https://www.aieok.com/article/reg.html").prop("target", "_blank");
|
$(".layui-layer-btn1", layero).prop("href", "https://www.aieok.com/article/reg.html").prop("target", "_blank");
|
||||||
},
|
}
|
||||||
end: function () {
|
|
||||||
$("#login").hide();
|
|
||||||
},
|
|
||||||
|
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//安装插件
|
//安装插件
|
||||||
if (event === "install") {
|
if (event === "install" || event === "upgrade") {
|
||||||
var userLoginUrl = $(this).data('userlogin');
|
var userLoginUrl = $(this).data('userlogin');
|
||||||
var userIsPayUrl = $(this).data('ispay');
|
var userIsPayUrl = $(this).data('ispay');
|
||||||
install(data,url,userLoginUrl,userIsPayUrl);
|
install(data,url,userLoginUrl,userIsPayUrl);
|
||||||
|
4
vendor/composer/autoload_files.php
vendored
4
vendor/composer/autoload_files.php
vendored
@ -8,13 +8,13 @@ $baseDir = dirname($vendorDir);
|
|||||||
return array(
|
return array(
|
||||||
'9b552a3cc426e3287cc811caefa3cf53' => $vendorDir . '/topthink/think-helper/src/helper.php',
|
'9b552a3cc426e3287cc811caefa3cf53' => $vendorDir . '/topthink/think-helper/src/helper.php',
|
||||||
'35fab96057f1bf5e7aba31a8a6d5fdde' => $vendorDir . '/topthink/think-orm/stubs/load_stubs.php',
|
'35fab96057f1bf5e7aba31a8a6d5fdde' => $vendorDir . '/topthink/think-orm/stubs/load_stubs.php',
|
||||||
'a4a119a56e50fbb293281d9a48007e0e' => $vendorDir . '/symfony/polyfill-php80/bootstrap.php',
|
|
||||||
'7b11c4dc42b3b3023073cb14e519683c' => $vendorDir . '/ralouphie/getallheaders/src/getallheaders.php',
|
'7b11c4dc42b3b3023073cb14e519683c' => $vendorDir . '/ralouphie/getallheaders/src/getallheaders.php',
|
||||||
|
'a4a119a56e50fbb293281d9a48007e0e' => $vendorDir . '/symfony/polyfill-php80/bootstrap.php',
|
||||||
'c964ee0ededf28c96ebd9db5099ef910' => $vendorDir . '/guzzlehttp/promises/src/functions_include.php',
|
'c964ee0ededf28c96ebd9db5099ef910' => $vendorDir . '/guzzlehttp/promises/src/functions_include.php',
|
||||||
'a0edc8309cc5e1d60e3047b5df6b7052' => $vendorDir . '/guzzlehttp/psr7/src/functions_include.php',
|
'a0edc8309cc5e1d60e3047b5df6b7052' => $vendorDir . '/guzzlehttp/psr7/src/functions_include.php',
|
||||||
|
'37a3dc5111fe8f707ab4c132ef1dbc62' => $vendorDir . '/guzzlehttp/guzzle/src/functions_include.php',
|
||||||
'0e6d7bf4a5811bfa5cf40c5ccd6fae6a' => $vendorDir . '/symfony/polyfill-mbstring/bootstrap.php',
|
'0e6d7bf4a5811bfa5cf40c5ccd6fae6a' => $vendorDir . '/symfony/polyfill-mbstring/bootstrap.php',
|
||||||
'25072dd6e2470089de65ae7bf11d3109' => $vendorDir . '/symfony/polyfill-php72/bootstrap.php',
|
'25072dd6e2470089de65ae7bf11d3109' => $vendorDir . '/symfony/polyfill-php72/bootstrap.php',
|
||||||
'37a3dc5111fe8f707ab4c132ef1dbc62' => $vendorDir . '/guzzlehttp/guzzle/src/functions_include.php',
|
|
||||||
'667aeda72477189d0494fecd327c3641' => $vendorDir . '/symfony/var-dumper/Resources/functions/dump.php',
|
'667aeda72477189d0494fecd327c3641' => $vendorDir . '/symfony/var-dumper/Resources/functions/dump.php',
|
||||||
'fe62ba7e10580d903cc46d808b5961a4' => $vendorDir . '/tightenco/collect/src/Collect/Support/helpers.php',
|
'fe62ba7e10580d903cc46d808b5961a4' => $vendorDir . '/tightenco/collect/src/Collect/Support/helpers.php',
|
||||||
'caf31cc6ec7cf2241cb6f12c226c3846' => $vendorDir . '/tightenco/collect/src/Collect/Support/alias.php',
|
'caf31cc6ec7cf2241cb6f12c226c3846' => $vendorDir . '/tightenco/collect/src/Collect/Support/alias.php',
|
||||||
|
3
vendor/composer/autoload_psr4.php
vendored
3
vendor/composer/autoload_psr4.php
vendored
@ -6,6 +6,7 @@ $vendorDir = dirname(__DIR__);
|
|||||||
$baseDir = dirname($vendorDir);
|
$baseDir = dirname($vendorDir);
|
||||||
|
|
||||||
return array(
|
return array(
|
||||||
|
'yzh52521\\EasyHttp\\' => array($vendorDir . '/yzh52521/easyhttp/src'),
|
||||||
'wamkj\\thinkphp\\' => array($vendorDir . '/wamkj/thinkphp6.0-databackup/src'),
|
'wamkj\\thinkphp\\' => array($vendorDir . '/wamkj/thinkphp6.0-databackup/src'),
|
||||||
'think\\view\\driver\\' => array($vendorDir . '/topthink/think-view/src'),
|
'think\\view\\driver\\' => array($vendorDir . '/topthink/think-view/src'),
|
||||||
'think\\trace\\' => array($vendorDir . '/topthink/think-trace/src'),
|
'think\\trace\\' => array($vendorDir . '/topthink/think-trace/src'),
|
||||||
@ -15,7 +16,7 @@ return array(
|
|||||||
'think\\app\\' => array($vendorDir . '/topthink/think-multi-app/src'),
|
'think\\app\\' => array($vendorDir . '/topthink/think-multi-app/src'),
|
||||||
'think\\' => array($vendorDir . '/topthink/framework/src/think', $vendorDir . '/topthink/think-helper/src', $vendorDir . '/topthink/think-orm/src', $vendorDir . '/topthink/think-template/src'),
|
'think\\' => array($vendorDir . '/topthink/framework/src/think', $vendorDir . '/topthink/think-helper/src', $vendorDir . '/topthink/think-orm/src', $vendorDir . '/topthink/think-template/src'),
|
||||||
'taoser\\think\\' => array($vendorDir . '/taoser/think-auth/src'),
|
'taoser\\think\\' => array($vendorDir . '/taoser/think-auth/src'),
|
||||||
'taoser\\' => array($vendorDir . '/taoser/think-setarr/src', $vendorDir . '/taoser/think-addons/src'),
|
'taoser\\' => array($vendorDir . '/taoser/think-addons/src', $vendorDir . '/taoser/think-setarr/src'),
|
||||||
'phpspirit\\databackup\\' => array($vendorDir . '/lotofbadcode/phpspirit_databackup/src'),
|
'phpspirit\\databackup\\' => array($vendorDir . '/lotofbadcode/phpspirit_databackup/src'),
|
||||||
'liliuwei\\social\\' => array($vendorDir . '/liliuwei/thinkphp-social/src'),
|
'liliuwei\\social\\' => array($vendorDir . '/liliuwei/thinkphp-social/src'),
|
||||||
'app\\' => array($baseDir . '/app'),
|
'app\\' => array($baseDir . '/app'),
|
||||||
|
16
vendor/composer/autoload_static.php
vendored
16
vendor/composer/autoload_static.php
vendored
@ -9,13 +9,13 @@ class ComposerStaticInit1b32198725235c8d6500c87262ef30c2
|
|||||||
public static $files = array (
|
public static $files = array (
|
||||||
'9b552a3cc426e3287cc811caefa3cf53' => __DIR__ . '/..' . '/topthink/think-helper/src/helper.php',
|
'9b552a3cc426e3287cc811caefa3cf53' => __DIR__ . '/..' . '/topthink/think-helper/src/helper.php',
|
||||||
'35fab96057f1bf5e7aba31a8a6d5fdde' => __DIR__ . '/..' . '/topthink/think-orm/stubs/load_stubs.php',
|
'35fab96057f1bf5e7aba31a8a6d5fdde' => __DIR__ . '/..' . '/topthink/think-orm/stubs/load_stubs.php',
|
||||||
'a4a119a56e50fbb293281d9a48007e0e' => __DIR__ . '/..' . '/symfony/polyfill-php80/bootstrap.php',
|
|
||||||
'7b11c4dc42b3b3023073cb14e519683c' => __DIR__ . '/..' . '/ralouphie/getallheaders/src/getallheaders.php',
|
'7b11c4dc42b3b3023073cb14e519683c' => __DIR__ . '/..' . '/ralouphie/getallheaders/src/getallheaders.php',
|
||||||
|
'a4a119a56e50fbb293281d9a48007e0e' => __DIR__ . '/..' . '/symfony/polyfill-php80/bootstrap.php',
|
||||||
'c964ee0ededf28c96ebd9db5099ef910' => __DIR__ . '/..' . '/guzzlehttp/promises/src/functions_include.php',
|
'c964ee0ededf28c96ebd9db5099ef910' => __DIR__ . '/..' . '/guzzlehttp/promises/src/functions_include.php',
|
||||||
'a0edc8309cc5e1d60e3047b5df6b7052' => __DIR__ . '/..' . '/guzzlehttp/psr7/src/functions_include.php',
|
'a0edc8309cc5e1d60e3047b5df6b7052' => __DIR__ . '/..' . '/guzzlehttp/psr7/src/functions_include.php',
|
||||||
|
'37a3dc5111fe8f707ab4c132ef1dbc62' => __DIR__ . '/..' . '/guzzlehttp/guzzle/src/functions_include.php',
|
||||||
'0e6d7bf4a5811bfa5cf40c5ccd6fae6a' => __DIR__ . '/..' . '/symfony/polyfill-mbstring/bootstrap.php',
|
'0e6d7bf4a5811bfa5cf40c5ccd6fae6a' => __DIR__ . '/..' . '/symfony/polyfill-mbstring/bootstrap.php',
|
||||||
'25072dd6e2470089de65ae7bf11d3109' => __DIR__ . '/..' . '/symfony/polyfill-php72/bootstrap.php',
|
'25072dd6e2470089de65ae7bf11d3109' => __DIR__ . '/..' . '/symfony/polyfill-php72/bootstrap.php',
|
||||||
'37a3dc5111fe8f707ab4c132ef1dbc62' => __DIR__ . '/..' . '/guzzlehttp/guzzle/src/functions_include.php',
|
|
||||||
'667aeda72477189d0494fecd327c3641' => __DIR__ . '/..' . '/symfony/var-dumper/Resources/functions/dump.php',
|
'667aeda72477189d0494fecd327c3641' => __DIR__ . '/..' . '/symfony/var-dumper/Resources/functions/dump.php',
|
||||||
'fe62ba7e10580d903cc46d808b5961a4' => __DIR__ . '/..' . '/tightenco/collect/src/Collect/Support/helpers.php',
|
'fe62ba7e10580d903cc46d808b5961a4' => __DIR__ . '/..' . '/tightenco/collect/src/Collect/Support/helpers.php',
|
||||||
'caf31cc6ec7cf2241cb6f12c226c3846' => __DIR__ . '/..' . '/tightenco/collect/src/Collect/Support/alias.php',
|
'caf31cc6ec7cf2241cb6f12c226c3846' => __DIR__ . '/..' . '/tightenco/collect/src/Collect/Support/alias.php',
|
||||||
@ -28,6 +28,10 @@ class ComposerStaticInit1b32198725235c8d6500c87262ef30c2
|
|||||||
);
|
);
|
||||||
|
|
||||||
public static $prefixLengthsPsr4 = array (
|
public static $prefixLengthsPsr4 = array (
|
||||||
|
'y' =>
|
||||||
|
array (
|
||||||
|
'yzh52521\\EasyHttp\\' => 18,
|
||||||
|
),
|
||||||
'w' =>
|
'w' =>
|
||||||
array (
|
array (
|
||||||
'wamkj\\thinkphp\\' => 15,
|
'wamkj\\thinkphp\\' => 15,
|
||||||
@ -143,6 +147,10 @@ class ComposerStaticInit1b32198725235c8d6500c87262ef30c2
|
|||||||
);
|
);
|
||||||
|
|
||||||
public static $prefixDirsPsr4 = array (
|
public static $prefixDirsPsr4 = array (
|
||||||
|
'yzh52521\\EasyHttp\\' =>
|
||||||
|
array (
|
||||||
|
0 => __DIR__ . '/..' . '/yzh52521/easyhttp/src',
|
||||||
|
),
|
||||||
'wamkj\\thinkphp\\' =>
|
'wamkj\\thinkphp\\' =>
|
||||||
array (
|
array (
|
||||||
0 => __DIR__ . '/..' . '/wamkj/thinkphp6.0-databackup/src',
|
0 => __DIR__ . '/..' . '/wamkj/thinkphp6.0-databackup/src',
|
||||||
@ -184,8 +192,8 @@ class ComposerStaticInit1b32198725235c8d6500c87262ef30c2
|
|||||||
),
|
),
|
||||||
'taoser\\' =>
|
'taoser\\' =>
|
||||||
array (
|
array (
|
||||||
0 => __DIR__ . '/..' . '/taoser/think-setarr/src',
|
0 => __DIR__ . '/..' . '/taoser/think-addons/src',
|
||||||
1 => __DIR__ . '/..' . '/taoser/think-addons/src',
|
1 => __DIR__ . '/..' . '/taoser/think-setarr/src',
|
||||||
),
|
),
|
||||||
'phpspirit\\databackup\\' =>
|
'phpspirit\\databackup\\' =>
|
||||||
array (
|
array (
|
||||||
|
55
vendor/composer/installed.json
vendored
55
vendor/composer/installed.json
vendored
@ -3560,6 +3560,61 @@
|
|||||||
"source": "https://github.com/yansongda/supports"
|
"source": "https://github.com/yansongda/supports"
|
||||||
},
|
},
|
||||||
"install-path": "../yansongda/supports"
|
"install-path": "../yansongda/supports"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "yzh52521/easyhttp",
|
||||||
|
"version": "v1.0.3",
|
||||||
|
"version_normalized": "1.0.3.0",
|
||||||
|
"source": {
|
||||||
|
"type": "git",
|
||||||
|
"url": "https://github.com/yzh52521/easyhttp.git",
|
||||||
|
"reference": "aa7f805cfed6ce613f10045aff564b05e62e944c"
|
||||||
|
},
|
||||||
|
"dist": {
|
||||||
|
"type": "zip",
|
||||||
|
"url": "https://api.github.com/repos/yzh52521/easyhttp/zipball/aa7f805cfed6ce613f10045aff564b05e62e944c",
|
||||||
|
"reference": "aa7f805cfed6ce613f10045aff564b05e62e944c",
|
||||||
|
"shasum": ""
|
||||||
|
},
|
||||||
|
"require": {
|
||||||
|
"guzzlehttp/guzzle": "^6.0|^7.0",
|
||||||
|
"php": "^7.2.5|^8.0",
|
||||||
|
"psr/log": "^1.0|^2.0|^3.0"
|
||||||
|
},
|
||||||
|
"time": "2022-10-13T06:56:42+00:00",
|
||||||
|
"type": "library",
|
||||||
|
"installation-source": "dist",
|
||||||
|
"autoload": {
|
||||||
|
"psr-4": {
|
||||||
|
"yzh52521\\EasyHttp\\": "src/"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"notification-url": "https://packagist.org/downloads/",
|
||||||
|
"license": [
|
||||||
|
"MIT"
|
||||||
|
],
|
||||||
|
"authors": [
|
||||||
|
{
|
||||||
|
"name": "yzh52521",
|
||||||
|
"email": "396751927@qq.com"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"description": "EasyHttp 是一个轻量级、语义化、对IDE友好的HTTP客户端,支持常见的HTTP请求、异步请求和并发请求,让你可以快速地使用 HTTP 请求与其他 Web 应用进行通信。",
|
||||||
|
"homepage": "https://github.com/yzh52521/easyhttp",
|
||||||
|
"keywords": [
|
||||||
|
"EasyHttp",
|
||||||
|
"curl",
|
||||||
|
"easy-http",
|
||||||
|
"http",
|
||||||
|
"php",
|
||||||
|
"php-http",
|
||||||
|
"phphttp"
|
||||||
|
],
|
||||||
|
"support": {
|
||||||
|
"issues": "https://github.com/yzh52521/easyhttp/issues",
|
||||||
|
"source": "https://github.com/yzh52521/easyhttp/tree/v1.0.3"
|
||||||
|
},
|
||||||
|
"install-path": "../yzh52521/easyhttp"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"dev": true,
|
"dev": true,
|
||||||
|
13
vendor/composer/installed.php
vendored
13
vendor/composer/installed.php
vendored
@ -3,7 +3,7 @@
|
|||||||
'name' => 'taoser/taoler',
|
'name' => 'taoser/taoler',
|
||||||
'pretty_version' => 'dev-master',
|
'pretty_version' => 'dev-master',
|
||||||
'version' => 'dev-master',
|
'version' => 'dev-master',
|
||||||
'reference' => 'ad4f215470c0da087a55d6ee63199988a4d216bd',
|
'reference' => 'db01522b1bc5e463fdc10fc88dcc01a3eee4f23a',
|
||||||
'type' => 'project',
|
'type' => 'project',
|
||||||
'install_path' => __DIR__ . '/../../',
|
'install_path' => __DIR__ . '/../../',
|
||||||
'aliases' => array(),
|
'aliases' => array(),
|
||||||
@ -367,7 +367,7 @@
|
|||||||
'taoser/taoler' => array(
|
'taoser/taoler' => array(
|
||||||
'pretty_version' => 'dev-master',
|
'pretty_version' => 'dev-master',
|
||||||
'version' => 'dev-master',
|
'version' => 'dev-master',
|
||||||
'reference' => 'ad4f215470c0da087a55d6ee63199988a4d216bd',
|
'reference' => 'db01522b1bc5e463fdc10fc88dcc01a3eee4f23a',
|
||||||
'type' => 'project',
|
'type' => 'project',
|
||||||
'install_path' => __DIR__ . '/../../',
|
'install_path' => __DIR__ . '/../../',
|
||||||
'aliases' => array(),
|
'aliases' => array(),
|
||||||
@ -553,5 +553,14 @@
|
|||||||
'aliases' => array(),
|
'aliases' => array(),
|
||||||
'dev_requirement' => false,
|
'dev_requirement' => false,
|
||||||
),
|
),
|
||||||
|
'yzh52521/easyhttp' => array(
|
||||||
|
'pretty_version' => 'v1.0.3',
|
||||||
|
'version' => '1.0.3.0',
|
||||||
|
'reference' => 'aa7f805cfed6ce613f10045aff564b05e62e944c',
|
||||||
|
'type' => 'library',
|
||||||
|
'install_path' => __DIR__ . '/../yzh52521/easyhttp',
|
||||||
|
'aliases' => array(),
|
||||||
|
'dev_requirement' => false,
|
||||||
|
),
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
|
2
vendor/guzzlehttp/guzzle/src/Client.php
vendored
2
vendor/guzzlehttp/guzzle/src/Client.php
vendored
@ -409,7 +409,7 @@ class Client implements ClientInterface, \Psr\Http\Client\ClientInterface
|
|||||||
if (isset($options['query'])) {
|
if (isset($options['query'])) {
|
||||||
$value = $options['query'];
|
$value = $options['query'];
|
||||||
if (\is_array($value)) {
|
if (\is_array($value)) {
|
||||||
$value = \http_build_query($value, null, '&', \PHP_QUERY_RFC3986);
|
$value = \http_build_query($value, '', '&', \PHP_QUERY_RFC3986);
|
||||||
}
|
}
|
||||||
if (!\is_string($value)) {
|
if (!\is_string($value)) {
|
||||||
throw new InvalidArgumentException('query must be a string or array');
|
throw new InvalidArgumentException('query must be a string or array');
|
||||||
|
2
vendor/services.php
vendored
2
vendor/services.php
vendored
@ -1,5 +1,5 @@
|
|||||||
<?php
|
<?php
|
||||||
// This file is automatically generated at:2022-10-15 14:22:33
|
// This file is automatically generated at:2022-10-17 08:21:26
|
||||||
declare (strict_types = 1);
|
declare (strict_types = 1);
|
||||||
return array (
|
return array (
|
||||||
0 => 'taoser\\addons\\Service',
|
0 => 'taoser\\addons\\Service',
|
||||||
|
22
vendor/yzh52521/easyhttp/LICENSE
vendored
Normal file
22
vendor/yzh52521/easyhttp/LICENSE
vendored
Normal file
@ -0,0 +1,22 @@
|
|||||||
|
The MIT License (MIT)
|
||||||
|
|
||||||
|
Copyright (c) 2014-present rap2hpoutre
|
||||||
|
|
||||||
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
of this software and associated documentation files (the "Software"), to deal
|
||||||
|
in the Software without restriction, including without limitation the rights
|
||||||
|
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
copies of the Software, and to permit persons to whom the Software is
|
||||||
|
furnished to do so, subject to the following conditions:
|
||||||
|
|
||||||
|
The above copyright notice and this permission notice shall be included in all
|
||||||
|
copies or substantial portions of the Software.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||||
|
SOFTWARE.
|
||||||
|
|
341
vendor/yzh52521/easyhttp/README.md
vendored
Normal file
341
vendor/yzh52521/easyhttp/README.md
vendored
Normal file
@ -0,0 +1,341 @@
|
|||||||
|
EasyHttp 是一个轻量级、语义化、对IDE友好的HTTP客户端,支持常见的HTTP请求、异步请求和并发请求,让你可以快速地使用 HTTP 请求与其他 Web 应用进行通信。
|
||||||
|
|
||||||
|
> EasyHttp并不强制依赖于cURL,如果没有安装cURL,EasyHttp会自动选择使用PHP流处理,或者你也可以提供自己的发送HTTP请求的处理方式。
|
||||||
|
|
||||||
|
如果您觉得EasyHttp对您有用的话,别忘了给点个赞哦^_^ !
|
||||||
|
|
||||||
|
github:[github.com/yzh52521/easyhttp](https://github.com/yzh52521/easyhttp "github.com/yzh52521/easyhttp")
|
||||||
|
|
||||||
|
gitee:[gitee.com/yzh52521/easyhttp](https://gitee.com/yzh52521/easyhttp "gitee.com/yzh52521/easyhttp")
|
||||||
|
|
||||||
|
本包是基于 [ gouguoyin/easyhttp ](https://gitee.com/gouguoyin/easyhttp "gitee.com/gouguoyin/easyhttp") 进行扩展开发,主要实现了以下扩展:
|
||||||
|
|
||||||
|
1. 增加 retry() 重试机制。
|
||||||
|
2. 增加 debug 日志调试功能。
|
||||||
|
3. 增加 withHost 指定服务端base_url
|
||||||
|
|
||||||
|
|
||||||
|
# 安装说明
|
||||||
|
|
||||||
|
#### 环境依赖
|
||||||
|
|
||||||
|
- PHP >= 7.2.5
|
||||||
|
- 如果使用PHP流处理,allow_url_fopen 必须在php.ini中启用。
|
||||||
|
- 如果使用cURL处理,cURL >= 7.19.4,并且编译了OpenSSL 与 zlib。
|
||||||
|
|
||||||
|
#### 一键安装
|
||||||
|
|
||||||
|
composer require yzh52521/easyhttp
|
||||||
|
|
||||||
|
## 发起请求
|
||||||
|
|
||||||
|
#### 同步请求
|
||||||
|
|
||||||
|
###### 常规请求
|
||||||
|
|
||||||
|
```php
|
||||||
|
$response = Http::get('http://httpbin.org/get');
|
||||||
|
|
||||||
|
$response = Http::get('http://httpbin.org/get?name=yzh52521');
|
||||||
|
|
||||||
|
$response = Http::get('http://httpbin.org/get?name=yzh52521', ['age' => 18]);
|
||||||
|
|
||||||
|
$response = Http::post('http://httpbin.org/post');
|
||||||
|
|
||||||
|
$response = Http::post('http://httpbin.org/post', ['name' => 'yzh52521']);
|
||||||
|
|
||||||
|
$response = Http::patch(...);
|
||||||
|
|
||||||
|
$response = Http::put(...);
|
||||||
|
|
||||||
|
$response = Http::delete(...);
|
||||||
|
|
||||||
|
$response = Http::head(...);
|
||||||
|
|
||||||
|
$response = Http::options(...);
|
||||||
|
```
|
||||||
|
|
||||||
|
###### 指定服务端base_url的请求
|
||||||
|
|
||||||
|
```php
|
||||||
|
// 指定服务端base_url地址,最终请求地址为 https://serv.yzh52521.com/login
|
||||||
|
$response = Http::withHost('https://serv.yzh52521.com')->post('/login');
|
||||||
|
|
||||||
|
```
|
||||||
|
###### 发送 Content-Type 编码请求
|
||||||
|
|
||||||
|
```php
|
||||||
|
// application/x-www-form-urlencoded(默认)
|
||||||
|
$response = Http::asForm()->post(...);
|
||||||
|
|
||||||
|
// application/json
|
||||||
|
$response = Http::asJson()->post(...);
|
||||||
|
```
|
||||||
|
|
||||||
|
###### 发送 Multipart 表单请求
|
||||||
|
|
||||||
|
```php
|
||||||
|
$response = Http::asMultipart(
|
||||||
|
'file_input_name', file_get_contents('photo1.jpg'), 'photo2.jpg'
|
||||||
|
)->post('http://test.com/attachments');
|
||||||
|
|
||||||
|
$response = Http::asMultipart(
|
||||||
|
'file_input_name', fopen('photo1.jpg', 'r'), 'photo2.jpg'
|
||||||
|
)->post(...);
|
||||||
|
|
||||||
|
$response = Http::attach(
|
||||||
|
'file_input_name', file_get_contents('photo1.jpg'), 'photo2.jpg'
|
||||||
|
)->post(...);
|
||||||
|
|
||||||
|
$response = Http::attach(
|
||||||
|
'file_input_name', fopen('photo1.jpg', 'r'), 'photo2.jpg'
|
||||||
|
)->post(...);
|
||||||
|
```
|
||||||
|
> 表单enctype属性需要设置成 multipart/form-data
|
||||||
|
|
||||||
|
###### 携带请求头的请求
|
||||||
|
|
||||||
|
```php
|
||||||
|
$response = Http::withHeaders([
|
||||||
|
'x-powered-by' => 'yzh52521'
|
||||||
|
])->post(...);
|
||||||
|
```
|
||||||
|
|
||||||
|
###### 携带重定向的请求
|
||||||
|
|
||||||
|
```php
|
||||||
|
// 默认
|
||||||
|
$response = Http::withRedirect(false)->post(...);
|
||||||
|
|
||||||
|
$response = Http::withRedirect([
|
||||||
|
'max' => 5,
|
||||||
|
'strict' => false,
|
||||||
|
'referer' => true,
|
||||||
|
'protocols' => ['http', 'https'],
|
||||||
|
'track_redirects' => false
|
||||||
|
])->post(...);
|
||||||
|
```
|
||||||
|
|
||||||
|
###### 携带认证的请求
|
||||||
|
|
||||||
|
```php
|
||||||
|
// Basic认证
|
||||||
|
$response = Http::withBasicAuth('username', 'password')->post(...);
|
||||||
|
|
||||||
|
// Digest认证(需要被HTTP服务器支持)
|
||||||
|
$response = Http::withDigestAuth('username', 'password')->post(...);
|
||||||
|
```
|
||||||
|
|
||||||
|
###### 携带 User-Agent 的请求
|
||||||
|
```php
|
||||||
|
$response = Http::withUA('Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/60.0.3100.0 Safari/537.36')->post(...);
|
||||||
|
```
|
||||||
|
|
||||||
|
###### 携带Token令牌的请求
|
||||||
|
|
||||||
|
```php
|
||||||
|
$response = Http::withToken('token')->post(...);
|
||||||
|
```
|
||||||
|
|
||||||
|
###### 携带认证文件的请求
|
||||||
|
|
||||||
|
```php
|
||||||
|
$response = Http::withCert('/path/server.pem', 'password')->post(...);
|
||||||
|
```
|
||||||
|
|
||||||
|
###### 携带SSL证书的请求
|
||||||
|
|
||||||
|
```php
|
||||||
|
// 默认
|
||||||
|
$response = Http::withVerify(false)->post(...);
|
||||||
|
|
||||||
|
$response = Http::withVerify('/path/to/cert.pem')->post(...);
|
||||||
|
```
|
||||||
|
|
||||||
|
###### 携带COOKIE的请求
|
||||||
|
|
||||||
|
```php
|
||||||
|
$response = Http::withCookies(array $cookies, string $domain)->post(...);
|
||||||
|
```
|
||||||
|
|
||||||
|
###### 携带协议版本的请求
|
||||||
|
|
||||||
|
```php
|
||||||
|
$response = Http::withVersion(1.1)->post(...);
|
||||||
|
```
|
||||||
|
|
||||||
|
###### 携带代理的请求
|
||||||
|
|
||||||
|
```php
|
||||||
|
$response = Http::withProxy('tcp://localhost:8125')->post(...);
|
||||||
|
|
||||||
|
$response = Http::withProxy([
|
||||||
|
'http' => 'tcp://localhost:8125', // Use this proxy with "http"
|
||||||
|
'https' => 'tcp://localhost:9124', // Use this proxy with "https",
|
||||||
|
'no' => ['.com.cn', 'yzh52521.cn'] // Don't use a proxy with these
|
||||||
|
])->post(...);
|
||||||
|
```
|
||||||
|
|
||||||
|
###### 设置超时时间(单位秒)
|
||||||
|
|
||||||
|
```php
|
||||||
|
$response = Http::timeout(60)->post(...);
|
||||||
|
```
|
||||||
|
|
||||||
|
###### 设置延迟时间(单位秒)
|
||||||
|
|
||||||
|
```php
|
||||||
|
$response = Http::delay(60)->post(...);
|
||||||
|
```
|
||||||
|
|
||||||
|
###### 设置并发次数
|
||||||
|
|
||||||
|
```php
|
||||||
|
$response = Http::concurrency(10)->promise(...);
|
||||||
|
```
|
||||||
|
|
||||||
|
###### 重发请求,设置retry方法。重试次数/两次重试之间的时间间隔(毫秒):
|
||||||
|
|
||||||
|
```php
|
||||||
|
$response = Http::retry(3, 100)->post(...);
|
||||||
|
```
|
||||||
|
|
||||||
|
#### 异步请求
|
||||||
|
|
||||||
|
```php
|
||||||
|
use yzh52521\EasyHttp\Response;
|
||||||
|
use yzh52521\EasyHttp\RequestException;
|
||||||
|
|
||||||
|
Http::getAsync('http://easyhttp.yzh52521.cn/api/sleep3.json', ['token' => TOKEN], function (Response $response) {
|
||||||
|
echo '异步请求成功,响应内容:' . $response->body() . PHP_EOL;
|
||||||
|
}, function (RequestException $e) {
|
||||||
|
echo '异步请求异常,错误码:' . $e->getCode() . ',错误信息:' . $e->getMessage() . PHP_EOL;
|
||||||
|
});
|
||||||
|
echo json_encode(['code' => 200, 'msg' => '请求成功'], JSON_UNESCAPED_UNICODE) . PHP_EOL;
|
||||||
|
|
||||||
|
//输出
|
||||||
|
{"code":200,"msg":"请求成功"}
|
||||||
|
异步请求成功,响应内容:{"code":200,"msg":"success","second":3}
|
||||||
|
|
||||||
|
Http::getAsync('http1://easyhttp.yzh52521.cn/api/sleep3.json', function (Response $response) {
|
||||||
|
echo '异步请求成功,响应内容:' . $response->body() . PHP_EOL;
|
||||||
|
}, function (RequestException $e) {
|
||||||
|
echo '异步请求异常,错误信息:' . $e->getMessage() . PHP_EOL;
|
||||||
|
});
|
||||||
|
echo json_encode(['code' => 200, 'msg' => '请求成功'], JSON_UNESCAPED_UNICODE) . PHP_EOL;
|
||||||
|
|
||||||
|
//输出
|
||||||
|
{"code":200,"msg":"请求成功"}
|
||||||
|
异步请求异常,错误信息:cURL error 1: Protocol "http1" not supported or disabled in libcurl (see https://curl.haxx.se/libcurl/c/libcurl-errors.html)
|
||||||
|
|
||||||
|
Http::postAsync(...);
|
||||||
|
|
||||||
|
Http::patchAsync(...);
|
||||||
|
|
||||||
|
Http::putAsync(...);
|
||||||
|
|
||||||
|
Http::deleteAsync(...);
|
||||||
|
|
||||||
|
Http::headAsync(...);
|
||||||
|
|
||||||
|
Http::optionsAsync(...);
|
||||||
|
```
|
||||||
|
|
||||||
|
#### 异步并发请求
|
||||||
|
|
||||||
|
```php
|
||||||
|
use yzh52521\EasyHttp\Response;
|
||||||
|
use yzh52521\EasyHttp\RequestException;
|
||||||
|
|
||||||
|
$promises = [
|
||||||
|
Http::getAsync('http://easyhttp.yzh52521.cn/api/sleep3.json'),
|
||||||
|
Http::getAsync('http1://easyhttp.yzh52521.cn/api/sleep1.json', ['name' => 'yzh52521']),
|
||||||
|
Http::postAsync('http://easyhttp.yzh52521.cn/api/sleep2.json', ['name' => 'yzh52521']),
|
||||||
|
];
|
||||||
|
|
||||||
|
Http::concurrency(10)->multiAsync($promises, function (Response $response, $index) {
|
||||||
|
echo "发起第 $index 个异步请求,请求时长:" . $response->json()->second . '秒' . PHP_EOL;
|
||||||
|
}, function (RequestException $e, $index) {
|
||||||
|
echo "发起第 $index 个请求失败,失败原因:" . $e->getMessage() . PHP_EOL;
|
||||||
|
});
|
||||||
|
|
||||||
|
//输出
|
||||||
|
发起第 1 个请求失败,失败原因:cURL error 1: Protocol "http1" not supported or disabled in libcurl (see https://curl.haxx.se/libcurl/c/libcurl-errors.html)
|
||||||
|
发起第 2 个异步请求,请求时长:2 秒
|
||||||
|
发起第 0 个异步请求,请求时长:3 秒
|
||||||
|
```
|
||||||
|
> 如果未调用concurrency()方法,并发次数默认为$promises的元素个数,$promises数组里必须是异步请求
|
||||||
|
|
||||||
|
## 使用响应
|
||||||
|
|
||||||
|
发起请求后会返回一个 yzh52521\EasyHttp\Response $response的实例,该实例提供了以下方法来检查请求的响应:
|
||||||
|
|
||||||
|
```php
|
||||||
|
$response->body() : string;
|
||||||
|
$response->json() : object;
|
||||||
|
$response->array() : array;
|
||||||
|
$response->status() : int;
|
||||||
|
$response->ok() : bool;
|
||||||
|
$response->successful() : bool;
|
||||||
|
$response->serverError() : bool;
|
||||||
|
$response->clientError() : bool;
|
||||||
|
$response->headers() : array;
|
||||||
|
$response->header($header) : string;
|
||||||
|
```
|
||||||
|
|
||||||
|
## 异常处理
|
||||||
|
|
||||||
|
请求在发生客户端或服务端错误时会抛出 yzh52521\EasyHttp\RequestException $e异常,该实例提供了以下方法来返回异常信息:
|
||||||
|
|
||||||
|
```php
|
||||||
|
$e->getCode() : int;
|
||||||
|
$e->getMessage() : string;
|
||||||
|
$e->getFile() : string;
|
||||||
|
$e->getLine() : int;
|
||||||
|
$e->getTrace() : array;
|
||||||
|
$e->getTraceAsString() : string;
|
||||||
|
```
|
||||||
|
## 调试日志
|
||||||
|
|
||||||
|
有时候难免要对 Http 的请求和响应包体进行记录以方便查找问题或做什么
|
||||||
|
|
||||||
|
```php
|
||||||
|
//传递一个日志类 thinkphp \think\facade\Log laravel Illuminate\Support\Facades\Log
|
||||||
|
Http::debug(Log::class)->post(...);
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
|
## 更新日志
|
||||||
|
### 2022-05-11
|
||||||
|
* 新增removeBodyFormat() 用于withOptions 指定body时,清除原由的bodyFromat
|
||||||
|
### 2022-05-10
|
||||||
|
* 新增发送原生请求的方法client()
|
||||||
|
* 新增发送原生异步请求的方法clientASync()
|
||||||
|
### 2021-09-03
|
||||||
|
* 新增 debug() 调试日志
|
||||||
|
* 新增 retry() 重试机制
|
||||||
|
* 修复header重叠的bug
|
||||||
|
### 2020-03-30
|
||||||
|
* 修复部分情况下IDE不能智能提示的BUG
|
||||||
|
* get()、getAsync()方法支持带参数的url
|
||||||
|
* 新增withUA()方法
|
||||||
|
* 新增withStream()方法
|
||||||
|
* 新增asMultipart()方法,attach()的别名
|
||||||
|
* 新增multiAsync()异步并发请求方法
|
||||||
|
|
||||||
|
### 2020-03-20
|
||||||
|
* 新增异步请求getAsync()方法
|
||||||
|
* 新增异步请求postAsync()方法
|
||||||
|
* 新增异步请求patchAsync()方法
|
||||||
|
* 新增异步请求putAsync()方法
|
||||||
|
* 新增异步请求deleteAsync()方法
|
||||||
|
* 新增异步请求headAsync()方法
|
||||||
|
* 新增异步请求optionsAsync()方法
|
||||||
|
|
||||||
|
## Todo List
|
||||||
|
- [x] 异步请求
|
||||||
|
- [x] 并发请求
|
||||||
|
- [x] 重试机制
|
||||||
|
- [ ] 支持http2
|
||||||
|
- [ ] 支持swoole
|
||||||
|
# easyhttp
|
33
vendor/yzh52521/easyhttp/composer.json
vendored
Normal file
33
vendor/yzh52521/easyhttp/composer.json
vendored
Normal file
@ -0,0 +1,33 @@
|
|||||||
|
{
|
||||||
|
"name": "yzh52521/easyhttp",
|
||||||
|
"description": "EasyHttp 是一个轻量级、语义化、对IDE友好的HTTP客户端,支持常见的HTTP请求、异步请求和并发请求,让你可以快速地使用 HTTP 请求与其他 Web 应用进行通信。",
|
||||||
|
"license": "MIT",
|
||||||
|
"keywords": [
|
||||||
|
"easyhttp",
|
||||||
|
"EasyHttp",
|
||||||
|
"php-http",
|
||||||
|
"phphttp",
|
||||||
|
"easy-http",
|
||||||
|
"php",
|
||||||
|
"http",
|
||||||
|
"curl"
|
||||||
|
],
|
||||||
|
"homepage": "https://github.com/yzh52521/easyhttp",
|
||||||
|
"authors": [
|
||||||
|
{
|
||||||
|
"name": "yzh52521",
|
||||||
|
"email": "396751927@qq.com"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"require": {
|
||||||
|
"php": "^7.2.5|^8.0",
|
||||||
|
"guzzlehttp/guzzle": "^6.0|^7.0",
|
||||||
|
"psr/log":"^1.0|^2.0|^3.0"
|
||||||
|
},
|
||||||
|
"autoload": {
|
||||||
|
"psr-4": {
|
||||||
|
"yzh52521\\EasyHttp\\": "src/"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"minimum-stability": "stable"
|
||||||
|
}
|
10
vendor/yzh52521/easyhttp/src/ConnectionException.php
vendored
Normal file
10
vendor/yzh52521/easyhttp/src/ConnectionException.php
vendored
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace yzh52521\EasyHttp;
|
||||||
|
|
||||||
|
use Exception;
|
||||||
|
|
||||||
|
class ConnectionException extends Exception
|
||||||
|
{
|
||||||
|
//
|
||||||
|
}
|
21
vendor/yzh52521/easyhttp/src/Facade.php
vendored
Normal file
21
vendor/yzh52521/easyhttp/src/Facade.php
vendored
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace yzh52521\EasyHttp;
|
||||||
|
|
||||||
|
class Facade
|
||||||
|
{
|
||||||
|
protected $facade;
|
||||||
|
|
||||||
|
public function __construct()
|
||||||
|
{
|
||||||
|
$this->facade = new $this->facade;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function __call($name, $params) {
|
||||||
|
return call_user_func_array([$this->facade, $name], $params);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static function __callStatic($name, $params) {
|
||||||
|
return call_user_func_array([new static(), $name], $params);
|
||||||
|
}
|
||||||
|
}
|
55
vendor/yzh52521/easyhttp/src/Http.php
vendored
Normal file
55
vendor/yzh52521/easyhttp/src/Http.php
vendored
Normal file
@ -0,0 +1,55 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace yzh52521\EasyHttp;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @method static \yzh52521\EasyHttp\Request asJson()
|
||||||
|
* @method static \yzh52521\EasyHttp\Request asForm()
|
||||||
|
* @method static \yzh52521\EasyHttp\Request asMultipart(string $name, string $contents, string|null $filename = null, array $headers)
|
||||||
|
* @method static \yzh52521\EasyHttp\Request attach(string $name, string $contents, string|null $filename = null, array $headers)
|
||||||
|
*
|
||||||
|
* @method static \yzh52521\EasyHttp\Request withRedirect(bool|array $redirect)
|
||||||
|
* @method static \yzh52521\EasyHttp\Request withStream(bool $boolean)
|
||||||
|
* @method static \yzh52521\EasyHttp\Request withVerify(bool|string $verify)
|
||||||
|
* @method static \yzh52521\EasyHttp\Request withHost(string $host)
|
||||||
|
* @method static \yzh52521\EasyHttp\Request withHeaders(array $headers)
|
||||||
|
* @method static \yzh52521\EasyHttp\Request withBasicAuth(string $username, string $password)
|
||||||
|
* @method static \yzh52521\EasyHttp\Request withDigestAuth(string $username, string $password)
|
||||||
|
* @method static \yzh52521\EasyHttp\Request withUA(string $ua)
|
||||||
|
* @method static \yzh52521\EasyHttp\Request withToken(string $token, string $type = 'Bearer')
|
||||||
|
* @method static \yzh52521\EasyHttp\Request withCookies(array $cookies, string $domain)
|
||||||
|
* @method static \yzh52521\EasyHttp\Request withProxy(string|array $proxy)
|
||||||
|
* @method static \yzh52521\EasyHttp\Request withVersion(string $version)
|
||||||
|
* @method static \yzh52521\EasyHttp\Request withOptions(array $options)
|
||||||
|
*
|
||||||
|
* @method static \yzh52521\EasyHttp\Request debug($class)
|
||||||
|
* @method static \yzh52521\EasyHttp\Request retry(int $retries=1,int $sleep=0)
|
||||||
|
* @method static \yzh52521\EasyHttp\Request delay(int $seconds)
|
||||||
|
* @method static \yzh52521\EasyHttp\Request timeout(int $seconds)
|
||||||
|
* @method static \yzh52521\EasyHttp\Request concurrency(int $times)
|
||||||
|
* @method static \yzh52521\EasyHttp\Request client(string $method, string $url, array $options = [])
|
||||||
|
* @method static \yzh52521\EasyHttp\Request clientAsync(string $method, string $url, array $options = [])
|
||||||
|
* @method static \yzh52521\EasyHttp\Request removeBodyFormat()
|
||||||
|
*
|
||||||
|
* @method static \yzh52521\EasyHttp\Request get(string $url, array $query = [])
|
||||||
|
* @method static \yzh52521\EasyHttp\Request post(string $url, array $data = [])
|
||||||
|
* @method static \yzh52521\EasyHttp\Request patch(string $url, array $data = [])
|
||||||
|
* @method static \yzh52521\EasyHttp\Request put(string $url, array $data = [])
|
||||||
|
* @method static \yzh52521\EasyHttp\Request delete(string $url, array $data = [])
|
||||||
|
* @method static \yzh52521\EasyHttp\Request head(string $url, array $data = [])
|
||||||
|
* @method static \yzh52521\EasyHttp\Request options(string $url, array $data = [])
|
||||||
|
*
|
||||||
|
* @method static \yzh52521\EasyHttp\Request getAsync(string $url, array|null $query = null, callable $success = null, callable $fail = null)
|
||||||
|
* @method static \yzh52521\EasyHttp\Request postAsync(string $url, array|null $data = null, callable $success = null, callable $fail = null)
|
||||||
|
* @method static \yzh52521\EasyHttp\Request patchAsync(string $url, array|null $data = null, callable $success = null, callable $fail = null)
|
||||||
|
* @method static \yzh52521\EasyHttp\Request putAsync(string $url, array|null $data = null, callable $success = null, callable $fail = null)
|
||||||
|
* @method static \yzh52521\EasyHttp\Request deleteAsync(string $url, array|null $data = null, callable $success = null, callable $fail = null)
|
||||||
|
* @method static \yzh52521\EasyHttp\Request headAsync(string $url, array|null $data = null, callable $success = null, callable $fail = null)
|
||||||
|
* @method static \yzh52521\EasyHttp\Request optionsAsync(string $url, array|null $data = null, callable $success = null, callable $fail = null)
|
||||||
|
* @method static \yzh52521\EasyHttp\Request multiAsync(array $promises, callable $success = null, callable $fail = null)
|
||||||
|
*/
|
||||||
|
|
||||||
|
class Http extends Facade
|
||||||
|
{
|
||||||
|
protected $facade = Request::class;
|
||||||
|
}
|
273
vendor/yzh52521/easyhttp/src/Logger.php
vendored
Normal file
273
vendor/yzh52521/easyhttp/src/Logger.php
vendored
Normal file
@ -0,0 +1,273 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace yzh52521\EasyHttp;
|
||||||
|
|
||||||
|
use GuzzleHttp\Exception\RequestException;
|
||||||
|
use GuzzleHttp\MessageFormatter;
|
||||||
|
use GuzzleHttp\Promise;
|
||||||
|
use Psr\Http\Message\RequestInterface;
|
||||||
|
use Psr\Http\Message\ResponseInterface;
|
||||||
|
use Psr\Log\LogLevel;
|
||||||
|
use Psr\Log\LoggerInterface;
|
||||||
|
|
||||||
|
use InvalidArgumentException;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Guzzle middleware which logs a request and its response.
|
||||||
|
*/
|
||||||
|
class Logger
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* @var \Psr\Log\LoggerInterface|callable
|
||||||
|
*/
|
||||||
|
protected $logger;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var \GuzzleHttp\MessageFormatter|callable
|
||||||
|
*/
|
||||||
|
protected $formatter;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var string|callable Constant or callable that accepts a Response.
|
||||||
|
*/
|
||||||
|
protected $logLevel;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var boolean Whether or not to log requests as they are made.
|
||||||
|
*/
|
||||||
|
protected $logRequests;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a callable middleware for logging requests and responses.
|
||||||
|
*
|
||||||
|
* @param LoggerInterface|callable $logger
|
||||||
|
* @param string|callable Constant or callable that accepts a Response.
|
||||||
|
*/
|
||||||
|
public function __construct($logger, $formatter = null)
|
||||||
|
{
|
||||||
|
// Use the setters to take care of type validation
|
||||||
|
$this->setLogger($logger);
|
||||||
|
$this->setFormatter($formatter ?: $this->getDefaultFormatter());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the default formatter;
|
||||||
|
*
|
||||||
|
* @return MessageFormatter
|
||||||
|
*/
|
||||||
|
protected function getDefaultFormatter()
|
||||||
|
{
|
||||||
|
return new MessageFormatter();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets whether requests should be logged before the response is received.
|
||||||
|
*
|
||||||
|
* @param boolean $logRequests
|
||||||
|
*/
|
||||||
|
public function setRequestLoggingEnabled($logRequests = true)
|
||||||
|
{
|
||||||
|
$this->logRequests = (bool) $logRequests;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the logger, which can be a PSR-3 logger or a callable that accepts
|
||||||
|
* a log level, message, and array context.
|
||||||
|
*
|
||||||
|
* @param LoggerInterface|callable $logger
|
||||||
|
*
|
||||||
|
* @throws InvalidArgumentException
|
||||||
|
*/
|
||||||
|
public function setLogger($logger)
|
||||||
|
{
|
||||||
|
if ($logger instanceof LoggerInterface || is_callable($logger)) {
|
||||||
|
$this->logger = $logger;
|
||||||
|
} else {
|
||||||
|
throw new InvalidArgumentException(
|
||||||
|
"Logger has to be a Psr\Log\LoggerInterface or callable"
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the formatter, which can be a MessageFormatter or callable that
|
||||||
|
* accepts a request, response, and a reason if an error has occurred.
|
||||||
|
*
|
||||||
|
* @param MessageFormatter|callable $formatter
|
||||||
|
*
|
||||||
|
* @throws InvalidArgumentException
|
||||||
|
*/
|
||||||
|
public function setFormatter($formatter)
|
||||||
|
{
|
||||||
|
if ($formatter instanceof MessageFormatter || is_callable($formatter)) {
|
||||||
|
$this->formatter = $formatter;
|
||||||
|
} else {
|
||||||
|
throw new InvalidArgumentException(
|
||||||
|
"Formatter has to be a \GuzzleHttp\MessageFormatter or callable"
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the log level to use, which can be either a string or a callable
|
||||||
|
* that accepts a response (which could be null). A log level could also
|
||||||
|
* be null, which indicates that the default log level should be used.
|
||||||
|
*
|
||||||
|
* @param string|callable|null
|
||||||
|
*/
|
||||||
|
public function setLogLevel($logLevel)
|
||||||
|
{
|
||||||
|
$this->logLevel = $logLevel;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Logs a request and/or a response.
|
||||||
|
*
|
||||||
|
* @param RequestInterface $request
|
||||||
|
* @param ResponseInterface|null $response
|
||||||
|
* @param $reason
|
||||||
|
* @return mixed
|
||||||
|
*/
|
||||||
|
protected function log(
|
||||||
|
RequestInterface $request,
|
||||||
|
ResponseInterface $response = null,
|
||||||
|
$reason = null
|
||||||
|
) {
|
||||||
|
if ($reason instanceof RequestException) {
|
||||||
|
$response = $reason->getResponse();
|
||||||
|
}
|
||||||
|
|
||||||
|
$level = $this->getLogLevel($response);
|
||||||
|
$message = $this->getLogMessage($request, $response, $reason);
|
||||||
|
$context = compact('request', 'response', 'reason');
|
||||||
|
|
||||||
|
// Make sure that the content of the body is available again.
|
||||||
|
if ($response) {
|
||||||
|
$response->getBody()->seek(0);;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (is_callable($this->logger)) {
|
||||||
|
return call_user_func($this->logger, $level, $message, $context);
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->logger->log($level, $message, $context);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Formats a request and response as a log message.
|
||||||
|
*
|
||||||
|
* @param RequestInterface $request
|
||||||
|
* @param ResponseInterface|null $response
|
||||||
|
* @param mixed $reason
|
||||||
|
*
|
||||||
|
* @return string The formatted message.
|
||||||
|
*/
|
||||||
|
protected function getLogMessage(
|
||||||
|
RequestInterface $request,
|
||||||
|
ResponseInterface $response = null,
|
||||||
|
$reason = null
|
||||||
|
) {
|
||||||
|
if ($this->formatter instanceof MessageFormatter) {
|
||||||
|
return $this->formatter->format(
|
||||||
|
$request,
|
||||||
|
$response,
|
||||||
|
$reason
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
return call_user_func($this->formatter, $request, $response, $reason);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns a log level for a given response.
|
||||||
|
*
|
||||||
|
* @param ResponseInterface $response The response being logged.
|
||||||
|
*
|
||||||
|
* @return string LogLevel
|
||||||
|
*/
|
||||||
|
protected function getLogLevel(ResponseInterface $response = null)
|
||||||
|
{
|
||||||
|
if ( ! $this->logLevel) {
|
||||||
|
return $this->getDefaultLogLevel($response);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (is_callable($this->logLevel)) {
|
||||||
|
return call_user_func($this->logLevel, $response);
|
||||||
|
}
|
||||||
|
|
||||||
|
return (string) $this->logLevel;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the default log level for a response.
|
||||||
|
*
|
||||||
|
* @param ResponseInterface $response
|
||||||
|
*
|
||||||
|
* @return string LogLevel
|
||||||
|
*/
|
||||||
|
protected function getDefaultLogLevel(ResponseInterface $response = null) {
|
||||||
|
if ($response && $response->getStatusCode() >= 300) {
|
||||||
|
return LogLevel::NOTICE;
|
||||||
|
}
|
||||||
|
|
||||||
|
return LogLevel::INFO;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns a function which is handled when a request was successful.
|
||||||
|
*
|
||||||
|
* @param RequestInterface $request
|
||||||
|
*
|
||||||
|
* @return \Closure
|
||||||
|
*/
|
||||||
|
protected function onSuccess(RequestInterface $request)
|
||||||
|
{
|
||||||
|
return function ($response) use ($request) {
|
||||||
|
$this->log($request, $response);
|
||||||
|
return $response;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns a function which is handled when a request was rejected.
|
||||||
|
*
|
||||||
|
* @param RequestInterface $request
|
||||||
|
*
|
||||||
|
* @return \Closure
|
||||||
|
*/
|
||||||
|
protected function onFailure(RequestInterface $request)
|
||||||
|
{
|
||||||
|
return function ($reason) use ($request) {
|
||||||
|
|
||||||
|
// Only log a rejected request if it hasn't already been logged.
|
||||||
|
if ( ! $this->logRequests) {
|
||||||
|
$this->log($request, null, $reason);
|
||||||
|
}
|
||||||
|
|
||||||
|
return Promise\rejection_for($reason);
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Called when the middleware is handled by the client.
|
||||||
|
*
|
||||||
|
* @param callable $handler
|
||||||
|
*
|
||||||
|
* @return \Closure
|
||||||
|
*/
|
||||||
|
public function __invoke(callable $handler)
|
||||||
|
{
|
||||||
|
return function ($request, array $options) use ($handler) {
|
||||||
|
|
||||||
|
// Only log requests if explicitly set to do so
|
||||||
|
if ($this->logRequests) {
|
||||||
|
$this->log($request);
|
||||||
|
}
|
||||||
|
|
||||||
|
return $handler($request, $options)->then(
|
||||||
|
$this->onSuccess($request),
|
||||||
|
$this->onFailure($request)
|
||||||
|
);
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
607
vendor/yzh52521/easyhttp/src/Request.php
vendored
Normal file
607
vendor/yzh52521/easyhttp/src/Request.php
vendored
Normal file
@ -0,0 +1,607 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace yzh52521\EasyHttp;
|
||||||
|
|
||||||
|
use GuzzleHttp\Handler\CurlHandler;
|
||||||
|
use GuzzleHttp\HandlerStack;
|
||||||
|
|
||||||
|
use GuzzleHttp\Pool;
|
||||||
|
use GuzzleHttp\Client;
|
||||||
|
use GuzzleHttp\Promise;
|
||||||
|
use GuzzleHttp\Cookie\CookieJar;
|
||||||
|
use GuzzleHttp\Exception\ConnectException;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @method \yzh52521\EasyHttp\Response body()
|
||||||
|
* @method \yzh52521\EasyHttp\Response array()
|
||||||
|
* @method \yzh52521\EasyHttp\Response json()
|
||||||
|
* @method \yzh52521\EasyHttp\Response headers()
|
||||||
|
* @method \yzh52521\EasyHttp\Response header( string $header )
|
||||||
|
* @method \yzh52521\EasyHttp\Response status()
|
||||||
|
* @method \yzh52521\EasyHttp\Response successful()
|
||||||
|
* @method \yzh52521\EasyHttp\Response ok()
|
||||||
|
* @method \yzh52521\EasyHttp\Response redirect()
|
||||||
|
* @method \yzh52521\EasyHttp\Response clientError()
|
||||||
|
* @method \yzh52521\EasyHttp\Response serverError()
|
||||||
|
*/
|
||||||
|
class Request
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* \GuzzleHttp\Client单例
|
||||||
|
* @var array
|
||||||
|
*/
|
||||||
|
private static $instances = [];
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \GuzzleHttp\Client;
|
||||||
|
* @var Client
|
||||||
|
*/
|
||||||
|
protected $client;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Body格式
|
||||||
|
* @var string
|
||||||
|
*/
|
||||||
|
protected $bodyFormat;
|
||||||
|
|
||||||
|
protected $isRemoveBodyFormat = false;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var array
|
||||||
|
*/
|
||||||
|
protected $options = [];
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var array
|
||||||
|
*/
|
||||||
|
protected $promises = [];
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 并发次数
|
||||||
|
* @var
|
||||||
|
*/
|
||||||
|
protected $concurrency;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @var HandlerStack
|
||||||
|
*/
|
||||||
|
protected $handlerStack;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Request constructor.
|
||||||
|
*/
|
||||||
|
public function __construct()
|
||||||
|
{
|
||||||
|
$this->client = $this->getInstance();
|
||||||
|
|
||||||
|
$this->bodyFormat = 'form_params';
|
||||||
|
$this->options = [
|
||||||
|
'http_errors' => false,
|
||||||
|
];
|
||||||
|
if (!$this->handlerStack instanceof HandlerStack) {
|
||||||
|
$this->handlerStack = HandlerStack::create( new CurlHandler() );
|
||||||
|
}
|
||||||
|
$this->options['handler'] = $this->handlerStack;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Request destructor.
|
||||||
|
*/
|
||||||
|
public function __destruct()
|
||||||
|
{
|
||||||
|
if (!empty( $this->promises )) {
|
||||||
|
Promise\settle( $this->promises )->wait();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取单例
|
||||||
|
* @return mixed
|
||||||
|
*/
|
||||||
|
public function getInstance()
|
||||||
|
{
|
||||||
|
$name = get_called_class();
|
||||||
|
|
||||||
|
if (!isset( self::$instances[$name] )) {
|
||||||
|
self::$instances[$name] = new Client();
|
||||||
|
}
|
||||||
|
|
||||||
|
return self::$instances[$name];
|
||||||
|
}
|
||||||
|
|
||||||
|
public function asForm()
|
||||||
|
{
|
||||||
|
$this->bodyFormat = 'form_params';
|
||||||
|
$this->withHeaders( ['Content-Type' => 'application/x-www-form-urlencoded'] );
|
||||||
|
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function asJson()
|
||||||
|
{
|
||||||
|
$this->bodyFormat = 'json';
|
||||||
|
$this->withHeaders( ['Content-Type' => 'application/json'] );
|
||||||
|
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function asMultipart(string $name,string $contents,string $filename = null,array $headers = [])
|
||||||
|
{
|
||||||
|
$this->bodyFormat = 'multipart';
|
||||||
|
|
||||||
|
$this->options = array_filter( [
|
||||||
|
'name' => $name,
|
||||||
|
'contents' => $contents,
|
||||||
|
'headers' => $headers,
|
||||||
|
'filename' => $filename,
|
||||||
|
] );
|
||||||
|
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function withHost(string $host)
|
||||||
|
{
|
||||||
|
$this->options['base_uri'] = $host;
|
||||||
|
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function withOptions(array $options)
|
||||||
|
{
|
||||||
|
unset( $this->options[$this->bodyFormat],$this->options['body'] );
|
||||||
|
|
||||||
|
$this->options = array_merge_recursive( $this->options,$options );
|
||||||
|
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function withCert(string $path,string $password)
|
||||||
|
{
|
||||||
|
$this->options['cert'] = [$path,$password];
|
||||||
|
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function withHeaders(array $headers)
|
||||||
|
{
|
||||||
|
$this->options = array_merge_recursive( $this->options,[
|
||||||
|
'headers' => $headers,
|
||||||
|
] );
|
||||||
|
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function withBasicAuth(string $username,string $password)
|
||||||
|
{
|
||||||
|
$this->options['auth'] = [$username,$password];
|
||||||
|
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function withDigestAuth(string $username,string $password)
|
||||||
|
{
|
||||||
|
$this->options['auth'] = [$username,$password,'digest'];
|
||||||
|
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function withUA(string $ua)
|
||||||
|
{
|
||||||
|
$this->options['headers']['User-Agent'] = trim( $ua );
|
||||||
|
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function withToken(string $token,string $type = 'Bearer')
|
||||||
|
{
|
||||||
|
$this->options['headers']['Authorization'] = trim( $type.' '.$token );
|
||||||
|
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function withCookies(array $cookies,string $domain)
|
||||||
|
{
|
||||||
|
$this->options = array_merge_recursive( $this->options,[
|
||||||
|
'cookies' => CookieJar::fromArray( $cookies,$domain ),
|
||||||
|
] );
|
||||||
|
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function withProxy($proxy)
|
||||||
|
{
|
||||||
|
$this->options['proxy'] = $proxy;
|
||||||
|
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function withVersion($version)
|
||||||
|
{
|
||||||
|
$this->options['version'] = $version;
|
||||||
|
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function withRedirect($redirect = false)
|
||||||
|
{
|
||||||
|
$this->options['allow_redirects'] = $redirect;
|
||||||
|
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function withVerify($verify = false)
|
||||||
|
{
|
||||||
|
$this->options['verify'] = $verify;
|
||||||
|
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function withStream($boolean = false)
|
||||||
|
{
|
||||||
|
$this->options['stream'] = $boolean;
|
||||||
|
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function concurrency(int $times)
|
||||||
|
{
|
||||||
|
$this->concurrency = $times;
|
||||||
|
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function retry(int $retries = 1,int $sleep = 0)
|
||||||
|
{
|
||||||
|
$this->handlerStack->push( ( new Retry() )->handle( $retries,$sleep ) );
|
||||||
|
$this->options['handler'] = $this->handlerStack;
|
||||||
|
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function delay(int $seconds)
|
||||||
|
{
|
||||||
|
$this->options['delay'] = $seconds * 1000;
|
||||||
|
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function timeout(int $seconds)
|
||||||
|
{
|
||||||
|
$this->options['timeout'] = $seconds * 1000;
|
||||||
|
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function removeBodyFormat()
|
||||||
|
{
|
||||||
|
$this->isRemoveBodyFormat = true;
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function debug($class)
|
||||||
|
{
|
||||||
|
$logger = new Logger( function ($level,$message,array $context) use ($class) {
|
||||||
|
$class::log( $level,$message );
|
||||||
|
},function ($request,$response,$reason) {
|
||||||
|
$requestBody = $request->getBody();
|
||||||
|
$requestBody->rewind();
|
||||||
|
|
||||||
|
//请求头
|
||||||
|
$requestHeaders = [];
|
||||||
|
|
||||||
|
foreach ( $request->getHeaders() as $k => $vs ) {
|
||||||
|
foreach ( $vs as $v ) {
|
||||||
|
$requestHeaders[] = "$k: $v";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//响应头
|
||||||
|
$responseHeaders = [];
|
||||||
|
|
||||||
|
foreach ( $response->getHeaders() as $k => $vs ) {
|
||||||
|
foreach ( $vs as $v ) {
|
||||||
|
$responseHeaders[] = "$k: $v";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$uri = $request->getUri();
|
||||||
|
$path = $uri->getPath();
|
||||||
|
|
||||||
|
if ($query = $uri->getQuery()) {
|
||||||
|
$path .= '?'.$query;
|
||||||
|
}
|
||||||
|
|
||||||
|
return sprintf(
|
||||||
|
"Request %s\n%s %s HTTP/%s\r\n%s\r\n\r\n%s\r\n--------------------\r\nHTTP/%s %s %s\r\n%s\r\n\r\n%s",
|
||||||
|
$uri,
|
||||||
|
$request->getMethod(),
|
||||||
|
$path,
|
||||||
|
$request->getProtocolVersion(),
|
||||||
|
join( "\r\n",$requestHeaders ),
|
||||||
|
$requestBody->getContents(),
|
||||||
|
$response->getProtocolVersion(),
|
||||||
|
$response->getStatusCode(),
|
||||||
|
$response->getReasonPhrase(),
|
||||||
|
join( "\r\n",$responseHeaders ),
|
||||||
|
$response->getBody()->getContents()
|
||||||
|
);
|
||||||
|
} );
|
||||||
|
$this->handlerStack->push( $logger );
|
||||||
|
$this->options['handler'] = $this->handlerStack;
|
||||||
|
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function attach(string $name,string $contents,string $filename = null,array $headers = [])
|
||||||
|
{
|
||||||
|
$this->options['multipart'] = array_filter( [
|
||||||
|
'name' => $name,
|
||||||
|
'contents' => $contents,
|
||||||
|
'headers' => $headers,
|
||||||
|
'filename' => $filename,
|
||||||
|
] );
|
||||||
|
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function get(string $url,array $query = [])
|
||||||
|
{
|
||||||
|
$params= parse_url( $url,PHP_URL_QUERY );
|
||||||
|
|
||||||
|
parse_str( $params?:'',$result );
|
||||||
|
|
||||||
|
$this->options['query'] = array_merge( $result,$query );
|
||||||
|
|
||||||
|
return $this->request( 'GET',$url,$query );
|
||||||
|
}
|
||||||
|
|
||||||
|
public function post(string $url,array $data = [])
|
||||||
|
{
|
||||||
|
$this->options[$this->bodyFormat] = $data;
|
||||||
|
|
||||||
|
return $this->request( 'POST',$url,$data );
|
||||||
|
}
|
||||||
|
|
||||||
|
public function patch(string $url,array $data = [])
|
||||||
|
{
|
||||||
|
$this->options[$this->bodyFormat] = $data;
|
||||||
|
|
||||||
|
return $this->request( 'PATCH',$url,$data );
|
||||||
|
}
|
||||||
|
|
||||||
|
public function put(string $url,array $data = [])
|
||||||
|
{
|
||||||
|
$this->options[$this->bodyFormat] = $data;
|
||||||
|
|
||||||
|
return $this->request( 'PUT',$url,$data );
|
||||||
|
}
|
||||||
|
|
||||||
|
public function delete(string $url,array $data = [])
|
||||||
|
{
|
||||||
|
$this->options[$this->bodyFormat] = $data;
|
||||||
|
|
||||||
|
return $this->request( 'DELETE',$url,$data );
|
||||||
|
}
|
||||||
|
|
||||||
|
public function head(string $url,array $data = [])
|
||||||
|
{
|
||||||
|
$this->options[$this->bodyFormat] = $data;
|
||||||
|
|
||||||
|
return $this->request( 'HEAD',$url,$data );
|
||||||
|
}
|
||||||
|
|
||||||
|
public function options(string $url,array $data = [])
|
||||||
|
{
|
||||||
|
$this->options[$this->bodyFormat] = $data;
|
||||||
|
|
||||||
|
return $this->request( 'OPTIONS',$url,$data );
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getAsync(string $url,$query = null,callable $success = null,callable $fail = null)
|
||||||
|
{
|
||||||
|
is_callable( $query ) || $this->options['query'] = $query;
|
||||||
|
|
||||||
|
return $this->requestAsync( 'GET',$url,$query,$success,$fail );
|
||||||
|
}
|
||||||
|
|
||||||
|
public function postAsync(string $url,$data = null,callable $success = null,callable $fail = null)
|
||||||
|
{
|
||||||
|
is_callable( $data ) || $this->options[$this->bodyFormat] = $data;
|
||||||
|
|
||||||
|
return $this->requestAsync( 'POST',$url,$data,$success,$fail );
|
||||||
|
}
|
||||||
|
|
||||||
|
public function patchAsync(string $url,$data = null,callable $success = null,callable $fail = null)
|
||||||
|
{
|
||||||
|
is_callable( $data ) || $this->options[$this->bodyFormat] = $data;
|
||||||
|
|
||||||
|
return $this->requestAsync( 'PATCH',$url,$data,$success,$fail );
|
||||||
|
}
|
||||||
|
|
||||||
|
public function putAsync(string $url,$data = null,callable $success = null,callable $fail = null)
|
||||||
|
{
|
||||||
|
is_callable( $data ) || $this->options[$this->bodyFormat] = $data;
|
||||||
|
|
||||||
|
return $this->requestAsync( 'PUT',$url,$data,$success,$fail );
|
||||||
|
}
|
||||||
|
|
||||||
|
public function deleteAsync(string $url,$data = null,callable $success = null,callable $fail = null)
|
||||||
|
{
|
||||||
|
is_callable( $data ) || $this->options[$this->bodyFormat] = $data;
|
||||||
|
|
||||||
|
return $this->requestAsync( 'DELETE',$url,$data,$success,$fail );
|
||||||
|
}
|
||||||
|
|
||||||
|
public function headAsync(string $url,$data = null,callable $success = null,callable $fail = null)
|
||||||
|
{
|
||||||
|
is_callable( $data ) || $this->options[$this->bodyFormat] = $data;
|
||||||
|
|
||||||
|
return $this->requestAsync( 'HEAD',$url,$data,$success,$fail );
|
||||||
|
}
|
||||||
|
|
||||||
|
public function optionsAsync(string $url,$data = null,callable $success = null,callable $fail = null)
|
||||||
|
{
|
||||||
|
is_callable( $data ) || $this->options[$this->bodyFormat] = $data;
|
||||||
|
|
||||||
|
return $this->requestAsync( 'OPTIONS',$url,$data,$success,$fail );
|
||||||
|
}
|
||||||
|
|
||||||
|
public function multiAsync(array $promises,callable $success = null,callable $fail = null)
|
||||||
|
{
|
||||||
|
$count = count( $promises );
|
||||||
|
|
||||||
|
$this->concurrency = $this->concurrency ?: $count;
|
||||||
|
|
||||||
|
$requests = function () use ($promises) {
|
||||||
|
foreach ( $promises as $promise ) {
|
||||||
|
yield function () use ($promise) {
|
||||||
|
return $promise;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
$fulfilled = function ($response,$index) use ($success) {
|
||||||
|
if (!is_null( $success )) {
|
||||||
|
$response = $this->response( $response );
|
||||||
|
call_user_func_array( $success,[$response,$index] );
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
$rejected = function ($exception,$index) use ($fail) {
|
||||||
|
if (!is_null( $fail )) {
|
||||||
|
$exception = $this->exception( $exception );
|
||||||
|
call_user_func_array( $fail,[$exception,$index] );
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
$pool = new Pool( $this->client,$requests(),[
|
||||||
|
'concurrency' => $this->concurrency,
|
||||||
|
'fulfilled' => $fulfilled,
|
||||||
|
'rejected' => $rejected,
|
||||||
|
] );
|
||||||
|
|
||||||
|
$pool->promise();
|
||||||
|
|
||||||
|
return $pool;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected function request(string $method,string $url,array $options = [])
|
||||||
|
{
|
||||||
|
isset( $this->options[$this->bodyFormat] ) && $this->options[$this->bodyFormat] = $options;
|
||||||
|
if ($this->isRemoveBodyFormat) {
|
||||||
|
unset( $this->options[$this->bodyFormat] );
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
$response = $this->client->request( $method,$url,$this->options );
|
||||||
|
return $this->response( $response );
|
||||||
|
} catch ( ConnectException $e ) {
|
||||||
|
throw new ConnectionException( $e->getMessage(),0,$e );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 原生请求
|
||||||
|
* @param string $method
|
||||||
|
* @param string $url
|
||||||
|
* @param array $options
|
||||||
|
* @return Response
|
||||||
|
* @throws ConnectionException
|
||||||
|
* @throws \GuzzleHttp\Exception\GuzzleException
|
||||||
|
*/
|
||||||
|
public function client(string $method,string $url,array $options = [])
|
||||||
|
{
|
||||||
|
try {
|
||||||
|
if (empty( $options )) {
|
||||||
|
$options = $this->options;
|
||||||
|
}
|
||||||
|
$response = $this->client->request( $method,$url,$options );
|
||||||
|
return $this->response( $response );
|
||||||
|
} catch ( ConnectException $e ) {
|
||||||
|
throw new ConnectionException( $e->getMessage(),0,$e );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 原生异常请求
|
||||||
|
* @param string $method
|
||||||
|
* @param string $url
|
||||||
|
* @param array $options
|
||||||
|
* @return Response
|
||||||
|
* @throws ConnectionException
|
||||||
|
*/
|
||||||
|
public function clientAsync(string $method,string $url,array $options = [])
|
||||||
|
{
|
||||||
|
try {
|
||||||
|
if (empty( $options )) {
|
||||||
|
$options = $this->options;
|
||||||
|
}
|
||||||
|
$response = $this->client->requestAsync( $method,$url,$options );
|
||||||
|
return $this->response( $response );
|
||||||
|
} catch ( ConnectException $e ) {
|
||||||
|
throw new ConnectionException( $e->getMessage(),0,$e );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
protected function requestAsync(
|
||||||
|
string $method,
|
||||||
|
string $url,
|
||||||
|
$options = null,
|
||||||
|
callable $success = null,
|
||||||
|
callable $fail = null
|
||||||
|
)
|
||||||
|
{
|
||||||
|
if (is_callable( $options )) {
|
||||||
|
$successCallback = $options;
|
||||||
|
$failCallback = $success;
|
||||||
|
} else {
|
||||||
|
$successCallback = $success;
|
||||||
|
$failCallback = $fail;
|
||||||
|
}
|
||||||
|
|
||||||
|
isset( $this->options[$this->bodyFormat] ) && $this->options[$this->bodyFormat] = $options;
|
||||||
|
|
||||||
|
if ($this->isRemoveBodyFormat) {
|
||||||
|
unset( $this->options[$this->bodyFormat] );
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
$promise = $this->client->requestAsync( $method,$url,$this->options );
|
||||||
|
|
||||||
|
$fulfilled = function ($response) use ($successCallback) {
|
||||||
|
if (!is_null( $successCallback )) {
|
||||||
|
$response = $this->response( $response );
|
||||||
|
call_user_func_array( $successCallback,[$response] );
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
$rejected = function ($exception) use ($failCallback) {
|
||||||
|
if (!is_null( $failCallback )) {
|
||||||
|
$exception = $this->exception( $exception );
|
||||||
|
call_user_func_array( $failCallback,[$exception] );
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
$promise->then( $fulfilled,$rejected );
|
||||||
|
|
||||||
|
$this->promises[] = $promise;
|
||||||
|
|
||||||
|
return $promise;
|
||||||
|
} catch ( ConnectException $e ) {
|
||||||
|
throw new ConnectionException( $e->getMessage(),0,$e );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
protected function response($response)
|
||||||
|
{
|
||||||
|
return new Response( $response );
|
||||||
|
}
|
||||||
|
|
||||||
|
protected function exception($exception)
|
||||||
|
{
|
||||||
|
return new RequestException( $exception );
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
43
vendor/yzh52521/easyhttp/src/RequestException.php
vendored
Normal file
43
vendor/yzh52521/easyhttp/src/RequestException.php
vendored
Normal file
@ -0,0 +1,43 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace yzh52521\EasyHttp;
|
||||||
|
|
||||||
|
class RequestException
|
||||||
|
{
|
||||||
|
public $exception;
|
||||||
|
|
||||||
|
public function __construct($exception)
|
||||||
|
{
|
||||||
|
$this->exception = $exception;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getCode()
|
||||||
|
{
|
||||||
|
return $this->exception->getCode();
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getMessage()
|
||||||
|
{
|
||||||
|
return $this->exception->getMessage();
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getFile()
|
||||||
|
{
|
||||||
|
return $this->exception->getFile();
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getLine()
|
||||||
|
{
|
||||||
|
return $this->exception->getLine();
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getTrace()
|
||||||
|
{
|
||||||
|
return $this->exception->getTrace();
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getTraceAsString()
|
||||||
|
{
|
||||||
|
return $this->exception->getTraceAsString();
|
||||||
|
}
|
||||||
|
}
|
212
vendor/yzh52521/easyhttp/src/Response.php
vendored
Normal file
212
vendor/yzh52521/easyhttp/src/Response.php
vendored
Normal file
@ -0,0 +1,212 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace yzh52521\EasyHttp;
|
||||||
|
|
||||||
|
use ArrayAccess;
|
||||||
|
use LogicException;
|
||||||
|
|
||||||
|
class Response implements ArrayAccess
|
||||||
|
{
|
||||||
|
protected $response;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The decoded JSON response.
|
||||||
|
*
|
||||||
|
* @var array
|
||||||
|
*/
|
||||||
|
protected $decoded;
|
||||||
|
|
||||||
|
public function __construct($response)
|
||||||
|
{
|
||||||
|
$this->response = $response;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the body of the response.
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
public function body()
|
||||||
|
{
|
||||||
|
return (string)$this->response->getBody();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the Array decoded body of the response.
|
||||||
|
* @return array|mixed
|
||||||
|
*/
|
||||||
|
public function array()
|
||||||
|
{
|
||||||
|
if (!$this->decoded) {
|
||||||
|
$this->decoded = json_decode( (string)$this->response->getBody(),true );
|
||||||
|
}
|
||||||
|
|
||||||
|
return $this->decoded;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the JSON decoded body of the response.
|
||||||
|
* @return object|mixed
|
||||||
|
*/
|
||||||
|
public function json()
|
||||||
|
{
|
||||||
|
if (!$this->decoded) {
|
||||||
|
$this->decoded = json_decode( (string)$this->response->getBody() );
|
||||||
|
}
|
||||||
|
|
||||||
|
return $this->decoded;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get a header from the response.
|
||||||
|
* @param string $header
|
||||||
|
* @return mixed
|
||||||
|
*/
|
||||||
|
public function header(string $header)
|
||||||
|
{
|
||||||
|
return $this->response->getHeaderLine( $header );
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the headers from the response.
|
||||||
|
* @return mixed
|
||||||
|
*/
|
||||||
|
public function headers()
|
||||||
|
{
|
||||||
|
return $this->mapWithKeys( $this->response->getHeaders(),function ($v,$k) {
|
||||||
|
return [$k => $v];
|
||||||
|
} )->response;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the status code of the response.
|
||||||
|
* @return int
|
||||||
|
*/
|
||||||
|
public function status()
|
||||||
|
{
|
||||||
|
return (int)$this->response->getStatusCode();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Determine if the request was successful.
|
||||||
|
* @return bool
|
||||||
|
*/
|
||||||
|
public function successful()
|
||||||
|
{
|
||||||
|
return $this->status() >= 200 && $this->status() < 300;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Determine if the response code was "OK".
|
||||||
|
* @return bool
|
||||||
|
*/
|
||||||
|
public function ok()
|
||||||
|
{
|
||||||
|
return $this->status() === 200;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Determine if the response was a redirect.
|
||||||
|
* @return bool
|
||||||
|
*/
|
||||||
|
public function redirect()
|
||||||
|
{
|
||||||
|
return $this->status() >= 300 && $this->status() < 400;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Determine if the response indicates a client error occurred.
|
||||||
|
* @return bool
|
||||||
|
*/
|
||||||
|
public function clientError()
|
||||||
|
{
|
||||||
|
return $this->status() >= 400 && $this->status() < 500;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Determine if the response indicates a server error occurred.
|
||||||
|
* @return bool
|
||||||
|
*/
|
||||||
|
public function serverError()
|
||||||
|
{
|
||||||
|
return $this->status() >= 500;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Determine if the given offset exists.
|
||||||
|
*
|
||||||
|
* @param string $offset
|
||||||
|
* @return mixed
|
||||||
|
*/
|
||||||
|
#[\ReturnTypeWillChange]
|
||||||
|
public function offsetExists($offset)
|
||||||
|
{
|
||||||
|
return array_key_exists( $offset,$this->json() );
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the value for a given offset.
|
||||||
|
*
|
||||||
|
* @param string $offset
|
||||||
|
* @return mixed
|
||||||
|
*/
|
||||||
|
#[\ReturnTypeWillChange]
|
||||||
|
public function offsetGet($offset)
|
||||||
|
{
|
||||||
|
return $this->json()[$offset];
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the value at the given offset.
|
||||||
|
*
|
||||||
|
* @param string $offset
|
||||||
|
* @param mixed $value
|
||||||
|
* @return void
|
||||||
|
*
|
||||||
|
* @throws \LogicException
|
||||||
|
*/
|
||||||
|
#[\ReturnTypeWillChange]
|
||||||
|
public function offsetSet($offset,$value)
|
||||||
|
{
|
||||||
|
throw new LogicException( 'Response data may not be mutated using array access.' );
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Unset the value at the given offset.
|
||||||
|
*
|
||||||
|
* @param string $offset
|
||||||
|
* @return void
|
||||||
|
*
|
||||||
|
* @throws \LogicException
|
||||||
|
*/
|
||||||
|
#[\ReturnTypeWillChange]
|
||||||
|
public function offsetUnset($offset)
|
||||||
|
{
|
||||||
|
throw new LogicException( 'Response data may not be mutated using array access.' );
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the body of the response.
|
||||||
|
*
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
public function __toString()
|
||||||
|
{
|
||||||
|
return $this->body();
|
||||||
|
}
|
||||||
|
|
||||||
|
protected function mapWithKeys($items,callable $callback)
|
||||||
|
{
|
||||||
|
$result = [];
|
||||||
|
|
||||||
|
foreach ( $items as $key => $value ) {
|
||||||
|
$assoc = $callback( $value,$key );
|
||||||
|
|
||||||
|
foreach ( $assoc as $mapKey => $mapValue ) {
|
||||||
|
$result[$mapKey] = $mapValue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return new static( $result );
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
46
vendor/yzh52521/easyhttp/src/Retry.php
vendored
Normal file
46
vendor/yzh52521/easyhttp/src/Retry.php
vendored
Normal file
@ -0,0 +1,46 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace yzh52521\EasyHttp;
|
||||||
|
|
||||||
|
use GuzzleHttp\Middleware;
|
||||||
|
use GuzzleHttp\Psr7\Request;
|
||||||
|
use GuzzleHttp\Psr7\Response;
|
||||||
|
use GuzzleHttp\Exception\ServerException;
|
||||||
|
use GuzzleHttp\Exception\ConnectException;
|
||||||
|
|
||||||
|
class Retry
|
||||||
|
{
|
||||||
|
|
||||||
|
public function handle($retries,$sleep)
|
||||||
|
{
|
||||||
|
return Middleware::retry($this->decider($retries), $this->delay($sleep));
|
||||||
|
}
|
||||||
|
|
||||||
|
protected function decider(int $times)
|
||||||
|
{
|
||||||
|
return function (
|
||||||
|
$retries,
|
||||||
|
Request $request,
|
||||||
|
Response $response = null,
|
||||||
|
RequestException $exception = null
|
||||||
|
) use ($times) {
|
||||||
|
// 超过最大重试次数,不再重试
|
||||||
|
if ($retries >= $times) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return $exception instanceof ConnectException || $exception instanceof ServerException || ($response && $response->getStatusCode() >= 500);
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 返回一个匿名函数,该匿名函数返回下次重试的时间(毫秒)
|
||||||
|
* @param int $retry_delay
|
||||||
|
* @return \Closure
|
||||||
|
*/
|
||||||
|
protected function delay(int $retry_delay)
|
||||||
|
{
|
||||||
|
return function ($retries) use ($retry_delay) {
|
||||||
|
return $retry_delay * $retries;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
Loading…
x
Reference in New Issue
Block a user