正在显示
25 个修改的文件
包含
296 行增加
和
229 行删除
| 1 | <?php | 1 | <?php |
| 2 | + | ||
| 2 | namespace jytools; | 3 | namespace jytools; |
| 3 | 4 | ||
| 4 | /* | 5 | /* |
| 5 | binance合约接口 | 6 | binance合约接口 |
| 6 | */ | 7 | */ |
| 8 | + | ||
| 7 | class BinanceFutures | 9 | class BinanceFutures |
| 8 | { | 10 | { |
| 9 | static private string $host = 'https://fapi.binance.com'; | 11 | static private string $host = 'https://fapi.binance.com'; |
| 10 | private string $apikey = ''; | 12 | private string $apikey = ''; |
| 11 | private string $secret = ''; | 13 | private string $secret = ''; |
| 12 | 14 | ||
| 13 | - public function __construct($apikey='', $secret='',$host='') | 15 | + public function __construct($apikey = '', $secret = '', $host = '') |
| 14 | { | 16 | { |
| 15 | $this->apikey = $apikey; | 17 | $this->apikey = $apikey; |
| 16 | $this->secret = $secret; | 18 | $this->secret = $secret; |
| 17 | - if(!empty($host)){ | 19 | + if (!empty($host)) { |
| 18 | self::$host = $host; | 20 | self::$host = $host; |
| 19 | } | 21 | } |
| 20 | } | 22 | } |
| @@ -42,9 +44,9 @@ class BinanceFutures | @@ -42,9 +44,9 @@ class BinanceFutures | ||
| 42 | 44 | ||
| 43 | public function requestAccount($method, $path, $param) | 45 | public function requestAccount($method, $path, $param) |
| 44 | { | 46 | { |
| 45 | - if(empty($this->apikey) || empty($this->secret)){ | 47 | + if (empty($this->apikey) || empty($this->secret)) { |
| 46 | output('api 或 secret 为空'); | 48 | output('api 或 secret 为空'); |
| 47 | - return ['code'=>-1,'msg'=>'apikey or secret is empty']; | 49 | + return ['code' => -1, 'msg' => 'apikey or secret is empty']; |
| 48 | } | 50 | } |
| 49 | $url = $this->createUrl($path); | 51 | $url = $this->createUrl($path); |
| 50 | $param['timestamp'] = getMicrotime(); | 52 | $param['timestamp'] = getMicrotime(); |
| @@ -246,5 +248,3 @@ class BinanceFutures | @@ -246,5 +248,3 @@ class BinanceFutures | ||
| 246 | return self::requestMarket($method, $path, $param); | 248 | return self::requestMarket($method, $path, $param); |
| 247 | } | 249 | } |
| 248 | } | 250 | } |
| 249 | - | ||
| 250 | -?> |
| 1 | <?php | 1 | <?php |
| 2 | + | ||
| 2 | namespace jytools; | 3 | namespace jytools; |
| 3 | 4 | ||
| 4 | /* | 5 | /* |
| 5 | binance现货接口 | 6 | binance现货接口 |
| 6 | */ | 7 | */ |
| 8 | + | ||
| 7 | class BinanceSpot | 9 | class BinanceSpot |
| 8 | { | 10 | { |
| 9 | static private string $host = 'https://api.binance.com'; | 11 | static private string $host = 'https://api.binance.com'; |
| 10 | private string $apikey = ''; | 12 | private string $apikey = ''; |
| 11 | private string $secret = ''; | 13 | private string $secret = ''; |
| 12 | 14 | ||
| 13 | - public function __construct($apikey='', $secret='',$host='') | 15 | + public function __construct($apikey = '', $secret = '', $host = '') |
| 14 | { | 16 | { |
| 15 | $this->apikey = $apikey; | 17 | $this->apikey = $apikey; |
| 16 | $this->secret = $secret; | 18 | $this->secret = $secret; |
| 17 | - if(!empty($host)){ | 19 | + if (!empty($host)) { |
| 18 | self::$host = $host; | 20 | self::$host = $host; |
| 19 | } | 21 | } |
| 20 | } | 22 | } |
| @@ -33,7 +35,7 @@ class BinanceSpot | @@ -33,7 +35,7 @@ class BinanceSpot | ||
| 33 | { | 35 | { |
| 34 | $len = count($param); | 36 | $len = count($param); |
| 35 | if ($len == 0) { | 37 | if ($len == 0) { |
| 36 | -// output('param 为空,签名失败'); | 38 | + // output('param 为空,签名失败'); |
| 37 | return $param; | 39 | return $param; |
| 38 | } | 40 | } |
| 39 | $paramStr = http_build_query($param); | 41 | $paramStr = http_build_query($param); |
| @@ -65,7 +67,7 @@ class BinanceSpot | @@ -65,7 +67,7 @@ class BinanceSpot | ||
| 65 | private function requestListenKey($method, $path, $param) | 67 | private function requestListenKey($method, $path, $param) |
| 66 | { | 68 | { |
| 67 | $url = $this->createUrl($path); | 69 | $url = $this->createUrl($path); |
| 68 | -// $param['timestamp'] = getMicrotime(); | 70 | + // $param['timestamp'] = getMicrotime(); |
| 69 | $param['signature'] = $this->createSign($this->secret, $param); | 71 | $param['signature'] = $this->createSign($this->secret, $param); |
| 70 | $header = $this->createHeader($this->apikey); | 72 | $header = $this->createHeader($this->apikey); |
| 71 | if (!in_array(strtoupper($method), ['GET', 'POST', 'DELETE'])) { | 73 | if (!in_array(strtoupper($method), ['GET', 'POST', 'DELETE'])) { |
| @@ -112,14 +114,14 @@ class BinanceSpot | @@ -112,14 +114,14 @@ class BinanceSpot | ||
| 112 | * @param int $type (=1:行情等接口,不需要签名;=2:账户等接口需要签名) | 114 | * @param int $type (=1:行情等接口,不需要签名;=2:账户等接口需要签名) |
| 113 | * @return array|int|mixed | 115 | * @return array|int|mixed |
| 114 | */ | 116 | */ |
| 115 | - public function request(string $path, string $method, array $param, int $type=1) | 117 | + public function request(string $path, string $method, array $param, int $type = 1) |
| 116 | { | 118 | { |
| 117 | - if($type==2){ | 119 | + if ($type == 2) { |
| 118 | return self::requestAccount($method, $path, $param); | 120 | return self::requestAccount($method, $path, $param); |
| 119 | - }else if($type==1){ | 121 | + } else if ($type == 1) { |
| 120 | return self::requestMarket($method, $path, $param); | 122 | return self::requestMarket($method, $path, $param); |
| 121 | - }else{ | ||
| 122 | - return ['code'=>1000,'msg'=>'type参数错误']; | 123 | + } else { |
| 124 | + return ['code' => 1000, 'msg' => 'type参数错误']; | ||
| 123 | } | 125 | } |
| 124 | } | 126 | } |
| 125 | 127 | ||
| @@ -207,13 +209,15 @@ class BinanceSpot | @@ -207,13 +209,15 @@ class BinanceSpot | ||
| 207 | return $this->requestAccount($method, $path, $param); | 209 | return $this->requestAccount($method, $path, $param); |
| 208 | } | 210 | } |
| 209 | 211 | ||
| 210 | - public function cancelOrderById($param){ | 212 | + public function cancelOrderById($param) |
| 213 | + { | ||
| 211 | $path = '/api/v3/order'; | 214 | $path = '/api/v3/order'; |
| 212 | $method = 'DELETE'; | 215 | $method = 'DELETE'; |
| 213 | return $this->requestAccount($method, $path, $param); | 216 | return $this->requestAccount($method, $path, $param); |
| 214 | } | 217 | } |
| 215 | 218 | ||
| 216 | - public function openOrders($param){ | 219 | + public function openOrders($param) |
| 220 | + { | ||
| 217 | $path = '/api/v3/openOrders'; | 221 | $path = '/api/v3/openOrders'; |
| 218 | $method = 'GET'; | 222 | $method = 'GET'; |
| 219 | return $this->requestAccount($method, $path, $param); | 223 | return $this->requestAccount($method, $path, $param); |
| @@ -232,25 +236,29 @@ class BinanceSpot | @@ -232,25 +236,29 @@ class BinanceSpot | ||
| 232 | return $this->requestListenKey($method, $path, $param); | 236 | return $this->requestListenKey($method, $path, $param); |
| 233 | } | 237 | } |
| 234 | //杠杆账户下单 | 238 | //杠杆账户下单 |
| 235 | - public function orderMargin($param){ | 239 | + public function orderMargin($param) |
| 240 | + { | ||
| 236 | $path = '/sapi/v1/margin/order'; | 241 | $path = '/sapi/v1/margin/order'; |
| 237 | $method = 'POST'; | 242 | $method = 'POST'; |
| 238 | return $this->requestAccount($method, $path, $param); | 243 | return $this->requestAccount($method, $path, $param); |
| 239 | } | 244 | } |
| 240 | //杠杆账户撤销订单 (TRADE) | 245 | //杠杆账户撤销订单 (TRADE) |
| 241 | - public function cancelOrderMargin($param){ | 246 | + public function cancelOrderMargin($param) |
| 247 | + { | ||
| 242 | $path = '/sapi/v1/margin/order'; | 248 | $path = '/sapi/v1/margin/order'; |
| 243 | $method = 'DELETE'; | 249 | $method = 'DELETE'; |
| 244 | return $this->requestAccount($method, $path, $param); | 250 | return $this->requestAccount($method, $path, $param); |
| 245 | } | 251 | } |
| 246 | //杠杆账户订单列表 | 252 | //杠杆账户订单列表 |
| 247 | - public function openOrdersMargin($param){ | 253 | + public function openOrdersMargin($param) |
| 254 | + { | ||
| 248 | $path = '/sapi/v1/margin/openOrders'; | 255 | $path = '/sapi/v1/margin/openOrders'; |
| 249 | $method = 'GET'; | 256 | $method = 'GET'; |
| 250 | return $this->requestAccount($method, $path, $param); | 257 | return $this->requestAccount($method, $path, $param); |
| 251 | } | 258 | } |
| 252 | //调整全仓最大杠杆 (USER_DATA) | 259 | //调整全仓最大杠杆 (USER_DATA) |
| 253 | - public function maxLeverageMargin($param){ | 260 | + public function maxLeverageMargin($param) |
| 261 | + { | ||
| 254 | $path = '/sapi/v1/margin/max-leverage'; | 262 | $path = '/sapi/v1/margin/max-leverage'; |
| 255 | $method = 'POST'; | 263 | $method = 'POST'; |
| 256 | return $this->requestAccount($method, $path, $param); | 264 | return $this->requestAccount($method, $path, $param); |
| @@ -262,13 +270,11 @@ class BinanceSpot | @@ -262,13 +270,11 @@ class BinanceSpot | ||
| 262 | * ================================== | 270 | * ================================== |
| 263 | */ | 271 | */ |
| 264 | //24小时成交数据 | 272 | //24小时成交数据 |
| 265 | -// static public function ticker24hr($param = []) | ||
| 266 | -// { | ||
| 267 | -// $path = '/fapi/v1/ticker/24hr'; | ||
| 268 | -// $method = 'GET'; | ||
| 269 | -// return self::requestMarket($method, $path, $param); | ||
| 270 | -// } | 273 | + // static public function ticker24hr($param = []) |
| 274 | + // { | ||
| 275 | + // $path = '/fapi/v1/ticker/24hr'; | ||
| 276 | + // $method = 'GET'; | ||
| 277 | + // return self::requestMarket($method, $path, $param); | ||
| 278 | + // } | ||
| 271 | 279 | ||
| 272 | } | 280 | } |
| 273 | - | ||
| 274 | -?> |
| 1 | <?php | 1 | <?php |
| 2 | + | ||
| 2 | namespace jytools; | 3 | namespace jytools; |
| 3 | 4 | ||
| 4 | -class Feishu{ | 5 | +class Feishu |
| 6 | +{ | ||
| 5 | const user_liquid = 'gd1d6b34'; | 7 | const user_liquid = 'gd1d6b34'; |
| 6 | const user_jiaoyin = 'efdgdecb'; | 8 | const user_jiaoyin = 'efdgdecb'; |
| 7 | const user_small = 'db9d9g4d'; | 9 | const user_small = 'db9d9g4d'; |
| @@ -9,13 +11,13 @@ class Feishu{ | @@ -9,13 +11,13 @@ class Feishu{ | ||
| 9 | const user_tanli = 'f16c2bd7'; | 11 | const user_tanli = 'f16c2bd7'; |
| 10 | const user_007 = '9de6cgf3'; | 12 | const user_007 = '9de6cgf3'; |
| 11 | //风控处置群 | 13 | //风控处置群 |
| 12 | - const url_risk ='https://open.feishu.cn/open-apis/bot/v2/hook/7509c731-a1ab-4e2f-b781-9082a26fd11d'; | 14 | + const url_risk = 'https://open.feishu.cn/open-apis/bot/v2/hook/7509c731-a1ab-4e2f-b781-9082a26fd11d'; |
| 13 | //零容忍 | 15 | //零容忍 |
| 14 | const url_error = 'https://open.feishu.cn/open-apis/bot/v2/hook/a344e313-4d5d-4aa4-912b-dda37b2e3ee8'; | 16 | const url_error = 'https://open.feishu.cn/open-apis/bot/v2/hook/a344e313-4d5d-4aa4-912b-dda37b2e3ee8'; |
| 15 | //零忽略 | 17 | //零忽略 |
| 16 | const url_warning = 'https://open.feishu.cn/open-apis/bot/v2/hook/01c53b94-378a-45a3-abed-415f84f57f4a'; | 18 | const url_warning = 'https://open.feishu.cn/open-apis/bot/v2/hook/01c53b94-378a-45a3-abed-415f84f57f4a'; |
| 17 | //软件异常报警 | 19 | //软件异常报警 |
| 18 | - const url_warning_soft ='https://open.feishu.cn/open-apis/bot/v2/hook/d48c2e4a-0ef9-4684-88d4-e62d878fdaca'; | 20 | + const url_warning_soft = 'https://open.feishu.cn/open-apis/bot/v2/hook/d48c2e4a-0ef9-4684-88d4-e62d878fdaca'; |
| 19 | //测试频道 | 21 | //测试频道 |
| 20 | const url_test = 'https://open.feishu.cn/open-apis/bot/v2/hook/34a9f127-3838-43fc-bc35-6f5e4e96bf6d'; | 22 | const url_test = 'https://open.feishu.cn/open-apis/bot/v2/hook/34a9f127-3838-43fc-bc35-6f5e4e96bf6d'; |
| 21 | //交易与跟单业务沟通 | 23 | //交易与跟单业务沟通 |
| @@ -24,31 +26,34 @@ class Feishu{ | @@ -24,31 +26,34 @@ class Feishu{ | ||
| 24 | const url_strategy = 'https://open.feishu.cn/open-apis/bot/v2/hook/53444f37-cfec-420c-a4e6-2f415b908dee'; | 26 | const url_strategy = 'https://open.feishu.cn/open-apis/bot/v2/hook/53444f37-cfec-420c-a4e6-2f415b908dee'; |
| 25 | //网格策略运营群 | 27 | //网格策略运营群 |
| 26 | const url_grid = 'https://open.feishu.cn/open-apis/bot/v2/hook/19471aa1-f926-46d7-a1d5-a367d1449092'; | 28 | const url_grid = 'https://open.feishu.cn/open-apis/bot/v2/hook/19471aa1-f926-46d7-a1d5-a367d1449092'; |
| 27 | - static public function notice($content,$channel_url,$users=[]) | 29 | + static public function notice($content, $channel_url, $users = []) |
| 28 | { | 30 | { |
| 29 | $userXml = ''; | 31 | $userXml = ''; |
| 30 | foreach ($users as $user) { | 32 | foreach ($users as $user) { |
| 31 | $userXml .= "<at user_id='" . $user . "'></at>"; | 33 | $userXml .= "<at user_id='" . $user . "'></at>"; |
| 32 | } | 34 | } |
| 33 | $content = [ | 35 | $content = [ |
| 34 | - 'msg_type'=>"text", | ||
| 35 | - 'content'=>[ | ||
| 36 | - 'text'=>$content.$userXml | 36 | + 'msg_type' => "text", |
| 37 | + 'content' => [ | ||
| 38 | + 'text' => $content . $userXml | ||
| 37 | ] | 39 | ] |
| 38 | ]; | 40 | ]; |
| 39 | $con = json_encode($content); | 41 | $con = json_encode($content); |
| 40 | - return self::send_post_json($channel_url,$con); | 42 | + return self::send_post_json($channel_url, $con); |
| 41 | } | 43 | } |
| 42 | static public function send_post_json($url, $jsonStr) | 44 | static public function send_post_json($url, $jsonStr) |
| 43 | { | 45 | { |
| 44 | $ch = curl_init(); | 46 | $ch = curl_init(); |
| 45 | curl_setopt($ch, CURLOPT_POST, 1); | 47 | curl_setopt($ch, CURLOPT_POST, 1); |
| 46 | - curl_setopt($ch,CURLOPT_SSL_VERIFYPEER,false); | ||
| 47 | - curl_setopt($ch,CURLOPT_SSL_VERIFYPEER,false); | 48 | + curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false); |
| 49 | + curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false); | ||
| 48 | curl_setopt($ch, CURLOPT_URL, $url); | 50 | curl_setopt($ch, CURLOPT_URL, $url); |
| 49 | curl_setopt($ch, CURLOPT_POSTFIELDS, $jsonStr); | 51 | curl_setopt($ch, CURLOPT_POSTFIELDS, $jsonStr); |
| 50 | curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); | 52 | curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); |
| 51 | - curl_setopt($ch, CURLOPT_HTTPHEADER, array( | 53 | + curl_setopt( |
| 54 | + $ch, | ||
| 55 | + CURLOPT_HTTPHEADER, | ||
| 56 | + array( | ||
| 52 | 'Content-Type: application/json; charset=utf-8', | 57 | 'Content-Type: application/json; charset=utf-8', |
| 53 | 'Content-Length: ' . strlen($jsonStr) | 58 | 'Content-Length: ' . strlen($jsonStr) |
| 54 | ) | 59 | ) |
| @@ -58,4 +63,4 @@ class Feishu{ | @@ -58,4 +63,4 @@ class Feishu{ | ||
| 58 | curl_close($ch); | 63 | curl_close($ch); |
| 59 | return array($httpCode, $response); | 64 | return array($httpCode, $response); |
| 60 | } | 65 | } |
| 61 | -} | ||
| 66 | +} |
| 1 | <?php | 1 | <?php |
| 2 | 2 | ||
| 3 | namespace jytools; | 3 | namespace jytools; |
| 4 | + | ||
| 4 | require_once __DIR__ . '/functions.php'; | 5 | require_once __DIR__ . '/functions.php'; |
| 5 | class Logger | 6 | class Logger |
| 6 | { | 7 | { |
| @@ -8,45 +9,52 @@ class Logger | @@ -8,45 +9,52 @@ class Logger | ||
| 8 | private bool $dateSlice; | 9 | private bool $dateSlice; |
| 9 | private array $types; | 10 | private array $types; |
| 10 | 11 | ||
| 11 | - public function __construct($logPath, $types = ['info','warning','error'], $dateSlice = false) | 12 | + public function __construct($logPath, $types = ['info', 'warning', 'error'], $dateSlice = false) |
| 12 | { | 13 | { |
| 13 | $this->logPath = $logPath; | 14 | $this->logPath = $logPath; |
| 14 | $this->dateSlice = $dateSlice; | 15 | $this->dateSlice = $dateSlice; |
| 15 | $this->types = $types; | 16 | $this->types = $types; |
| 16 | } | 17 | } |
| 17 | - public function debug($msg){ | ||
| 18 | - $this->log($msg,'debug'); | 18 | + public function debug($msg) |
| 19 | + { | ||
| 20 | + $this->log($msg, 'debug'); | ||
| 19 | } | 21 | } |
| 20 | - public function info($msg){ | ||
| 21 | - $this->log($msg,'info'); | 22 | + public function info($msg) |
| 23 | + { | ||
| 24 | + $this->log($msg, 'info'); | ||
| 22 | } | 25 | } |
| 23 | - public function warning($msg){ | ||
| 24 | - $this->log($msg,'warning'); | 26 | + public function warning($msg) |
| 27 | + { | ||
| 28 | + $this->log($msg, 'warning'); | ||
| 25 | } | 29 | } |
| 26 | - public function error($msg){ | ||
| 27 | - $this->log($msg,'error'); | 30 | + public function error($msg) |
| 31 | + { | ||
| 32 | + $this->log($msg, 'error'); | ||
| 28 | } | 33 | } |
| 29 | - private function log($msg, $type){ | ||
| 30 | - $msg = '['.timeFormat('ms').']['.$type.']:'.$msg.PHP_EOL; | 34 | + private function log($msg, $type) |
| 35 | + { | ||
| 36 | + $msg = '[' . timeFormat('ms') . '][' . $type . ']:' . $msg . PHP_EOL; | ||
| 31 | echo $msg; | 37 | echo $msg; |
| 32 | - if (!in_array($type,$this->types)){ | 38 | + if (!in_array($type, $this->types)) { |
| 33 | return; | 39 | return; |
| 34 | } | 40 | } |
| 35 | if ($this->dateSlice) { | 41 | if ($this->dateSlice) { |
| 36 | - $path = $this->logPath.'/'.date('Y-m-d'); | ||
| 37 | - }else{ | 42 | + $path = $this->logPath . '/' . date('Y-m-d'); |
| 43 | + } else { | ||
| 38 | $path = $this->logPath; | 44 | $path = $this->logPath; |
| 39 | } | 45 | } |
| 40 | - $file = $path.'/'.$type.'.log'; | ||
| 41 | - $this->save($file,$msg,$type); | 46 | + $file = $path . '/' . $type . '.log'; |
| 47 | + $this->save($file, $msg, $type); | ||
| 42 | } | 48 | } |
| 43 | - private function save($file,$msg, $type='info'){ | ||
| 44 | - \Swoole\Coroutine::create(function () use ($file,$msg,$type) { | 49 | + private function save($file, $msg, $type = 'info') |
| 50 | + { | ||
| 51 | + \Swoole\Coroutine::create(function () use ($file, $msg, $type) { | ||
| 45 | $this->checkFileDir($file); | 52 | $this->checkFileDir($file); |
| 46 | - file_put_contents($file,$msg,FILE_APPEND); | 53 | + file_put_contents($file, $msg, FILE_APPEND); |
| 47 | }); | 54 | }); |
| 48 | } | 55 | } |
| 49 | - private function checkFileDir($file){ | 56 | + private function checkFileDir($file) |
| 57 | + { | ||
| 50 | // 获取目录路径 | 58 | // 获取目录路径 |
| 51 | $directoryPath = dirname($file); | 59 | $directoryPath = dirname($file); |
| 52 | if (!is_dir($directoryPath)) { | 60 | if (!is_dir($directoryPath)) { |
| @@ -54,4 +62,4 @@ class Logger | @@ -54,4 +62,4 @@ class Logger | ||
| 54 | mkdir($directoryPath, 0755, true); | 62 | mkdir($directoryPath, 0755, true); |
| 55 | } | 63 | } |
| 56 | } | 64 | } |
| 57 | -} | ||
| 65 | +} |
| 1 | <?php | 1 | <?php |
| 2 | + | ||
| 2 | namespace jytools; | 3 | namespace jytools; |
| 3 | 4 | ||
| 4 | class MongoCli | 5 | class MongoCli |
| 5 | { | 6 | { |
| 6 | private $pool; | 7 | private $pool; |
| 7 | private $database; | 8 | private $database; |
| 8 | - public function __construct($host,$port,$username,$password,$database, $num = 20) | 9 | + public function __construct($host, $port, $username, $password, $database, $num = 20) |
| 9 | { | 10 | { |
| 10 | $this->database = $database; | 11 | $this->database = $database; |
| 11 | - $userInfo = $username?"{$username}:{$password}@":""; | 12 | + $userInfo = $username ? "{$username}:{$password}@" : ""; |
| 12 | $dsn = "mongodb://{$userInfo}{$host}:{$port}/{$database}"; | 13 | $dsn = "mongodb://{$userInfo}{$host}:{$port}/{$database}"; |
| 13 | - $this->pool = new MongoPool($dsn,$num); | 14 | + $this->pool = new MongoPool($dsn, $num); |
| 14 | } | 15 | } |
| 15 | 16 | ||
| 16 | /* | 17 | /* |
| 17 | * 创建集合 | 18 | * 创建集合 |
| 18 | */ | 19 | */ |
| 19 | - public function createCollection($table,$createIndex=[]){ | 20 | + public function createCollection($table, $createIndex = []) |
| 21 | + { | ||
| 20 | try { | 22 | try { |
| 21 | $mongodb = $this->pool->get(); | 23 | $mongodb = $this->pool->get(); |
| 22 | $database = $mongodb->selectDatabase($this->database); | 24 | $database = $mongodb->selectDatabase($this->database); |
| @@ -59,7 +61,7 @@ class MongoCli | @@ -59,7 +61,7 @@ class MongoCli | ||
| 59 | * 写入数据 | 61 | * 写入数据 |
| 60 | * $collection->insertOne(['name' => 'John Doe']); | 62 | * $collection->insertOne(['name' => 'John Doe']); |
| 61 | * */ | 63 | * */ |
| 62 | - public function insertOne($table,$data = []) | 64 | + public function insertOne($table, $data = []) |
| 63 | { | 65 | { |
| 64 | try { | 66 | try { |
| 65 | $mongodb = $this->pool->get(); | 67 | $mongodb = $this->pool->get(); |
| @@ -78,7 +80,7 @@ class MongoCli | @@ -78,7 +80,7 @@ class MongoCli | ||
| 78 | * 批量写入数据 | 80 | * 批量写入数据 |
| 79 | * $collection->insertMany([['name' => 'John Doe'],['name' => 'John Doe']]); | 81 | * $collection->insertMany([['name' => 'John Doe'],['name' => 'John Doe']]); |
| 80 | * */ | 82 | * */ |
| 81 | - public function insertAll($table,$data = []) | 83 | + public function insertAll($table, $data = []) |
| 82 | { | 84 | { |
| 83 | try { | 85 | try { |
| 84 | $mongodb = $this->pool->get(); | 86 | $mongodb = $this->pool->get(); |
| @@ -97,7 +99,7 @@ class MongoCli | @@ -97,7 +99,7 @@ class MongoCli | ||
| 97 | * 查询单条数据 | 99 | * 查询单条数据 |
| 98 | * $collection->findOne(['name' => 'John Doe']); | 100 | * $collection->findOne(['name' => 'John Doe']); |
| 99 | * */ | 101 | * */ |
| 100 | - public function findOne($table,$where = []) | 102 | + public function findOne($table, $where = []) |
| 101 | { | 103 | { |
| 102 | try { | 104 | try { |
| 103 | $mongodb = $this->pool->get(); | 105 | $mongodb = $this->pool->get(); |
| @@ -124,21 +126,21 @@ class MongoCli | @@ -124,21 +126,21 @@ class MongoCli | ||
| 124 | * 'limit' => 100, | 126 | * 'limit' => 100, |
| 125 | * ]; | 127 | * ]; |
| 126 | * */ | 128 | * */ |
| 127 | - public function findAll($table,$where = [], $options=[]) | 129 | + public function findAll($table, $where = [], $options = []) |
| 128 | { | 130 | { |
| 129 | try { | 131 | try { |
| 130 | $mongodb = $this->pool->get(); | 132 | $mongodb = $this->pool->get(); |
| 131 | $database = $mongodb->selectDatabase($this->database); | 133 | $database = $mongodb->selectDatabase($this->database); |
| 132 | $collection = $database->selectCollection($table); | 134 | $collection = $database->selectCollection($table); |
| 133 | - $result = $collection->find($where,$options); | 135 | + $result = $collection->find($where, $options); |
| 134 | $this->pool->push($mongodb); | 136 | $this->pool->push($mongodb); |
| 135 | // 遍历结果集 | 137 | // 遍历结果集 |
| 136 | $data = []; | 138 | $data = []; |
| 137 | - if ($result){ | ||
| 138 | - $arr = $result->toArray(); | 139 | + if ($result) { |
| 140 | + $arr = $result->toArray(); | ||
| 139 | foreach ($arr as $item) { | 141 | foreach ($arr as $item) { |
| 140 | $data[] = $item->getArrayCopy(); | 142 | $data[] = $item->getArrayCopy(); |
| 141 | - } | 143 | + } |
| 142 | return $data; | 144 | return $data; |
| 143 | } | 145 | } |
| 144 | return []; | 146 | return []; |
| @@ -152,13 +154,13 @@ class MongoCli | @@ -152,13 +154,13 @@ class MongoCli | ||
| 152 | * 更新数据 | 154 | * 更新数据 |
| 153 | * $collection->updateOne(['name' => 'John Doe'], ['$set' => ['age' => 31]]); | 155 | * $collection->updateOne(['name' => 'John Doe'], ['$set' => ['age' => 31]]); |
| 154 | * */ | 156 | * */ |
| 155 | - public function updateOne($table,$where = [],$upData = []) | 157 | + public function updateOne($table, $where = [], $upData = []) |
| 156 | { | 158 | { |
| 157 | try { | 159 | try { |
| 158 | $mongodb = $this->pool->get(); | 160 | $mongodb = $this->pool->get(); |
| 159 | $database = $mongodb->selectDatabase($this->database); | 161 | $database = $mongodb->selectDatabase($this->database); |
| 160 | $collection = $database->selectCollection($table); | 162 | $collection = $database->selectCollection($table); |
| 161 | - $result = $collection->updateOne($where,$upData); | 163 | + $result = $collection->updateOne($where, $upData); |
| 162 | $this->pool->push($mongodb); | 164 | $this->pool->push($mongodb); |
| 163 | return $result; | 165 | return $result; |
| 164 | } catch (\Exception $e) { | 166 | } catch (\Exception $e) { |
| @@ -171,7 +173,7 @@ class MongoCli | @@ -171,7 +173,7 @@ class MongoCli | ||
| 171 | * 删除数据 | 173 | * 删除数据 |
| 172 | * $collection->deleteOne(['name' => 'John Doe']); | 174 | * $collection->deleteOne(['name' => 'John Doe']); |
| 173 | * */ | 175 | * */ |
| 174 | - public function deleteOne($table,$where = []) | 176 | + public function deleteOne($table, $where = []) |
| 175 | { | 177 | { |
| 176 | try { | 178 | try { |
| 177 | $mongodb = $this->pool->get(); | 179 | $mongodb = $this->pool->get(); |
| @@ -190,7 +192,7 @@ class MongoCli | @@ -190,7 +192,7 @@ class MongoCli | ||
| 190 | * 批量删除数据 | 192 | * 批量删除数据 |
| 191 | * $collection->deleteMany(['name' => 'John Doe']); | 193 | * $collection->deleteMany(['name' => 'John Doe']); |
| 192 | * */ | 194 | * */ |
| 193 | - public function deleteBatch($table,$where = []) | 195 | + public function deleteBatch($table, $where = []) |
| 194 | { | 196 | { |
| 195 | try { | 197 | try { |
| 196 | $mongodb = $this->pool->get(); | 198 | $mongodb = $this->pool->get(); |
| @@ -204,5 +206,4 @@ class MongoCli | @@ -204,5 +206,4 @@ class MongoCli | ||
| 204 | return []; | 206 | return []; |
| 205 | } | 207 | } |
| 206 | } | 208 | } |
| 207 | - | ||
| 208 | -} | ||
| 209 | +} |
| 1 | <?php | 1 | <?php |
| 2 | + | ||
| 2 | namespace jytools; | 3 | namespace jytools; |
| 3 | 4 | ||
| 4 | use MongoDB\Client; | 5 | use MongoDB\Client; |
| @@ -13,7 +14,7 @@ class MongoPool | @@ -13,7 +14,7 @@ class MongoPool | ||
| 13 | private $mongoUri; | 14 | private $mongoUri; |
| 14 | private $options; | 15 | private $options; |
| 15 | 16 | ||
| 16 | - public function __construct($mongoUri, $maxSize=20, $options = []) | 17 | + public function __construct($mongoUri, $maxSize = 20, $options = []) |
| 17 | { | 18 | { |
| 18 | $this->mongoUri = $mongoUri; | 19 | $this->mongoUri = $mongoUri; |
| 19 | $this->maxSize = $maxSize; | 20 | $this->maxSize = $maxSize; |
| @@ -35,8 +36,8 @@ class MongoPool | @@ -35,8 +36,8 @@ class MongoPool | ||
| 35 | 36 | ||
| 36 | public function get() | 37 | public function get() |
| 37 | { | 38 | { |
| 38 | - while ($this->pool->isEmpty()){ | ||
| 39 | -// output('Mongodb连接池为空,等待释放连接'); | 39 | + while ($this->pool->isEmpty()) { |
| 40 | + // output('Mongodb连接池为空,等待释放连接'); | ||
| 40 | Coroutine::sleep(0.1); | 41 | Coroutine::sleep(0.1); |
| 41 | } | 42 | } |
| 42 | $connection = $this->pool->pop(); | 43 | $connection = $this->pool->pop(); |
| @@ -58,7 +59,7 @@ class MongoPool | @@ -58,7 +59,7 @@ class MongoPool | ||
| 58 | // 检查连接是否有效,这里仅做示例,实际应用中可能需要更复杂的逻辑 | 59 | // 检查连接是否有效,这里仅做示例,实际应用中可能需要更复杂的逻辑 |
| 59 | if (is_object($connection) && get_class($connection) === Client::class) { | 60 | if (is_object($connection) && get_class($connection) === Client::class) { |
| 60 | $this->pool->push($connection); | 61 | $this->pool->push($connection); |
| 61 | - }else{ | 62 | + } else { |
| 62 | $this->currentSize -= 1; | 63 | $this->currentSize -= 1; |
| 63 | } | 64 | } |
| 64 | } | 65 | } |
| @@ -73,4 +74,4 @@ class MongoPool | @@ -73,4 +74,4 @@ class MongoPool | ||
| 73 | } | 74 | } |
| 74 | $this->currentSize = 0; | 75 | $this->currentSize = 0; |
| 75 | } | 76 | } |
| 76 | -} | ||
| 77 | +} |
| @@ -9,7 +9,7 @@ class MysqlCli | @@ -9,7 +9,7 @@ class MysqlCli | ||
| 9 | { | 9 | { |
| 10 | 10 | ||
| 11 | private $pool = null; | 11 | private $pool = null; |
| 12 | - private $prefix = '';// 前缀 | 12 | + private $prefix = ''; // 前缀 |
| 13 | 13 | ||
| 14 | private int $reconnectCount = 0; //period时间内重连次数 | 14 | private int $reconnectCount = 0; //period时间内重连次数 |
| 15 | private int $period = 300; | 15 | private int $period = 300; |
| @@ -40,13 +40,13 @@ class MysqlCli | @@ -40,13 +40,13 @@ class MysqlCli | ||
| 40 | $this->pool->close(); | 40 | $this->pool->close(); |
| 41 | } | 41 | } |
| 42 | $this->pool = new MysqliPool((new MysqliConfig) | 42 | $this->pool = new MysqliPool((new MysqliConfig) |
| 43 | - ->withHost($this->connectConfig['host']) | ||
| 44 | - ->withPort($this->connectConfig['port']) | ||
| 45 | - ->withDbName($this->connectConfig['database']) | ||
| 46 | - ->withCharset($this->connectConfig['charset']) | ||
| 47 | - ->withUsername($this->connectConfig['username']) | ||
| 48 | - ->withPassword($this->connectConfig['password']) | ||
| 49 | - , $this->connectConfig['connectCount'] | 43 | + ->withHost($this->connectConfig['host']) |
| 44 | + ->withPort($this->connectConfig['port']) | ||
| 45 | + ->withDbName($this->connectConfig['database']) | ||
| 46 | + ->withCharset($this->connectConfig['charset']) | ||
| 47 | + ->withUsername($this->connectConfig['username']) | ||
| 48 | + ->withPassword($this->connectConfig['password']), | ||
| 49 | + $this->connectConfig['connectCount'] | ||
| 50 | ); | 50 | ); |
| 51 | $this->prefix = $this->connectConfig['prefix']; | 51 | $this->prefix = $this->connectConfig['prefix']; |
| 52 | } | 52 | } |
| @@ -273,5 +273,4 @@ class MysqlCli | @@ -273,5 +273,4 @@ class MysqlCli | ||
| 273 | } | 273 | } |
| 274 | return $valueNew; | 274 | return $valueNew; |
| 275 | } | 275 | } |
| 276 | - | ||
| 277 | -} | ||
| 276 | +} |
| 1 | <?php | 1 | <?php |
| 2 | + | ||
| 2 | namespace jytools; | 3 | namespace jytools; |
| 3 | 4 | ||
| 4 | /* | 5 | /* |
| 5 | 所有接口 | 6 | 所有接口 |
| 6 | */ | 7 | */ |
| 8 | + | ||
| 7 | class OkApi | 9 | class OkApi |
| 8 | { | 10 | { |
| 9 | protected string $host = 'https://www.okx.com'; | 11 | protected string $host = 'https://www.okx.com'; |
| @@ -78,9 +80,9 @@ class OkApi | @@ -78,9 +80,9 @@ class OkApi | ||
| 78 | ]); | 80 | ]); |
| 79 | } | 81 | } |
| 80 | 82 | ||
| 81 | - $headers_array=[]; | ||
| 82 | - foreach ($headers as $key => $value){ | ||
| 83 | - $headers_array[]=$key.':'.$value; | 83 | + $headers_array = []; |
| 84 | + foreach ($headers as $key => $value) { | ||
| 85 | + $headers_array[] = $key . ':' . $value; | ||
| 84 | } | 86 | } |
| 85 | $this->headers = $headers_array; | 87 | $this->headers = $headers_array; |
| 86 | return $headers; | 88 | return $headers; |
| @@ -90,14 +92,14 @@ class OkApi | @@ -90,14 +92,14 @@ class OkApi | ||
| 90 | * 公共请求接口 | 92 | * 公共请求接口 |
| 91 | * $type 1: 需鉴权 2: 不需鉴权 | 93 | * $type 1: 需鉴权 2: 不需鉴权 |
| 92 | * */ | 94 | * */ |
| 93 | - public function request($method, $path, $param,$type=1) | 95 | + public function request($method, $path, $param, $type = 1) |
| 94 | { | 96 | { |
| 95 | $this->method = strtoupper($method); | 97 | $this->method = strtoupper($method); |
| 96 | $this->path = $path; | 98 | $this->path = $path; |
| 97 | $this->param = $param; | 99 | $this->param = $param; |
| 98 | - if($type==2){ | 100 | + if ($type == 2) { |
| 99 | $this->createHeaders(); | 101 | $this->createHeaders(); |
| 100 | - }else{ | 102 | + } else { |
| 101 | if (empty($this->apikey) || empty($this->secret) || empty($this->apipwd)) { | 103 | if (empty($this->apikey) || empty($this->secret) || empty($this->apipwd)) { |
| 102 | return ['code' => -1, 'msg' => 'apikey, secret or apipwd is empty']; | 104 | return ['code' => -1, 'msg' => 'apikey, secret or apipwd is empty']; |
| 103 | } | 105 | } |
| @@ -125,7 +127,7 @@ class OkApi | @@ -125,7 +127,7 @@ class OkApi | ||
| 125 | /** | 127 | /** |
| 126 | * 合约账户余额查询 | 128 | * 合约账户余额查询 |
| 127 | */ | 129 | */ |
| 128 | - public function getBalance($param=[]) | 130 | + public function getBalance($param = []) |
| 129 | { | 131 | { |
| 130 | $path = '/api/v5/account/balance'; | 132 | $path = '/api/v5/account/balance'; |
| 131 | return $this->request('GET', $path, $param); | 133 | return $this->request('GET', $path, $param); |
| @@ -133,7 +135,7 @@ class OkApi | @@ -133,7 +135,7 @@ class OkApi | ||
| 133 | /** | 135 | /** |
| 134 | * 资金账户余额查询 | 136 | * 资金账户余额查询 |
| 135 | */ | 137 | */ |
| 136 | - public function getAssetBalance($param=[]) | 138 | + public function getAssetBalance($param = []) |
| 137 | { | 139 | { |
| 138 | $path = '/api/v5/asset/balances'; | 140 | $path = '/api/v5/asset/balances'; |
| 139 | return $this->request('GET', $path, $param); | 141 | return $this->request('GET', $path, $param); |
| @@ -158,10 +160,9 @@ class OkApi | @@ -158,10 +160,9 @@ class OkApi | ||
| 158 | /* | 160 | /* |
| 159 | * 公共请求接口 | 161 | * 公共请求接口 |
| 160 | * */ | 162 | * */ |
| 161 | - public function getTransferHistory($path,$param) | 163 | + public function getTransferHistory($path, $param) |
| 162 | { | 164 | { |
| 163 | $path = '/api/v5/asset/bills'; | 165 | $path = '/api/v5/asset/bills'; |
| 164 | return $this->request('GET', $path, $param); | 166 | return $this->request('GET', $path, $param); |
| 165 | } | 167 | } |
| 166 | - | ||
| 167 | } | 168 | } |
| 1 | <?php | 1 | <?php |
| 2 | + | ||
| 2 | namespace jytools; | 3 | namespace jytools; |
| 3 | 4 | ||
| 4 | use Swoole\Database\RedisConfig; | 5 | use Swoole\Database\RedisConfig; |
| @@ -8,21 +9,22 @@ class RedisCli | @@ -8,21 +9,22 @@ class RedisCli | ||
| 8 | { | 9 | { |
| 9 | private $pool; | 10 | private $pool; |
| 10 | public $subRedis = null; | 11 | public $subRedis = null; |
| 11 | - public function __construct($host,$port,$password,$dbIndex, $num = 20) | 12 | + public function __construct($host, $port, $password, $dbIndex, $num = 20) |
| 12 | { | 13 | { |
| 13 | $this->pool = new RedisPool((new RedisConfig) | 14 | $this->pool = new RedisPool((new RedisConfig) |
| 14 | - ->withHost($host) | ||
| 15 | - ->withPort($port) | ||
| 16 | - ->withAuth($password) | ||
| 17 | - ->withDbIndex($dbIndex) | ||
| 18 | - ,$num //默认64个连接池 | 15 | + ->withHost($host) |
| 16 | + ->withPort($port) | ||
| 17 | + ->withAuth($password) | ||
| 18 | + ->withDbIndex($dbIndex), | ||
| 19 | + $num //默认64个连接池 | ||
| 19 | ); | 20 | ); |
| 20 | } | 21 | } |
| 21 | //集合存数据 | 22 | //集合存数据 |
| 22 | - public function sAdd($key,$member){ | 23 | + public function sAdd($key, $member) |
| 24 | + { | ||
| 23 | $redis = $this->pool->get(); | 25 | $redis = $this->pool->get(); |
| 24 | try { | 26 | try { |
| 25 | - $res = $redis->sAdd($key,$member); | 27 | + $res = $redis->sAdd($key, $member); |
| 26 | } catch (\RedisException $e) { | 28 | } catch (\RedisException $e) { |
| 27 | return false; | 29 | return false; |
| 28 | } | 30 | } |
| @@ -31,7 +33,8 @@ class RedisCli | @@ -31,7 +33,8 @@ class RedisCli | ||
| 31 | } | 33 | } |
| 32 | 34 | ||
| 33 | //获取集合 | 35 | //获取集合 |
| 34 | - public function sMembers($key){ | 36 | + public function sMembers($key) |
| 37 | + { | ||
| 35 | $redis = $this->pool->get(); | 38 | $redis = $this->pool->get(); |
| 36 | try { | 39 | try { |
| 37 | $res = $redis->sMembers($key); | 40 | $res = $redis->sMembers($key); |
| @@ -43,11 +46,12 @@ class RedisCli | @@ -43,11 +46,12 @@ class RedisCli | ||
| 43 | } | 46 | } |
| 44 | 47 | ||
| 45 | //移除集合成员 | 48 | //移除集合成员 |
| 46 | - public function sRem($key,$member){ | 49 | + public function sRem($key, $member) |
| 50 | + { | ||
| 47 | $redis = $this->pool->get(); | 51 | $redis = $this->pool->get(); |
| 48 | try { | 52 | try { |
| 49 | - $res = $redis->sRem($key,$member); | ||
| 50 | - }catch (\RedisException $e){ | 53 | + $res = $redis->sRem($key, $member); |
| 54 | + } catch (\RedisException $e) { | ||
| 51 | return false; | 55 | return false; |
| 52 | } | 56 | } |
| 53 | 57 | ||
| @@ -56,7 +60,8 @@ class RedisCli | @@ -56,7 +60,8 @@ class RedisCli | ||
| 56 | } | 60 | } |
| 57 | 61 | ||
| 58 | //哈希 键 字段 值 设置 | 62 | //哈希 键 字段 值 设置 |
| 59 | - public function hSet($key,$field,$value){ | 63 | + public function hSet($key, $field, $value) |
| 64 | + { | ||
| 60 | $redis = $this->pool->get(); | 65 | $redis = $this->pool->get(); |
| 61 | try { | 66 | try { |
| 62 | $res = $redis->hSet($key, $field, $value); | 67 | $res = $redis->hSet($key, $field, $value); |
| @@ -67,7 +72,8 @@ class RedisCli | @@ -67,7 +72,8 @@ class RedisCli | ||
| 67 | return $res; | 72 | return $res; |
| 68 | } | 73 | } |
| 69 | //获取 键对应字段的值 | 74 | //获取 键对应字段的值 |
| 70 | - public function hGet($key,$field){ | 75 | + public function hGet($key, $field) |
| 76 | + { | ||
| 71 | $redis = $this->pool->get(); | 77 | $redis = $this->pool->get(); |
| 72 | try { | 78 | try { |
| 73 | $res = $redis->hGet($key, $field); | 79 | $res = $redis->hGet($key, $field); |
| @@ -78,7 +84,8 @@ class RedisCli | @@ -78,7 +84,8 @@ class RedisCli | ||
| 78 | return $res; | 84 | return $res; |
| 79 | } | 85 | } |
| 80 | //获取键所有字段和值 | 86 | //获取键所有字段和值 |
| 81 | - public function hGetAll($key){ | 87 | + public function hGetAll($key) |
| 88 | + { | ||
| 82 | $redis = $this->pool->get(); | 89 | $redis = $this->pool->get(); |
| 83 | try { | 90 | try { |
| 84 | $res = $redis->hGetAll($key); | 91 | $res = $redis->hGetAll($key); |
| @@ -89,7 +96,8 @@ class RedisCli | @@ -89,7 +96,8 @@ class RedisCli | ||
| 89 | return $res; | 96 | return $res; |
| 90 | } | 97 | } |
| 91 | //删除一个值 | 98 | //删除一个值 |
| 92 | - public function hDel($key,$field){ | 99 | + public function hDel($key, $field) |
| 100 | + { | ||
| 93 | $redis = $this->pool->get(); | 101 | $redis = $this->pool->get(); |
| 94 | try { | 102 | try { |
| 95 | $res = $redis->hDel($key, $field); | 103 | $res = $redis->hDel($key, $field); |
| @@ -104,7 +112,8 @@ class RedisCli | @@ -104,7 +112,8 @@ class RedisCli | ||
| 104 | * 发布订阅等 | 112 | * 发布订阅等 |
| 105 | */ | 113 | */ |
| 106 | //将信息发送到指定的频道 | 114 | //将信息发送到指定的频道 |
| 107 | - public function publish($channel,$message){ | 115 | + public function publish($channel, $message) |
| 116 | + { | ||
| 108 | $redis = $this->pool->get(); | 117 | $redis = $this->pool->get(); |
| 109 | try { | 118 | try { |
| 110 | $res = $redis->publish($channel, $message); | 119 | $res = $redis->publish($channel, $message); |
| @@ -115,13 +124,13 @@ class RedisCli | @@ -115,13 +124,13 @@ class RedisCli | ||
| 115 | return $res; | 124 | return $res; |
| 116 | } | 125 | } |
| 117 | 126 | ||
| 118 | - public function subscribe($channels,callable $onMessage) | 127 | + public function subscribe($channels, callable $onMessage) |
| 119 | { | 128 | { |
| 120 | $redis = $this->pool->get(); | 129 | $redis = $this->pool->get(); |
| 121 | $this->subRedis = $redis; | 130 | $this->subRedis = $redis; |
| 122 | try { | 131 | try { |
| 123 | - $res = $redis->subscribe($channels,function($redis, $channel, $message)use($onMessage){ | ||
| 124 | - call_user_func($onMessage,$redis, $channel, $message); | 132 | + $res = $redis->subscribe($channels, function ($redis, $channel, $message) use ($onMessage) { |
| 133 | + call_user_func($onMessage, $redis, $channel, $message); | ||
| 125 | }); | 134 | }); |
| 126 | } catch (\RedisException $e) { | 135 | } catch (\RedisException $e) { |
| 127 | return false; | 136 | return false; |
| @@ -131,20 +140,19 @@ class RedisCli | @@ -131,20 +140,19 @@ class RedisCli | ||
| 131 | return $res; | 140 | return $res; |
| 132 | } | 141 | } |
| 133 | 142 | ||
| 134 | - public function psubscribe($channels,callable $onMessage) | 143 | + public function psubscribe($channels, callable $onMessage) |
| 135 | { | 144 | { |
| 136 | $redis = $this->pool->get(); | 145 | $redis = $this->pool->get(); |
| 137 | $this->subRedis = $redis; | 146 | $this->subRedis = $redis; |
| 138 | try { | 147 | try { |
| 139 | - $res = $redis->psubscribe($channels,function($redis, $pattern, $channel, $message)use($onMessage){ | 148 | + $res = $redis->psubscribe($channels, function ($redis, $pattern, $channel, $message) use ($onMessage) { |
| 140 | call_user_func($onMessage, $pattern, $redis, $channel, $message); | 149 | call_user_func($onMessage, $pattern, $redis, $channel, $message); |
| 141 | }); | 150 | }); |
| 142 | - }catch (\RedisException $e) { | 151 | + } catch (\RedisException $e) { |
| 143 | return false; | 152 | return false; |
| 144 | } | 153 | } |
| 145 | $this->subRedis = null; | 154 | $this->subRedis = null; |
| 146 | $this->pool->put($redis); | 155 | $this->pool->put($redis); |
| 147 | return $res; | 156 | return $res; |
| 148 | } | 157 | } |
| 149 | - | ||
| 150 | -} | ||
| 158 | +} |
| 1 | <?php | 1 | <?php |
| 2 | + | ||
| 2 | namespace jytools; | 3 | namespace jytools; |
| 4 | + | ||
| 3 | use Swoole\Http\Request; | 5 | use Swoole\Http\Request; |
| 4 | use Swoole\Http\Response; | 6 | use Swoole\Http\Response; |
| 5 | use Swoole\Http\Server; | 7 | use Swoole\Http\Server; |
| @@ -11,8 +13,9 @@ class SimpleServer | @@ -11,8 +13,9 @@ class SimpleServer | ||
| 11 | { | 13 | { |
| 12 | $this->httpServer = new Server($host, $port); | 14 | $this->httpServer = new Server($host, $port); |
| 13 | } | 15 | } |
| 14 | - public function router($url, $callback){ | ||
| 15 | - $this->httpServer->on('Request', function (Request $request, Response $response) use ($url, $callback){ | 16 | + public function router($url, $callback) |
| 17 | + { | ||
| 18 | + $this->httpServer->on('Request', function (Request $request, Response $response) use ($url, $callback) { | ||
| 16 | $requestInfo = [ | 19 | $requestInfo = [ |
| 17 | 'path' => $request->server['path_info'], | 20 | 'path' => $request->server['path_info'], |
| 18 | 'uri' => $request->server['request_uri'], | 21 | 'uri' => $request->server['request_uri'], |
| @@ -27,11 +30,11 @@ class SimpleServer | @@ -27,11 +30,11 @@ class SimpleServer | ||
| 27 | $response->end(); | 30 | $response->end(); |
| 28 | return; | 31 | return; |
| 29 | } | 32 | } |
| 30 | - if($url == $simpleRequest->uri){ | 33 | + if ($url == $simpleRequest->uri) { |
| 31 | $res = call_user_func($callback, $simpleRequest); | 34 | $res = call_user_func($callback, $simpleRequest); |
| 32 | - if(!$res){ | 35 | + if (!$res) { |
| 33 | $response->end(); | 36 | $response->end(); |
| 34 | - }else{ | 37 | + } else { |
| 35 | $response->end($res); | 38 | $response->end($res); |
| 36 | } | 39 | } |
| 37 | return; | 40 | return; |
| @@ -40,8 +43,8 @@ class SimpleServer | @@ -40,8 +43,8 @@ class SimpleServer | ||
| 40 | }); | 43 | }); |
| 41 | } | 44 | } |
| 42 | 45 | ||
| 43 | - public function start(){ | 46 | + public function start() |
| 47 | + { | ||
| 44 | $this->httpServer->start(); | 48 | $this->httpServer->start(); |
| 45 | } | 49 | } |
| 46 | } | 50 | } |
| 47 | - |
| 1 | <?php | 1 | <?php |
| 2 | + | ||
| 2 | namespace jytools; | 3 | namespace jytools; |
| 4 | + | ||
| 3 | use Swoole\Http\Request; | 5 | use Swoole\Http\Request; |
| 4 | use Swoole\Http\Response; | 6 | use Swoole\Http\Response; |
| 5 | use Swoole\Coroutine\Http\Server; | 7 | use Swoole\Coroutine\Http\Server; |
| @@ -11,10 +13,11 @@ class SimpleServerCoroutine | @@ -11,10 +13,11 @@ class SimpleServerCoroutine | ||
| 11 | { | 13 | { |
| 12 | $this->httpServer = new Server($host, $port, $ssl); | 14 | $this->httpServer = new Server($host, $port, $ssl); |
| 13 | } | 15 | } |
| 14 | - public function router($method, $path, $callback){ | ||
| 15 | - $this->httpServer->handle($path, function (Request $request, Response $response) use ($method,$callback) { | 16 | + public function router($method, $path, $callback) |
| 17 | + { | ||
| 18 | + $this->httpServer->handle($path, function (Request $request, Response $response) use ($method, $callback) { | ||
| 16 | $m = $request->getMethod(); | 19 | $m = $request->getMethod(); |
| 17 | - if(!in_array($m,$method)){ | 20 | + if (!in_array($m, $method)) { |
| 18 | $response->status(405); | 21 | $response->status(405); |
| 19 | $response->end(); | 22 | $response->end(); |
| 20 | return; | 23 | return; |
| @@ -30,16 +33,16 @@ class SimpleServerCoroutine | @@ -30,16 +33,16 @@ class SimpleServerCoroutine | ||
| 30 | ]; | 33 | ]; |
| 31 | $simpleRequest = new SimpleRequest($requestInfo); | 34 | $simpleRequest = new SimpleRequest($requestInfo); |
| 32 | $res = call_user_func($callback, $simpleRequest); | 35 | $res = call_user_func($callback, $simpleRequest); |
| 33 | - if(empty($res)){ | ||
| 34 | - $response->end(json_encode(['code'=>-1,'msg'=>'nothing return'])); | ||
| 35 | - }else{ | 36 | + if (empty($res)) { |
| 37 | + $response->end(json_encode(['code' => -1, 'msg' => 'nothing return'])); | ||
| 38 | + } else { | ||
| 36 | $response->end($res); | 39 | $response->end($res); |
| 37 | } | 40 | } |
| 38 | }); | 41 | }); |
| 39 | } | 42 | } |
| 40 | 43 | ||
| 41 | - public function start(){ | 44 | + public function start() |
| 45 | + { | ||
| 42 | $this->httpServer->start(); | 46 | $this->httpServer->start(); |
| 43 | } | 47 | } |
| 44 | } | 48 | } |
| 45 | - |
| 1 | <?php | 1 | <?php |
| 2 | + | ||
| 2 | namespace jytools; | 3 | namespace jytools; |
| 3 | //格式化输出 | 4 | //格式化输出 |
| 4 | use Swoole\Process; | 5 | use Swoole\Process; |
| @@ -7,25 +8,25 @@ use Swoole\Event; | @@ -7,25 +8,25 @@ use Swoole\Event; | ||
| 7 | function output(): void | 8 | function output(): void |
| 8 | { | 9 | { |
| 9 | $args = func_get_args(); | 10 | $args = func_get_args(); |
| 10 | - $outStr = '['.timeFormat('ms').']:'; | ||
| 11 | - foreach($args as $key => $value){ | 11 | + $outStr = '[' . timeFormat('ms') . ']:'; |
| 12 | + foreach ($args as $key => $value) { | ||
| 12 | $value = is_array($value) ? json_encode($value) : $value; | 13 | $value = is_array($value) ? json_encode($value) : $value; |
| 13 | - if(is_bool($value)){ | ||
| 14 | - $value = $value ? 'bool:true':'bool:false'; | 14 | + if (is_bool($value)) { |
| 15 | + $value = $value ? 'bool:true' : 'bool:false'; | ||
| 15 | } | 16 | } |
| 16 | - $outStr .= count($args) - $key > 1 ? $value.' ' : $value; | 17 | + $outStr .= count($args) - $key > 1 ? $value . ' ' : $value; |
| 17 | } | 18 | } |
| 18 | - echo $outStr.PHP_EOL; | 19 | + echo $outStr . PHP_EOL; |
| 19 | } | 20 | } |
| 20 | //格式化时间 | 21 | //格式化时间 |
| 21 | -function timeFormat($type='s',$format='Y-m-d H:i:s'): string | 22 | +function timeFormat($type = 's', $format = 'Y-m-d H:i:s'): string |
| 22 | { | 23 | { |
| 23 | date_default_timezone_set('Asia/Shanghai'); | 24 | date_default_timezone_set('Asia/Shanghai'); |
| 24 | $microTime = microtime(); | 25 | $microTime = microtime(); |
| 25 | - list($msTime,$sTime) = explode(' ',$microTime); | ||
| 26 | - $timeStr = date($format,$sTime); | ||
| 27 | - if($type == 'ms'){ | ||
| 28 | - $timeStr .= '.'.sprintf("%03d",floor($msTime*1000)); | 26 | + list($msTime, $sTime) = explode(' ', $microTime); |
| 27 | + $timeStr = date($format, $sTime); | ||
| 28 | + if ($type == 'ms') { | ||
| 29 | + $timeStr .= '.' . sprintf("%03d", floor($msTime * 1000)); | ||
| 29 | } | 30 | } |
| 30 | return $timeStr; | 31 | return $timeStr; |
| 31 | } | 32 | } |
| @@ -34,55 +35,88 @@ function timeFormat($type='s',$format='Y-m-d H:i:s'): string | @@ -34,55 +35,88 @@ function timeFormat($type='s',$format='Y-m-d H:i:s'): string | ||
| 34 | function getMicrotime(): float|int | 35 | function getMicrotime(): float|int |
| 35 | { | 36 | { |
| 36 | list($uSec, $sec) = explode(' ', microtime()); | 37 | list($uSec, $sec) = explode(' ', microtime()); |
| 37 | - return $sec*1000+round($uSec*1000); | 38 | + return $sec * 1000 + round($uSec * 1000); |
| 38 | } | 39 | } |
| 39 | 40 | ||
| 40 | //获取精度 | 41 | //获取精度 |
| 41 | function getPrecision($number): int | 42 | function getPrecision($number): int |
| 42 | { | 43 | { |
| 43 | $count = 0; | 44 | $count = 0; |
| 44 | - while($number < 1){ | 45 | + while ($number < 1) { |
| 45 | $number *= 10; | 46 | $number *= 10; |
| 46 | $count += 1; | 47 | $count += 1; |
| 47 | } | 48 | } |
| 48 | return $count; | 49 | return $count; |
| 49 | } | 50 | } |
| 50 | 51 | ||
| 51 | -function getIntervalUnit($interval,$type='s'): float|int | 52 | +function getIntervalUnit($interval, $type = 's'): float|int |
| 52 | { | 53 | { |
| 53 | $unitTime = 0; | 54 | $unitTime = 0; |
| 54 | - if($interval == '1m'){ | 55 | + if ($interval == '1m') { |
| 55 | $unitTime = 60; | 56 | $unitTime = 60; |
| 56 | } | 57 | } |
| 57 | - if($interval == '5m'){ | ||
| 58 | - $unitTime = 60*5; | 58 | + if ($interval == '5m') { |
| 59 | + $unitTime = 60 * 5; | ||
| 60 | + } | ||
| 61 | + if ($interval == '15m') { | ||
| 62 | + $unitTime = 60 * 15; | ||
| 63 | + } | ||
| 64 | + if ($interval == '1h') { | ||
| 65 | + $unitTime = 60 * 60; | ||
| 59 | } | 66 | } |
| 60 | - if($interval == '15m'){ | ||
| 61 | - $unitTime = 60*15; | 67 | + if ($interval == '4h') { |
| 68 | + $unitTime = 60 * 60 * 4; | ||
| 62 | } | 69 | } |
| 63 | - if($interval == '1h'){ | ||
| 64 | - $unitTime = 60*60; | 70 | + if ($interval == '1d') { |
| 71 | + $unitTime = 60 * 60 * 24; | ||
| 72 | + } | ||
| 73 | + return $type == 's' ? $unitTime : $unitTime * 1000; | ||
| 74 | +} | ||
| 75 | + | ||
| 76 | +//科学计数法转数字 | ||
| 77 | +function scToNum($scStr) | ||
| 78 | +{ | ||
| 79 | + $check_str = ''; | ||
| 80 | + if (strpos($scStr, 'e') !== false) { | ||
| 81 | + $check_str = 'e'; | ||
| 65 | } | 82 | } |
| 66 | - if($interval == '4h'){ | ||
| 67 | - $unitTime = 60*60*4; | 83 | + if (strpos($scStr, 'E') !== false) { |
| 84 | + $check_str = 'E'; | ||
| 68 | } | 85 | } |
| 69 | - if($interval == '1d'){ | ||
| 70 | - $unitTime = 60*60*24; | 86 | + if (empty($check_str)) { |
| 87 | + return $scStr; //非科学计数直接返回。 | ||
| 71 | } | 88 | } |
| 72 | - return $type == 's' ? $unitTime : $unitTime*1000; | 89 | + $num_length = 0; |
| 90 | + $split_array = explode($check_str, $scStr); | ||
| 91 | + $num_length += strlen($split_array[0]); | ||
| 92 | + $num_length += (int)str_replace(['-', '+'], '', $split_array[1]); | ||
| 93 | + $float_number = (float)$scStr; | ||
| 94 | + $decimal_string = number_format($float_number, $num_length, '.', ''); | ||
| 95 | + $num = rtrim(rtrim($decimal_string, '0'), '.'); //去除小数后多余的0 | ||
| 96 | + return $num; | ||
| 73 | } | 97 | } |
| 98 | +//时间戳转ISO8601 | ||
| 99 | +function tsToISO($timestamp) | ||
| 100 | +{ | ||
| 101 | + $datetime = new \DateTime(); | ||
| 102 | + $datetime->setTimestamp(floor($timestamp / 1000)); | ||
| 103 | + $datetime->setTimezone(new \DateTimeZone('UTC')); | ||
| 104 | + $milliseconds = sprintf('.%03d', $timestamp % 1000); | ||
| 105 | + return $datetime->format('Y-m-d\TH:i:s') . $milliseconds . 'Z'; | ||
| 106 | +} | ||
| 107 | + | ||
| 74 | 108 | ||
| 75 | //以守护进程运行 | 109 | //以守护进程运行 |
| 76 | -function runAsDaemon($callback,$isDaemon=true): void | 110 | +function runAsDaemon($callback, $isDaemon = true): void |
| 77 | { | 111 | { |
| 78 | - if($isDaemon){ | 112 | + if ($isDaemon) { |
| 79 | Process::daemon(); | 113 | Process::daemon(); |
| 80 | - $process = new Process(function ()use ($callback){ | 114 | + $process = new Process(function () use ($callback) { |
| 81 | call_user_func($callback); | 115 | call_user_func($callback); |
| 82 | Event::wait(); | 116 | Event::wait(); |
| 83 | }); | 117 | }); |
| 84 | $process->start(); | 118 | $process->start(); |
| 85 | - }else{ | 119 | + } else { |
| 86 | call_user_func($callback); | 120 | call_user_func($callback); |
| 87 | Event::wait(); | 121 | Event::wait(); |
| 88 | } | 122 | } |
jytools/load.php
0 → 100644
| 1 | +<?php | ||
| 2 | +require_once __DIR__ . '/Auth.php'; | ||
| 3 | +require_once __DIR__ . '/BinanceFutures.php'; | ||
| 4 | +require_once __DIR__ . '/BinanceSpot.php'; | ||
| 5 | +require_once __DIR__ . '/Curl.php'; | ||
| 6 | +require_once __DIR__ . '/FeiShu.php'; | ||
| 7 | +require_once __DIR__ . '/functions.php'; | ||
| 8 | +require_once __DIR__ . '/KlineAssist.php'; | ||
| 9 | +require_once __DIR__ . '/Logger.php'; | ||
| 10 | +require_once __DIR__ . '/MongoCli.php'; | ||
| 11 | +require_once __DIR__ . '/MongoPool.php'; | ||
| 12 | +require_once __DIR__ . '/MysqlCli.php'; | ||
| 13 | +require_once __DIR__ . '/OkApi.php'; | ||
| 14 | +require_once __DIR__ . '/RedisCli.php'; | ||
| 15 | +require_once __DIR__ . '/SimpleRequest.php'; | ||
| 16 | +require_once __DIR__ . '/SimpleServer.php'; | ||
| 17 | +require_once __DIR__ . '/SimpleServerCoroutine.php'; | ||
| 18 | +require_once __DIR__ . '/Websocket.php'; |
| @@ -2,8 +2,7 @@ | @@ -2,8 +2,7 @@ | ||
| 2 | 2 | ||
| 3 | namespace trader; | 3 | namespace trader; |
| 4 | 4 | ||
| 5 | -require_once __DIR__ . '/autoload.php'; | ||
| 6 | -require_once __DIR__ . '/../vendor/autoload.php'; | 5 | +require_once __DIR__ . '/load.php'; |
| 7 | 6 | ||
| 8 | use trader\struct\ApiInfo; | 7 | use trader\struct\ApiInfo; |
| 9 | use trader\okx\ExBroker as OkxBroker; | 8 | use trader\okx\ExBroker as OkxBroker; |
| @@ -17,7 +16,7 @@ use trader\struct\SymbolInfo; | @@ -17,7 +16,7 @@ use trader\struct\SymbolInfo; | ||
| 17 | use trader\struct\WsDataOrder; | 16 | use trader\struct\WsDataOrder; |
| 18 | use trader\struct\Pos; | 17 | use trader\struct\Pos; |
| 19 | use \Exception; | 18 | use \Exception; |
| 20 | -use function Jiaoyin\timeFormat; | 19 | +use function jytools\timeFormat; |
| 21 | use trader\okx\Api as OkApi; | 20 | use trader\okx\Api as OkApi; |
| 22 | 21 | ||
| 23 | class CmBroker | 22 | class CmBroker |
trader/common/func.php
已删除
100644 → 0
| 1 | -<?php | ||
| 2 | - | ||
| 3 | -namespace trader; | ||
| 4 | - | ||
| 5 | - | ||
| 6 | -function scToNum($scStr) | ||
| 7 | -{ | ||
| 8 | - $check_str = ''; | ||
| 9 | - if (strpos($scStr, 'e') !== false) { | ||
| 10 | - $check_str = 'e'; | ||
| 11 | - } | ||
| 12 | - if (strpos($scStr, 'E') !== false) { | ||
| 13 | - $check_str = 'E'; | ||
| 14 | - } | ||
| 15 | - if (empty($check_str)) { | ||
| 16 | - return $scStr; //非科学计数直接返回。 | ||
| 17 | - } | ||
| 18 | - $num_length = 0; | ||
| 19 | - $split_array = explode($check_str, $scStr); | ||
| 20 | - $num_length += strlen($split_array[0]); | ||
| 21 | - $num_length += (int)str_replace(['-', '+'], '', $split_array[1]); | ||
| 22 | - $float_number = (float)$scStr; | ||
| 23 | - $decimal_string = number_format($float_number, $num_length, '.', ''); | ||
| 24 | - $num = rtrim(rtrim($decimal_string, '0'), '.'); //去除小数后多余的0 | ||
| 25 | - return $num; | ||
| 26 | -} | ||
| 27 | -function tsToISO($timestamp) | ||
| 28 | -{ | ||
| 29 | - $datetime = new \DateTime(); | ||
| 30 | - $datetime->setTimestamp(floor($timestamp / 1000)); | ||
| 31 | - $datetime->setTimezone(new \DateTimeZone('UTC')); | ||
| 32 | - $milliseconds = sprintf('.%03d', $timestamp % 1000); | ||
| 33 | - return $datetime->format('Y-m-d\TH:i:s') . $milliseconds . 'Z'; | ||
| 34 | -} |
| @@ -2,12 +2,12 @@ | @@ -2,12 +2,12 @@ | ||
| 2 | 2 | ||
| 3 | namespace trader\binance; | 3 | namespace trader\binance; |
| 4 | 4 | ||
| 5 | -require_once __DIR__ . '/../../../vendor/autoload.php'; | 5 | +require_once __DIR__ . '/../../load.php'; |
| 6 | require_once __DIR__ . '/Api.php'; | 6 | require_once __DIR__ . '/Api.php'; |
| 7 | 7 | ||
| 8 | use trader\struct\ApiInfo; | 8 | use trader\struct\ApiInfo; |
| 9 | use trader\binance\Api as BnApi; | 9 | use trader\binance\Api as BnApi; |
| 10 | -use Jiaoyin\Websocket; | 10 | +use jytools\Websocket; |
| 11 | 11 | ||
| 12 | class ExBroker | 12 | class ExBroker |
| 13 | { | 13 | { |
| @@ -28,7 +28,8 @@ class ExBroker | @@ -28,7 +28,8 @@ class ExBroker | ||
| 28 | } | 28 | } |
| 29 | 29 | ||
| 30 | //获取所有品种资金费率 | 30 | //获取所有品种资金费率 |
| 31 | - public function getAllPremium() { | 31 | + public function getAllPremium() |
| 32 | + { | ||
| 32 | $res = $this->api->getPremiumIndex(); | 33 | $res = $this->api->getPremiumIndex(); |
| 33 | } | 34 | } |
| 34 | } | 35 | } |
| @@ -6,9 +6,9 @@ require_once __DIR__ . '/../../autoload.php'; | @@ -6,9 +6,9 @@ require_once __DIR__ . '/../../autoload.php'; | ||
| 6 | require_once __DIR__ . '/../../../vendor/autoload.php'; | 6 | require_once __DIR__ . '/../../../vendor/autoload.php'; |
| 7 | 7 | ||
| 8 | use trader\struct\ApiInfo; | 8 | use trader\struct\ApiInfo; |
| 9 | -use Jiaoyin\Curl; | ||
| 10 | -use function Jiaoyin\getMicrotime; | ||
| 11 | -use function trader\tsToISO; | 9 | +use jytools\Curl; |
| 10 | +use function jytools\getMicrotime; | ||
| 11 | +use function jytools\tsToISO; | ||
| 12 | 12 | ||
| 13 | class Api | 13 | class Api |
| 14 | { | 14 | { |
| @@ -2,13 +2,13 @@ | @@ -2,13 +2,13 @@ | ||
| 2 | 2 | ||
| 3 | namespace trader\okx; | 3 | namespace trader\okx; |
| 4 | 4 | ||
| 5 | -require_once __DIR__ . '/../../../vendor/autoload.php'; | 5 | +require_once __DIR__ . '/../../load.php'; |
| 6 | require_once __DIR__ . '/Api.php'; | 6 | require_once __DIR__ . '/Api.php'; |
| 7 | 7 | ||
| 8 | use trader\struct\ApiInfo; | 8 | use trader\struct\ApiInfo; |
| 9 | use trader\okx\Api as OkxApi; | 9 | use trader\okx\Api as OkxApi; |
| 10 | -use Jiaoyin\Websocket; | ||
| 11 | -use function Jiaoyin\output; | 10 | +use jytools\Websocket; |
| 11 | +use function jytools\output; | ||
| 12 | 12 | ||
| 13 | 13 | ||
| 14 | class ExBroker | 14 | class ExBroker |
trader/load.php
0 → 100644
| 1 | +<?php | ||
| 2 | +require_once __DIR__ . '/../jytools/load.php'; | ||
| 3 | +require_once __DIR__ . '/CmBroker.php'; | ||
| 4 | +require_once __DIR__ . '/common/tool.php'; | ||
| 5 | +require_once __DIR__ . '/struct/ApiInfo.php'; | ||
| 6 | +require_once __DIR__ . '/struct/SymbolInfo.php'; | ||
| 7 | +require_once __DIR__ . '/struct/Order.php'; | ||
| 8 | +require_once __DIR__ . '/struct/WsData.php'; | ||
| 9 | +require_once __DIR__ . '/struct/WsDataTrade.php'; | ||
| 10 | +require_once __DIR__ . '/struct/WsDataPos.php'; | ||
| 11 | +require_once __DIR__ . '/struct/WsDataOrder.php'; | ||
| 12 | +require_once __DIR__ . '/struct/Pos.php'; | ||
| 13 | +require_once __DIR__ . '/struct/Kline.php'; | ||
| 14 | +require_once __DIR__ . '/exchange/okx/ExBroker.php'; | ||
| 15 | +require_once __DIR__ . '/exchange/binance/ExBroker.php'; |
| @@ -4,7 +4,7 @@ namespace trader\struct; | @@ -4,7 +4,7 @@ namespace trader\struct; | ||
| 4 | 4 | ||
| 5 | require_once __DIR__ . '/../../vendor/autoload.php'; | 5 | require_once __DIR__ . '/../../vendor/autoload.php'; |
| 6 | 6 | ||
| 7 | -use function Jiaoyin\getPrecision; | 7 | +use function jytools\getPrecision; |
| 8 | 8 | ||
| 9 | class SymbolInfo | 9 | class SymbolInfo |
| 10 | { | 10 | { |
-
请 注册 或 登录 后发表评论