// +---------------------------------------------------------------------- declare (strict_types=1); namespace app\common\library\express\provider\driver; use app\common\library\helper; use app\common\library\express\provider\Driver; use cores\exception\BaseException; /** * 阿里云物流查询驱动 * Class Aliyun * @package app\common\library\express\provider\driver */ class Aliyun extends Driver { // API地址 const API_URL = 'https://wdexpress.market.alicloudapi.com/gxali'; /** * 查询物流轨迹 * @param string $code * @param string $expressNo * @return array * @throws BaseException */ public function query(string $code, string $expressNo): array { // 授权参数 $appCode = $this->options['appCode']; $headers = ["Authorization: APPCODE " . $appCode]; // 物流查询参数 $querys = ['n' => $expressNo, 't' => $code]; // 请求API $result = $this->curlGet(self::API_URL, $headers, $querys); $data = helper::jsonDecode($result); // 记录日志 log_record(['name' => '查询物流轨迹', 'provider' => 'aliyun', 'param' => $querys, 'result' => $data]); // 格式化返回的数据 return $this->formatTraces($data['Traces']); } /** * 格式化返回的数据 * @param array $source * @return array */ private function formatTraces(array $source): array { return array_map(function ($item) { return ['time' => $item['AcceptTime'], 'context' => $item['AcceptStation']]; }, array_reverse($source)); } /** * curl请求指定url * @param string $url * @param array $headers * @param array $querys * @return bool|mixed|string * @throws BaseException */ protected function curlGet(string $url, array $headers, array $querys) { $ch = curl_init(); curl_setopt($ch, CURLOPT_URL, $url . '?' . http_build_query($querys)); curl_setopt($ch, CURLOPT_HEADER, true); curl_setopt($ch, CURLOPT_HTTPHEADER, $headers); curl_setopt($ch, CURLOPT_FAILONERROR, false); curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false); curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false); $result = curl_exec($ch); $httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE); [$header, $body] = explode("\r\n\r\n", $result, 2); curl_close($ch); if ($httpCode == 200) { return $body; } $message = '参数名错误或其他错误'; if ($httpCode == 400 && strpos($header, "Invalid Param Location") !== false) { $message = '参数错误'; } elseif ($httpCode == 400 && strpos($header, "Invalid AppCode") !== false) { $message = 'AppCode错误'; } elseif ($httpCode == 400 && strpos($header, "Invalid Url") !== false) { $message = '请求的 Method、Path 或者环境错误'; } elseif ($httpCode == 403 && strpos($header, "Unauthorized") !== false) { $message = '服务未被授权(或URL和Path不正确)'; } elseif ($httpCode == 403 && strpos($header, "Quota Exhausted") !== false) { $message = '套餐包次数用完'; } elseif ($httpCode == 500) { $message = 'API网关错误'; } elseif ($httpCode == 0) { $message = 'URL错误'; } throwError('阿里云物流查询API失败:' . $message); } }