10]); $response = $client->request('GET', $url, array_filter([ 'query' => $queryData, 'headers' => $headers, 'verify' => false ])); $body = (string)$response->getBody(); return $json ? json_decode($body, true) : $body; } catch (RequestException $e) { return false; } } /** * post请求 * @param $url * @param array $postData * @param array $headers * @param bool $json * @return mixed|string */ public static function httpPost($url, $postData = [], $headers = [], $json = true) { try { $client = new Client(['timeout' => 10]); $response = $client->request('POST', $url, array_filter([ 'form_params' => $postData, 'headers' => $headers, 'verify' => false ])); $body = (string)$response->getBody(); return $json ? json_decode($body, true) : $body; } catch (RequestException $e) { Log::info('httpPost-error:' . $e->getMessage()); return false; } } /** * @param $method * @param $url * @param array $data * @param array $headers * @param bool $jsonRequest * @param bool $jsonDecode * @return mixed|string * @throws \Exception * @throws \GuzzleHttp\Exception\GuzzleException */ public static function httpRequest($method, $url, $data = [], $headers = [], $jsonRequest = false, $jsonDecode = true) { try { $method = strtoupper($method); $client = new Client(['verify' => false]); $methodMap = [ 'GET' => 'query', 'POST' => 'form_params', ]; $type = $jsonRequest ? 'json' : $methodMap[$method] ?? 'query'; $param = [$type => $data]; if ($headers) { $param['headers'] = $headers; } $response = $client->request($method, $url, $param); $body = (string)$response->getBody(); return $jsonDecode ? json_decode($body, true) : $body; } catch (TransferException $e) { throw new \Exception($e->getMessage(), $e->getCode()); } } /** * 输出xml字符 * @param $values * @return string * @throws \Exception */ public static function ToXml($values) { if (!is_array($values) || count($values) <= 0) { throw new \Exception("数组数据异常!"); } $xml = ""; foreach ($values as $key => $val) { if (is_numeric($val)) { $xml .= "<" . $key . ">" . $val . ""; } else { $xml .= "<" . $key . ">"; } } $xml .= ""; return $xml; } /** * 将xml转为array * @param $xml * @return mixed * @throws \Exception */ public static function FromXml($xml) { if (!$xml) { throw new \Exception("xml数据异常!"); } //将XML转为array //禁止引用外部xml实体 libxml_disable_entity_loader(true); $values = json_decode(json_encode(simplexml_load_string($xml, 'SimpleXMLElement', LIBXML_NOCDATA)), true); return $values; } /** * 格式化参数格式化成url参数 * @param $values * @return string */ public static function ToUrlParams($values) { $buff = ""; foreach ($values as $k => $v) { if ($k != "sign" && $v != "" && !is_array($v)) { $buff .= $k . "=" . $v . "&"; } } $buff = trim($buff, "&"); return $buff; } /** * 生成签名 * @param $values * @param $key * @return string */ public static function MakeSign($values, $key = '') { unset($values['sign']); //签名步骤一:按字典序排序参数 ksort($values); $string = self::ToUrlParams($values); //签名步骤二:在string后加入KEY !$key && $key = Env::get('wechat.api_key'); $string = $string . "&key=" . $key; //签名步骤三:MD5加密或者HMAC-SHA256 if (isset($values['sign_type']) && $values['sign_type'] == 'HMAC-SHA256') { $sign = hash_hmac("sha256", $string, $key); } else { $sign = md5($string); } //签名步骤四:所有字符转为大写 $result = strtoupper($sign); Log::info('通用工具签名-MakeSign:' . json_encode(['values' => $values, 'string' => $string, 'sign' => $sign])); return $result; } /** * 验证签名是否正确 * @param $values * @param $sign * @param $key * @return bool */ public static function CheckSign($values, $sign, $key = '') { $localSign = self::MakeSign($values, $key); Log::info('通用工具签名信息-Tool-CheckSign' . json_encode(['data' => $values, 'sign' => $sign, 'localSign' => $localSign])); if ($localSign == $sign) { //签名正确 return true; } return false; } /** * 打包签名数据 * @param $values * @return mixed */ public static function packSign($values) { if (!isset($values['nonce_str'])) { $values['nonce_str'] = uniqid(); } if (!isset($values['time_stamp'])) { $values['time_stamp'] = time(); } //签名步骤四:所有字符转为大写 $values['sign'] = self::MakeSign($values, Env::get('app.token_key')); return $values; } /** * @param $array * @return mixed */ public static function changeArrayKey($array) { foreach ($array as &$value) { if (isset($value['name'])) { $value['text'] = $value['name']; unset($value['name']); } if (isset($value['subItems'])) { foreach ($value['subItems'] as &$v) { $v['text'] = $v['name']; unset($v['name']); } $value['children'] = $value['subItems']; unset($value['subItems']); } } return $array; } /** * 解析字符串数组 * @param $string * @param $data * @return mixed */ public static function parseArrStr($string, $data) { $fieldArr = explode('.', str_replace(['{', '}'], '', $string)); foreach ($fieldArr as $field) { $data = $data[$field] ?? ''; } return $data; } /** * @param $value * @param $data * @return string */ public static function parseTempData($value, $data) { if (preg_match_all('/\{.*?\}/', $value, $matches)) { $str = ''; foreach ($matches as $match){ $str .= ToolService::parseArrStr($match, $data); } $value = $str; } return $value; } /** * 获取请求缓存Key * @param $url * @param $param * @return mixed */ public static function httpCacheKey($url, $param) { $query = http_build_query($param); $parse = parse_url($url); $urls = implode(':', ['http-cache', $parse['host'], $parse['path'], $query]); $key = preg_replace('/[^a-zA-Z0-9_\-:]/', '', $urls); return $key; } /** * 递归实现无限极分类 * @param array $array 分类数据 * @param int $pid 父ID * @param int $level 分类级别 * @return array 分好类的数组 直接遍历即可 $level可以用来遍历缩进 */ public static function getTree($array, $pid = 0, $level = 0) { //声明静态数组,避免递归调用时,多次声明导致数组覆盖 static $list = []; foreach ($array as $key => $value) { //第一次遍历,找到父节点为根节点的节点 也就是pid=0的节点 if ($value['parent_id'] == $pid) { //父节点为根节点的节点,级别为0,也就是第一级 $value['level'] = $level; $value['name'] = str_repeat('--', $level) . $value['name']; //把数组放到list中 $list[] = $value; //把这个节点从数组中移除,减少后续递归消耗 unset($array[$key]); //开始递归,查找父ID为该节点ID的节点,级别则为原级别+1 self::getTree($array, $value['id'], $level + 1); } } return $list; } }