['lat,lng', [lat,lng]]
+ */ + public function setLocations(array $locations) + { + $pieces = []; + foreach ($locations as $item) { + if(is_array($item)) { + $pieces[] = "{$item[0]},{$item[1]}"; + } + } + $this->option['locations'] = implode(';', $pieces); + } + + /** + * 设置坐标类型 + * @param number $value + * 1 GPS坐标 + * 2 sogou经纬度 + * 3 baidu经纬度 + * 4 mapbar经纬度 + * 5 腾讯、google、高德坐标[默认] + * 6 sogou墨卡托 + */ + public function setType($value=self::TYPE_DEFAULT) + { + $this->option['type'] = $value; + } +} \ No newline at end of file diff --git a/extend/joypack/tencent-map/src/Logger.php b/extend/joypack/tencent-map/src/Logger.php new file mode 100644 index 00000000..248eb9eb --- /dev/null +++ b/extend/joypack/tencent-map/src/Logger.php @@ -0,0 +1,121 @@ +development = $development; + + if($root_path) { + if(is_dir($root_path)) { + $this->rootPath = $root_path; + } else { + if(@mkdir($root_path, 0775, true)) { + $this->rootPath = $root_path; + } + } + } + } + + public function __toString() + { + return __CLASS__; + } + + /** + * 写入 debug 日志 + * @param string $message + * @param string | array $data + */ + public function debug($message, $data=null) + { + $this->save($message, $data, 'DEBUG'); + } + + /** + * 写入 INFO 日志 + * @param string $message + * @param string | array $data + */ + public function info($message, $data=null) + { + $this->save($message, $data, 'INFO'); + } + + /** + * 写入 ERROR 日志 + * @param string $message + * @param string | array $data + */ + public function error($message, $data=null) + { + $this->save($message, $data, 'ERROR'); + } + + /** + * 打印变量 + * @param mixed $args 打印列表 + * 最后一个元素如果是 true 则 exit + */ + public function print(...$args) + { + $args = func_get_args(); + + $length = count($args); + + $exit = false; + + if(is_bool($last_argument = $args[$length-1])) { + if($last_argument) { + $exit = true; + array_pop($args); + } + } + + echo ''; + while ($argument = array_shift($args)) { + print_r($argument); + echo ''; + + if($exit) { + exit; + } + } + + protected function save($message, $data, $level) + { + if(is_null($this->rootPath)) { + return; + } + + // 生产环境时只记录错误信息 + if(!$this->development) { + if($level != 'ERROR') { + return; + } + } + + $date = date('Y-m-d'); + + $now = date('Y-m-d H:i:s'); + + $filename = "{$this->rootPath}/{$date}.log"; + + if(is_array($data)) { + $data = json_encode($data, JSON_UNESCAPED_UNICODE); + } + + @file_put_contents($filename, "[{$level}] {$now} {$message} {$data}\r\n", FILE_APPEND); + } +} \ No newline at end of file diff --git a/extend/joypack/tencent-map/src/Option.php b/extend/joypack/tencent-map/src/Option.php new file mode 100644 index 00000000..21f64f2a --- /dev/null +++ b/extend/joypack/tencent-map/src/Option.php @@ -0,0 +1,98 @@ +setKey($key); + $this->setSecret($secret); + } + + public function setSecret($value) + { + $this->secret = $value; + } + + /** + * 开发密钥 + * @param string $value + */ + public function setKey($value) + { + $this->option['key'] = $value; + } + + /** + * 返回格式:支持JSON/JSONP,默认JSON + * @param string $value + */ + public function setOutput($value=self::OUTPUT_JSON) + { + $this->option['output'] = $value; + } + + /** + * JSONP方式回调函数 + * @param string $value + */ + public function setCallback($value) + { + $this->option['callback'] = $value; + } + + /** + * 签名 + * @param string $uri + */ + public function setSig($uri) + { + $this->option['sig'] = $this->buildSig($uri, $this->getAll()); + } + + /** + * 获得所有参数 + * @return array + */ + public function getAll() + { + return $this->option; + } + + /** + * 生成签名 + * @param string $uri + * @return string + */ + protected function buildSig($uri, $option) + { + ksort($option); + + $pieces = []; + foreach ($option as $key => $val) + { + $pieces[] = "{$key}={$val}"; + } + + $str = sprintf('%s?%s', rtrim($uri, '/'), implode('&', $pieces)); + + /* + echo '
'; + } + echo '
'; + print_r("{$str}{$this->secret}"); + die; + //*/ + + return md5("{$str}{$this->secret}"); + } +} \ No newline at end of file diff --git a/extend/joypack/tencent-map/src/Request.php b/extend/joypack/tencent-map/src/Request.php new file mode 100644 index 00000000..78a8f7fe --- /dev/null +++ b/extend/joypack/tencent-map/src/Request.php @@ -0,0 +1,181 @@ +logger = $logger; + } + + public function uri($uri) + { + $this->url .= '/' . trim($uri, '/'); + return $this; + } + + public function query($name, $value=null) + { + if(is_array($name)) { + $this->query = array_merge($this->query, $name); + } else { + $this->query[$name] = $value; + } + return $this; + } + + public function field($name, $value=null) + { + if(is_array($name)) { + $this->field = array_merge($this->field, $name); + } else { + $this->field[$name] = $value; + } + return $this; + } + + /** + * method get + * @param array $query + * @return Response + */ + public function get(array $query=[]) + { + if($query) { + $this->query($query); + } + + $url = $this->mergeQuery($this->url, $this->query); + + return $this->create($url); + } + + public function post(array $fields=[]) + { + if($fields) { + $this->field($fields); + } + + $url = $this->mergeQuery($this->url, $this->query); + + return $this->create($url, 'POST', $this->field); + } + + /** + *将参数合并到 URL
+ * @param string $url 请求的地址 + * @param array $query 请求参数 + * @param bool $recursive 是否递归合并 + * @return mixed + */ + protected function mergeQuery($url, array $query, bool $recursive=false) + { + if(empty($url)) { + return null; + } + + // 没有设置参数时直接返回地址 + if(empty($query)) { + return $url; + } + + $parsed = parse_url($url); + + // 合并参数 + if(isset($parsed['query'])) { + $url = substr($url, 0, strpos($url, '?')); + + $str_parsed = []; + + parse_str($parsed['query'], $str_parsed); + + if($recursive) { + $query = array_merge_recursive($str_parsed, $query); + } else { + $query = array_merge($str_parsed, $query); + } + } else { + $url = rtrim($url, '/?'); + } + + // 生成 query 字符串 + $url = "{$url}?" . http_build_query($query); + + return $url; + + // 处理锚点 + if(isset($parsed['fragment'])) { + $url .= "#{$parsed['fragment']}"; + } + + return $url; + } + + /** + *创建请求
+ * @param string $url 请求地址 + * @param string $method 请求方式 + * @param array $data POST 数据 + * @return Response + */ + protected function create($url, $data=null) + { + //$referer = "{$_SERVER['REQUEST_SCHEME']}://{$_SERVER['SERVER_NAME']}"; + + //$header = [ + //"CLIENT-IP: {$_SERVER['REMOTE_ADDR']}", + //"X-FORWARDED-FOR: {$_SERVER['REMOTE_ADDR']}", + //"Content-Type: application/json; charset=utf-8", + //"Accept: */*" + //]; + + $ch = curl_init(); + + curl_setopt($ch, CURLOPT_URL, $url); + //curl_setopt($ch, CURLOPT_HEADER, $header); + curl_setopt($ch, CURLOPT_TIMEOUT, 10); + //curl_setopt($ch, CURLOPT_REFERER, $referer); + curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); + curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, 0); + curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 0); + + if(!is_null($data)) { + curl_setopt($ch, CURLOPT_POST, true); + if($data) { + curl_setopt($ch, CURLOPT_POSTFIELDS, $data); + } + } + + $original = curl_exec($ch); + + $error = null; + if($errno = curl_errno($ch)) { + $error = curl_error($ch); + } + + curl_close($ch); + + $this->logger->info('请求地址', $url); + + if($data) { + $this->logger->info('请求数据', $data); + } + + $this->logger->info('响应数据', $original); + + return new Response($errno, $error, $original, $this->logger); + } +} \ No newline at end of file diff --git a/extend/joypack/tencent-map/src/Response.php b/extend/joypack/tencent-map/src/Response.php new file mode 100644 index 00000000..39d1c956 --- /dev/null +++ b/extend/joypack/tencent-map/src/Response.php @@ -0,0 +1,159 @@ +logger = $logger; + + // 仅成功时 + if(0 === $errno) { + $decode = json_decode($original, true); + if(is_null($decode)) { + // 错误 + $this->setErrorMessage(99); + // 写入日志 + $logger->error('解析失败'); + } else { + $this->original = $original; + $this->decode = $decode; + } + } else { + // 错误 + $this->setErrorMessage($errno); + // 写入日志 + $logger->error($error); + } + } + + /** + * 返回json + * @return string + */ + public function getOriginal() + { + return $this->original; + } + + /** + * 返回数组 + * @return array + */ + public function toArray() + { + return $this->decode; + } + + /** + * 获得某属性时 + * @param string $prop_name + * @return mixed + */ + public function __get($property) + { + return $this->decode[ $property ] ?? null; + } + + public function __toString() + { + return $this->original; + } + + protected function setErrorMessage($errno) + { + $errors = [ + 1=> 'UNSUPPORTED_PROTOCOL', + 2=> 'FAILED_INIT', + 3=> 'URL_MALFORMAT', + 4=> 'URL_MALFORMAT_USER', + 5=> 'COULDNT_RESOLVE_PROXY', + 6=> 'COULDNT_RESOLVE_HOST', + 7=> 'COULDNT_CONNECT', + 8=> 'FTP_WEIRD_SERVER_REPLY', + 9=> 'REMOTE_ACCESS_DENIED', + 11=> 'FTP_WEIRD_PASS_REPLY', + 13=> 'FTP_WEIRD_PASV_REPLY', + 14=>'FTP_WEIRD_227_FORMAT', + 15=> 'FTP_CANT_GET_HOST', + 17=> 'FTP_COULDNT_SET_TYPE', + 18=> 'PARTIAL_FILE', + 19=> 'FTP_COULDNT_RETR_FILE', + 21=> 'QUOTE_ERROR', + 22=> 'HTTP_RETURNED_ERROR', + 23=> 'WRITE_ERROR', + 25=> 'UPLOAD_FAILED', + 26=> 'READ_ERROR', + 27=> 'OUT_OF_MEMORY', + 28=> 'OPERATION_TIMEDOUT', + 30=> 'FTP_PORT_FAILED', + 31=> 'FTP_COULDNT_USE_REST', + 33=> 'RANGE_ERROR', + 34=> 'HTTP_POST_ERROR', + 35=> 'SSL_CONNECT_ERROR', + 36=> 'BAD_DOWNLOAD_RESUME', + 37=> 'FILE_COULDNT_READ_FILE', + 38=> 'LDAP_CANNOT_BIND', + 39=> 'LDAP_SEARCH_FAILED', + 41=> 'FUNCTION_NOT_FOUND', + 42=> 'ABORTED_BY_CALLBACK', + 43=> 'BAD_FUNCTION_ARGUMENT', + 45=> 'INTERFACE_FAILED', + 47=> 'TOO_MANY_REDIRECTS', + 48=> 'UNKNOWN_TELNET_OPTION', + 49=> 'TELNET_OPTION_SYNTAX', + 51=> 'PEER_FAILED_VERIFICATION', + 52=> 'GOT_NOTHING', + 53=> 'SSL_ENGINE_NOTFOUND', + 54=> 'SSL_ENGINE_SETFAILED', + 55=> 'SEND_ERROR', + 56=> 'RECV_ERROR', + 58=> 'SSL_CERTPROBLEM', + 59=> 'SSL_CIPHER', + 60=> 'SSL_CACERT', + 61=> 'BAD_CONTENT_ENCODING', + 62=> 'LDAP_INVALID_URL', + 63=> 'FILESIZE_EXCEEDED', + 64=> 'USE_SSL_FAILED', + 65=> 'SEND_FAIL_REWIND', + 66=> 'SSL_ENGINE_INITFAILED', + 67=> 'LOGIN_DENIED', + 68=> 'TFTP_NOTFOUND', + 69=> 'TFTP_PERM', + 70=> 'REMOTE_DISK_FULL', + 71=> 'TFTP_ILLEGAL', + 72=> 'TFTP_UNKNOWNID', + 73=> 'REMOTE_FILE_EXISTS', + 74=> 'TFTP_NOSUCHUSER', + 75=> 'CONV_FAILED', + 76=> 'CONV_REQD', + 77=> 'SSL_CACERT_BADFILE', + 78=> 'REMOTE_FILE_NOT_FOUND', + 79=> 'SSH', + 80=> 'SSL_SHUTDOWN_FAILED', + 81=> 'AGAIN', + 82=> 'SSL_CRL_BADFILE', + 83=> 'SSL_ISSUER_ERROR', + 84=> 'FTP_PRET_FAILED', + 84=> 'FTP_PRET_FAILED', + 85=> 'RTSP_CSEQ_ERROR', + 86=> 'RTSP_SESSION_ERROR', + 87=> 'FTP_BAD_FILE_LIST', + 88=> 'CHUNK_FAILED', + 99=> 'DECODE_ERROR', + ]; + $this->error = $errors[ $errno ] ?? 'UNKNOWN_ERROR'; + } +} \ No newline at end of file