├── ab.png ├── index.php ├── system ├── Config.php └── OcrFactory.php ├── lib ├── Ocr.php ├── ShowOcr.php ├── baseocr │ ├── AipHttpClient.php │ ├── AipBase.php │ └── AipBCEUtil.php └── AipOcr.php ├── config └── main.php ├── controller └── BaiduPet.php ├── README.md ├── model └── BaiduPetModel.php └── dog.php /ab.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cfrs2005/lcg-php/HEAD/ab.png -------------------------------------------------------------------------------- /index.php: -------------------------------------------------------------------------------- 1 | maxAmount = 1000; 16 | $this->minAmount = 100; 17 | $this->userCookie = ''; 18 | 19 | } 20 | 21 | 22 | public function run() 23 | { 24 | 25 | } 26 | 27 | public function help() 28 | { 29 | } 30 | 31 | 32 | public function buy() 33 | { 34 | } 35 | 36 | public function sell() 37 | { 38 | } 39 | 40 | public function star() 41 | { 42 | 43 | } 44 | 45 | public function breed() 46 | { 47 | } 48 | 49 | } -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # lcg-php 2 | 3 | 莱茨狗 黑产服务端代码 4 | 5 | 目前看来 莱茨狗 开发速度较慢,不如外面的山寨 6 | 7 | 应该是团队rd 按自己的想法做的,目前看来 进度慢,简单的完善交易流程都有没有,投入有限,而且没什么可玩的。 8 | 9 | 10 | 11 | 还不如安心的去刷2个公信宝。 好歹1天也几块钱 12 | 13 | 推广注册链接: 14 | 15 | https://blockcity.gxshares.org/#/?referUser=giTNP2MOZZPqUGTCVt10355330406 16 | 17 | 尚未支持提现,不建议绑定 支付宝之类的 授权信息 18 | 19 | 可交易平台 20 | 21 | https://big.one 22 | 23 | 24 | 25 | 26 | # 增加品种提示 27 | 28 | 增加查询分页数量 ,增加查询类型 29 | 30 | ```` 31 | // sort 查询类型类型 32 | // 支持 "CREATETIME_DESC","CREATETIME_ASC","AMOUNT_ASC","AMOUNT_DESC" 33 | define('SORT_TYPE','CREATETIME_DESC'); 34 | 35 | //目前只能到20 36 | define('SIZE_PAGE',20) 37 | 38 | ```` 39 | 40 | # ocr -showapi 41 | 42 | 增加验证码 识别率 超过 99% 43 | 44 | https://www.showapi.com/api/sku/184 45 | 注册付费 蛮贵的 我用1分钱 刷到一只狗 46 | 47 | 48 | ```` 49 | vim dog.php 50 | define('SHOW_API_ID', ''); 51 | define('SHOW_API_SECRET', ''); 52 | define('ORC_FUNC', 'showApiOcr'); 53 | 54 | ```` 55 | 56 | # ocr - baidu 57 | 58 | 采用百度ocr识别验证码,其实效果不好. 59 | 60 | 访问 https://console.bce.baidu.com 找到 文字识别 申请应用即可 61 | 62 | 申请地址 63 | https://console.bce.baidu.com/ai/?_=1517904818639#/ai/ocr/overview/index 64 | 65 | 创建即可 66 | 67 | 500次/天免费 68 | 69 | 70 | ```` 71 | vim dog.php 72 | 73 | //api相关内容 74 | define('APP_ID', ''); 75 | define('API_KEY', ''); 76 | define('SECRET_KEY', ''); 77 | define('ORC_FUNC', 'idlOcr'); 78 | //配置 79 | cookie=""; 80 | ```` 81 | 82 | # 执行 php >= 5.6 83 | ```` 84 | php dog.php 85 | 86 | 2018-02-06 17:22:45 黑产 百度 pet-chain 87 | 2018-02-06 17:22:45 当前价格最大限制为: 1000 88 | 2018-02-06 17:22:45 1858369951695906444 价格: 2170.00 89 | 2018-02-06 17:22:45 1855391890091024066 价格: 2179.00 90 | 2018-02-06 17:22:45 1855391649572851410 价格: 2179.99 91 | 2018-02-06 17:22:45 1855390515701487655 价格: 2185.00 92 | 2018-02-06 17:22:45 1855391924450754966 价格: 2185.00 93 | 2018-02-06 17:22:45 1855391305975467756 价格: 2186.00 94 | 2018-02-06 17:22:45 1855445422563413857 价格: 2187.99 95 | 2018-02-06 17:22:45 1855391890091020576 价格: 2188.00 96 | 2018-02-06 17:22:45 1855391924450757306 价格: 2188.00 97 | ```` 98 | 99 | 100 | # 新版本 101 | ```` 102 | 看心情 103 | 104 | ```` -------------------------------------------------------------------------------- /model/BaiduPetModel.php: -------------------------------------------------------------------------------- 1 | requestTimeId = time() . "451"; 16 | 17 | } 18 | 19 | /** 20 | * @param int $pageNo 21 | * @param int $pageSize 22 | * @return string 23 | */ 24 | public function getListUrlCmd($pageNo = 1, $pageSize = 10) 25 | { 26 | $data = [ 27 | "pageNo" => $pageNo, 28 | "pageSize" => $pageSize, 29 | "querySortType" => "AMOUNT_ASC", 30 | "petIds" => [], 31 | "lastAmount" => null, 32 | "lastRareDegree" => null, 33 | "requestId" => $this->requestTimeId, 34 | "appId" => 1, 35 | "tpl" => "", 36 | ]; 37 | return $this->__getCmd(PET_LIST_URL, ORIGIN, ORIGIN, $this->userCookie, $data); 38 | 39 | } 40 | 41 | public function getInfoUrlCmd() 42 | { 43 | 44 | } 45 | 46 | public function getCaptchaCmd() 47 | { 48 | 49 | } 50 | 51 | 52 | /** 53 | * @param $url 54 | * @param $origin 55 | * @param $referer 56 | * @param $cookie 57 | * @param $data 58 | * @param string $contenttype 59 | * @return string 60 | */ 61 | private function __getCmd($url, $origin, $referer, $cookie, $data, $contenttype = 'application/json') 62 | { 63 | $dataStr = json_encode($data); 64 | $cmd = "curl '{$url}' -H 'Origin: {$origin}' -H 'Accept-Encoding: gzip, deflate, br' -H 'Accept-Language: zh-CN,zh;q=0.9,en-US;q=0.8,en;q=0.7,zh-TW;q=0.6' -H 'User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_11_4) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/63.0.3239.132 Safari/537.36' -H 'Content-Type: {$contenttype}' -H 'Accept: application/json' -H 'Referer: {$referer}' -H 'Cookie: {$cookie}' -H 'Connection: keep-alive' --data-binary '{$dataStr}' --compressed"; 65 | return $cmd; 66 | } 67 | 68 | } -------------------------------------------------------------------------------- /lib/ShowOcr.php: -------------------------------------------------------------------------------- 1 | showapi_appid = $appid; 21 | $this->showapi_secret = $secret; 22 | } 23 | 24 | /** 25 | * @param $img_content 26 | * @return string 27 | */ 28 | public function getCaptcha($img_content) 29 | { 30 | $paramArr = array( 31 | 'showapi_appid' => $this->showapi_appid, 32 | 'img_base64' => $img_content, 33 | 'typeId' => "34", 34 | 'convert_to_jpg' => "0", 35 | ); 36 | $param = $this->_createParam($paramArr, $this->showapi_secret); 37 | $url = 'http://route.showapi.com/184-5?'; 38 | $result = $this->_curl($url, $param); 39 | $result = json_decode($result, true); 40 | if ($result && $result['showapi_res_code'] === 0) { 41 | return $result['showapi_res_body']['Result']; 42 | } 43 | return ''; 44 | } 45 | 46 | /** 47 | * @param $url 48 | * @param string $param 49 | * @return mixed 50 | */ 51 | private function _curl($url, $param = '') 52 | { 53 | $ch = curl_init(); 54 | curl_setopt($ch, CURLOPT_URL, $url); 55 | curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); 56 | curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, 0); 57 | curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 0); 58 | curl_setopt($ch, CURLOPT_POSTFIELDS, $param); 59 | $output = curl_exec($ch); 60 | curl_close($ch); 61 | return $output; 62 | } 63 | 64 | /** 65 | * @param $paramArr 66 | * @param $showapi_secret 67 | * @return string 68 | */ 69 | private function _createParam($paramArr, $showapi_secret) 70 | { 71 | $paraStr = ""; 72 | $signStr = ""; 73 | ksort($paramArr); 74 | foreach ($paramArr as $key => $val) { 75 | if ($key != '' && $val != '') { 76 | $signStr .= $key . $val; 77 | $paraStr .= $key . '=' . urlencode($val) . '&'; 78 | } 79 | } 80 | $signStr .= $showapi_secret; 81 | $sign = strtolower(md5($signStr)); 82 | $paraStr .= 'showapi_sign=' . $sign; 83 | return $paraStr; 84 | } 85 | } -------------------------------------------------------------------------------- /dog.php: -------------------------------------------------------------------------------- 1 | 1, "pageSize" => SIZE_PAGE, "querySortType" => SORT_TYPE, "petIds" => [], "lastAmount" => null, "lastRareDegree" => null, "requestId" => $time, "appId" => 1, "tpl" => ""]; 31 | $listPetUrl = 'https://pet-chain.baidu.com/data/market/queryPetsOnSale'; 32 | $cmd = buildCmd($listPetUrl, ORIGIN, JSON, ORIGIN, $cookie, $data); 33 | 34 | exec($cmd, $output, $return_arr); 35 | if (!isset($output[0])) { 36 | _log("empty respone"); 37 | exit(); 38 | } 39 | $info = json_decode($output[0], true); 40 | $output = []; 41 | foreach ($info['data']['petsOnSale'] as $item) { 42 | _log($item['petId'] ."\t品种:\t".@$petDegree[$item['rareDegree']]. "\t价格:\t" . $item['amount']); 43 | if (intval($item['amount']) > MAX_AMOUNT || intval($item['amount']) <= MIN_AMOUNT) { 44 | continue; 45 | } 46 | _log("执行买入\t" . $item['petId']); 47 | $petUrl = "https://pet-chain.baidu.com/chain/detail?channel=market&petId=" . $item['petId'] . "&validCode=" . $item['validCode']; 48 | _log($petUrl); 49 | $getCaptcha = 'https://pet-chain.baidu.com/data/captcha/gen'; 50 | $cmd = buildCmd($getCaptcha, ORIGIN, JSON, $petUrl, $cookie, ['requestId' => $time, 'appId' => 1, 'tpl' => '']); 51 | _log($cmd); 52 | @exec($cmd, $output, $return_arr); 53 | _log(serialize($output[0])); 54 | $captInfo = @json_decode($output[0], true); 55 | if (!$captInfo) { 56 | continue; 57 | } 58 | $captcha = call_user_func(ORC_FUNC, base64_decode($captInfo['data']['img'])); 59 | if (!$captcha) { 60 | _log("empty captcha,识别失败"); 61 | continue; 62 | } 63 | _log("captcha is :\t" . $captcha); 64 | $submitUrl = 'https://pet-chain.baidu.com/data/txn/create'; 65 | $submitData = ['petId' => $item['petId'], 'amount' => $item['amount'], 'seed' => $captInfo['data']['seed'], 'captcha' => $captcha, 'validCode' => $item['validCode'], 'requestId' => $time, 'appId' => 1, 'tpl' => '']; 66 | $cmd = buildCmd($submitUrl, ORIGIN, JSON, $petUrl, $cookie, $submitData); 67 | @exec($cmd, $output, $return_arr); 68 | $result = @json_decode($output[1], true); 69 | if ($result) { 70 | if (@$result['errorNo'] > 10000) { 71 | _log("执行买入\t" . $item['petId'] . "\t失败\t" . $result['errorMsg']); 72 | } else { 73 | _log("执行买入\t" . $item['petId'] . "\t成功\t" . $result['errorMsg']); 74 | } 75 | } else { 76 | _log('service 500'); 77 | } 78 | } 79 | 80 | 81 | function help() 82 | { 83 | _log('黑产 百度 pet-chain'); 84 | _log("当前允许购买 价格区间为:\t".MIN_AMOUNT."\t ~ \t" . MAX_AMOUNT); 85 | } 86 | 87 | /** 88 | * @param $url 89 | * @param $origin 90 | * @param $contenttype 91 | * @param $referer 92 | * @param $cookie 93 | * @param $data 94 | * @return string 95 | */ 96 | function buildCmd($url, $origin, $contenttype, $referer, $cookie, $data) 97 | { 98 | $dataStr = json_encode($data); 99 | $cmd = "curl '{$url}' -H 'Origin: {$origin}' -H 'Accept-Encoding: gzip, deflate, br' -H 'Accept-Language: zh-CN,zh;q=0.9,en-US;q=0.8,en;q=0.7,zh-TW;q=0.6' -H 'User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_11_4) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/63.0.3239.132 Safari/537.36' -H 'Content-Type: {$contenttype}' -H 'Accept: application/json' -H 'Referer: {$referer}' -H 'Cookie: {$cookie}' -H 'Connection: keep-alive' --data-binary '{$dataStr}' --compressed"; 100 | return $cmd; 101 | } 102 | 103 | /** 104 | * 百度 105 | * @param $pic_content 106 | * @return string 107 | */ 108 | function idlOcr($pic_content) 109 | { 110 | file_put_contents('ab.png', $pic_content); 111 | $client = new AipOcr(APP_ID, API_KEY, SECRET_KEY); 112 | $info = $client->basicGeneral($pic_content); 113 | //高精 114 | // $info=$client->basicAccurate($pic_content); 115 | if ($info) { 116 | _log(json_encode($info)); 117 | return trim(@$info['words_result'][0]['words']); 118 | } 119 | return ''; 120 | } 121 | 122 | /** 123 | * show api 124 | * @param $pic_content 125 | * @return string 126 | */ 127 | function showApiOcr($pic_content) 128 | { 129 | $showOcr = new ShowOcr(SHOW_API_ID, SHOW_API_SECRET); 130 | return $showOcr->getCaptcha(base64_encode($pic_content)); 131 | } 132 | 133 | /** 134 | * @param $str 135 | */ 136 | function _log($str) 137 | { 138 | echo date('Y-m-d H:i:s') . "\t" . $str . PHP_EOL; 139 | } 140 | -------------------------------------------------------------------------------- /lib/baseocr/AipHttpClient.php: -------------------------------------------------------------------------------- 1 | headers = $this->buildHeaders($headers); 29 | $this->connectTimeout = 60000; 30 | $this->socketTimeout = 60000; 31 | $this->conf = array(); 32 | } 33 | 34 | /** 35 | * 连接超时 36 | * @param int $ms 毫秒 37 | */ 38 | public function setConnectionTimeoutInMillis($ms){ 39 | $this->connectTimeout = $ms; 40 | } 41 | 42 | /** 43 | * 响应超时 44 | * @param int $ms 毫秒 45 | */ 46 | public function setSocketTimeoutInMillis($ms){ 47 | $this->socketTimeout = $ms; 48 | } 49 | 50 | /** 51 | * 配置 52 | * @param array $conf 53 | */ 54 | public function setConf($conf){ 55 | $this->conf = $conf; 56 | } 57 | 58 | /** 59 | * 请求预处理 60 | * @param resource $ch 61 | */ 62 | public function prepare($ch){ 63 | foreach($this->conf as $key => $value){ 64 | curl_setopt($ch, $key, $value); 65 | } 66 | } 67 | 68 | /** 69 | * @param string $url 70 | * @param array $data HTTP POST BODY 71 | * @param array $param HTTP URL 72 | * @param array $headers HTTP header 73 | * @return array 74 | */ 75 | public function post($url, $data=array(), $params=array(), $headers=array()){ 76 | $url = $this->buildUrl($url, $params); 77 | $headers = array_merge($this->headers, $this->buildHeaders($headers)); 78 | 79 | $ch = curl_init(); 80 | $this->prepare($ch); 81 | curl_setopt($ch, CURLOPT_URL, $url); 82 | curl_setopt($ch, CURLOPT_POST, 1); 83 | curl_setopt($ch, CURLOPT_HEADER, false); 84 | curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); 85 | curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false); 86 | curl_setopt($ch, CURLOPT_HTTPHEADER, $headers); 87 | curl_setopt($ch, CURLOPT_POSTFIELDS, is_array($data) ? http_build_query($data) : $data); 88 | curl_setopt($ch, CURLOPT_TIMEOUT_MS, $this->socketTimeout); 89 | curl_setopt($ch, CURLOPT_CONNECTTIMEOUT_MS, $this->connectTimeout); 90 | $content = curl_exec($ch); 91 | $code = curl_getinfo($ch, CURLINFO_HTTP_CODE); 92 | 93 | if($code === 0){ 94 | throw new Exception(curl_error($ch)); 95 | } 96 | 97 | curl_close($ch); 98 | return array( 99 | 'code' => $code, 100 | 'content' => $content, 101 | ); 102 | } 103 | 104 | /** 105 | * @param string $url 106 | * @param array $datas HTTP POST BODY 107 | * @param array $param HTTP URL 108 | * @param array $headers HTTP header 109 | * @return array 110 | */ 111 | public function multi_post($url, $datas=array(), $params=array(), $headers=array()){ 112 | $url = $this->buildUrl($url, $params); 113 | $headers = array_merge($this->headers, $this->buildHeaders($headers)); 114 | 115 | $chs = array(); 116 | $result = array(); 117 | $mh = curl_multi_init(); 118 | foreach($datas as $data){ 119 | $ch = curl_init(); 120 | $chs[] = $ch; 121 | $this->prepare($ch); 122 | curl_setopt($ch, CURLOPT_URL, $url); 123 | curl_setopt($ch, CURLOPT_POST, 1); 124 | curl_setopt($ch, CURLOPT_HEADER, false); 125 | curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); 126 | curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false); 127 | curl_setopt($ch, CURLOPT_HTTPHEADER, $headers); 128 | curl_setopt($ch, CURLOPT_POSTFIELDS, is_array($data) ? http_build_query($data) : $data); 129 | curl_setopt($ch, CURLOPT_TIMEOUT_MS, $this->socketTimeout); 130 | curl_setopt($ch, CURLOPT_CONNECTTIMEOUT_MS, $this->connectTimeout); 131 | curl_multi_add_handle($mh, $ch); 132 | } 133 | 134 | $running = null; 135 | do{ 136 | curl_multi_exec($mh, $running); 137 | usleep(100); 138 | }while($running); 139 | 140 | foreach($chs as $ch){ 141 | $content = curl_multi_getcontent($ch); 142 | $code = curl_getinfo($ch, CURLINFO_HTTP_CODE); 143 | $result[] = array( 144 | 'code' => $code, 145 | 'content' => $content, 146 | ); 147 | curl_multi_remove_handle($mh, $ch); 148 | } 149 | curl_multi_close($mh); 150 | 151 | return $result; 152 | } 153 | 154 | /** 155 | * @param string $url 156 | * @param array $param HTTP URL 157 | * @param array $headers HTTP header 158 | * @return array 159 | */ 160 | public function get($url, $params=array(), $headers=array()){ 161 | $url = $this->buildUrl($url, $params); 162 | $headers = array_merge($this->headers, $this->buildHeaders($headers)); 163 | 164 | $ch = curl_init(); 165 | $this->prepare($ch); 166 | curl_setopt($ch, CURLOPT_URL, $url); 167 | curl_setopt($ch, CURLOPT_HEADER, false); 168 | curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); 169 | curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false); 170 | curl_setopt($ch, CURLOPT_HTTPHEADER, $headers); 171 | curl_setopt($ch, CURLOPT_TIMEOUT_MS, $this->socketTimeout); 172 | curl_setopt($ch, CURLOPT_CONNECTTIMEOUT_MS, $this->connectTimeout); 173 | $content = curl_exec($ch); 174 | $code = curl_getinfo($ch, CURLINFO_HTTP_CODE); 175 | 176 | if($code === 0){ 177 | throw new Exception(curl_error($ch)); 178 | } 179 | 180 | curl_close($ch); 181 | return array( 182 | 'code' => $code, 183 | 'content' => $content, 184 | ); 185 | } 186 | 187 | /** 188 | * 构造 header 189 | * @param array $headers 190 | * @return array 191 | */ 192 | private function buildHeaders($headers){ 193 | $result = array(); 194 | foreach($headers as $k => $v){ 195 | $result[] = sprintf('%s:%s', $k, $v); 196 | } 197 | return $result; 198 | } 199 | 200 | /** 201 | * 202 | * @param string $url 203 | * @param array $params 参数 204 | * @return string 205 | */ 206 | private function buildUrl($url, $params){ 207 | if(!empty($params)){ 208 | $str = http_build_query($params); 209 | return $url . (strpos($url, '?') === false ? '?' : '&') . $str; 210 | }else{ 211 | return $url; 212 | } 213 | } 214 | } 215 | -------------------------------------------------------------------------------- /lib/baseocr/AipBase.php: -------------------------------------------------------------------------------- 1 | appId = trim($appId); 69 | $this->apiKey = trim($apiKey); 70 | $this->secretKey = trim($secretKey); 71 | $this->isCloudUser = null; 72 | $this->client = new AipHttpClient(); 73 | $this->version = '2_1_0'; 74 | $this->proxies = array(); 75 | } 76 | 77 | /** 78 | * 查看版本 79 | * @return string 80 | * 81 | */ 82 | public function getVersion(){ 83 | return $this->version; 84 | } 85 | 86 | /** 87 | * 连接超时 88 | * @param int $ms 毫秒 89 | */ 90 | public function setConnectionTimeoutInMillis($ms){ 91 | $this->client->setConnectionTimeoutInMillis($ms); 92 | } 93 | 94 | /** 95 | * 响应超时 96 | * @param int $ms 毫秒 97 | */ 98 | public function setSocketTimeoutInMillis($ms){ 99 | $this->client->setSocketTimeoutInMillis($ms); 100 | } 101 | 102 | /** 103 | * 代理 104 | * @param array $proxy 105 | * @return string 106 | * 107 | */ 108 | public function setProxies($proxies){ 109 | $this->client->setConf($proxies); 110 | } 111 | 112 | /** 113 | * 处理请求参数 114 | * @param string $url 115 | * @param array $params 116 | * @param array $data 117 | * @param array $headers 118 | */ 119 | protected function proccessRequest($url, &$params, &$data, $headers){ 120 | $params['aipSdk'] = 'php'; 121 | $params['aipSdkVersion'] = $this->version; 122 | } 123 | 124 | /** 125 | * Api 请求 126 | * @param string $url 127 | * @param mixed $data 128 | * @return mixed 129 | */ 130 | protected function request($url, $data, $headers=array()){ 131 | try{ 132 | $result = $this->validate($url, $data); 133 | if($result !== true){ 134 | return $result; 135 | } 136 | 137 | $params = array(); 138 | $authObj = $this->auth(); 139 | 140 | if($this->isCloudUser === false){ 141 | $params['access_token'] = $authObj['access_token']; 142 | } 143 | 144 | // 特殊处理 145 | $this->proccessRequest($url, $params, $data, $headers); 146 | 147 | $headers = $this->getAuthHeaders('POST', $url, $params, $headers); 148 | $response = $this->client->post($url, $data, $params, $headers); 149 | 150 | $obj = $this->proccessResult($response['content']); 151 | 152 | if(!$this->isCloudUser && isset($obj['error_code']) && $obj['error_code'] == 110){ 153 | $authObj = $this->auth(true); 154 | $params['access_token'] = $authObj['access_token']; 155 | $response = $this->client->post($url, $data, $params, $headers); 156 | $obj = $this->proccessResult($response['content']); 157 | } 158 | 159 | if(empty($obj) || !isset($obj['error_code'])){ 160 | $this->writeAuthObj($authObj); 161 | } 162 | }catch(Exception $e){ 163 | return array( 164 | 'error_code' => 'SDK108', 165 | 'error_msg' => 'connection or read data timeout', 166 | ); 167 | } 168 | 169 | return $obj; 170 | } 171 | 172 | /** 173 | * Api 多个并发请求 174 | * @param string $url 175 | * @param mixed $data 176 | * @return mixed 177 | */ 178 | protected function multi_request($url, $data){ 179 | try{ 180 | $params = array(); 181 | $authObj = $this->auth(); 182 | $headers = $this->getAuthHeaders('POST', $url); 183 | 184 | if($this->isCloudUser === false){ 185 | $params['access_token'] = $authObj['access_token']; 186 | } 187 | 188 | $responses = $this->client->multi_post($url, $data, $params, $headers); 189 | 190 | $is_success = false; 191 | foreach($responses as $response){ 192 | $obj = $this->proccessResult($response['content']); 193 | 194 | if(empty($obj) || !isset($obj['error_code'])){ 195 | $is_success = true; 196 | } 197 | 198 | if(!$this->isCloudUser && isset($obj['error_code']) && $obj['error_code'] == 110){ 199 | $authObj = $this->auth(true); 200 | $params['access_token'] = $authObj['access_token']; 201 | $responses = $this->client->post($url, $data, $params, $headers); 202 | break; 203 | } 204 | } 205 | 206 | if($is_success){ 207 | $this->writeAuthObj($authObj); 208 | } 209 | 210 | $objs = array(); 211 | foreach($responses as $response){ 212 | $objs[] = $this->proccessResult($response['content']); 213 | } 214 | 215 | }catch(Exception $e){ 216 | return array( 217 | 'error_code' => 'SDK108', 218 | 'error_msg' => 'connection or read data timeout', 219 | ); 220 | } 221 | 222 | return $objs; 223 | } 224 | 225 | /** 226 | * 格式检查 227 | * @param string $url 228 | * @param array $data 229 | * @return mix 230 | */ 231 | protected function validate($url, &$data){ 232 | return true; 233 | } 234 | 235 | /** 236 | * 格式化结果 237 | * @param $content string 238 | * @return mixed 239 | */ 240 | protected function proccessResult($content){ 241 | return json_decode($content, true, 512, JSON_BIGINT_AS_STRING); 242 | } 243 | 244 | /** 245 | * 返回 access token 路径 246 | * @return string 247 | */ 248 | private function getAuthFilePath(){ 249 | return dirname(__FILE__) . DIRECTORY_SEPARATOR . md5($this->apiKey); 250 | } 251 | 252 | /** 253 | * 写入本地文件 254 | * @param array $obj 255 | * @return void 256 | */ 257 | private function writeAuthObj($obj){ 258 | if($obj === null || (isset($obj['is_read']) && $obj['is_read'] === true)){ 259 | return; 260 | } 261 | 262 | $obj['time'] = time(); 263 | $obj['is_cloud_user'] = $this->isCloudUser; 264 | @file_put_contents($this->getAuthFilePath(), json_encode($obj)); 265 | } 266 | 267 | /** 268 | * 读取本地缓存 269 | * @return array 270 | */ 271 | private function readAuthObj(){ 272 | $content = @file_get_contents($this->getAuthFilePath()); 273 | if($content !== false){ 274 | $obj = json_decode($content, true, 512, JSON_BIGINT_AS_STRING); 275 | $this->isCloudUser = $obj['is_cloud_user']; 276 | $obj['is_read'] = true; 277 | if($this->isCloudUser || $obj['time'] + $obj['expires_in'] - 30 > time()){ 278 | return $obj; 279 | } 280 | } 281 | 282 | return null; 283 | } 284 | 285 | /** 286 | * 认证 287 | * @param bool $refresh 是否刷新 288 | * @return array 289 | */ 290 | private function auth($refresh=false){ 291 | 292 | //非过期刷新 293 | if(!$refresh){ 294 | $obj = $this->readAuthObj(); 295 | if(!empty($obj)){ 296 | return $obj; 297 | } 298 | } 299 | 300 | $response = $this->client->get($this->accessTokenUrl, array( 301 | 'grant_type' => 'client_credentials', 302 | 'client_id' => $this->apiKey, 303 | 'client_secret' => $this->secretKey, 304 | )); 305 | 306 | $obj = json_decode($response['content'], true, 512, JSON_BIGINT_AS_STRING); 307 | 308 | $this->isCloudUser = !$this->isPermission($obj); 309 | return $obj; 310 | } 311 | 312 | /** 313 | * 判断认证是否有权限 314 | * @param array $authObj 315 | * @return boolean 316 | */ 317 | protected function isPermission($authObj) 318 | { 319 | if(empty($authObj) || !isset($authObj['scope'])){ 320 | return false; 321 | } 322 | 323 | $scopes = explode(' ', $authObj['scope']); 324 | 325 | return in_array($this->scope, $scopes); 326 | } 327 | 328 | /** 329 | * @param string $method HTTP method 330 | * @param string $url 331 | * @param array $param 参数 332 | * @return array 333 | */ 334 | private function getAuthHeaders($method, $url, $params=array(), $headers=array()){ 335 | 336 | //不是云的老用户则不用在header中签名 认证 337 | if($this->isCloudUser === false){ 338 | return $headers; 339 | } 340 | 341 | $obj = parse_url($url); 342 | if(!empty($obj['query'])){ 343 | foreach(explode('&', $obj['query']) as $kv){ 344 | if(!empty($kv)){ 345 | list($k, $v) = explode('=', $kv, 2); 346 | $params[$k] = $v; 347 | } 348 | } 349 | } 350 | 351 | //UTC 时间戳 352 | $timestamp = gmdate('Y-m-d\TH:i:s\Z'); 353 | $headers['Host'] = isset($obj['port']) ? sprintf('%s:%s', $obj['host'], $obj['port']) : $obj['host']; 354 | $headers['x-bce-date'] = $timestamp; 355 | 356 | //签名 357 | $headers['authorization'] = AipSampleSigner::sign(array( 358 | 'ak' => $this->apiKey, 359 | 'sk' => $this->secretKey, 360 | ), $method, $obj['path'], $headers, $params, array( 361 | 'timestamp' => $timestamp, 362 | 'headersToSign' => array_keys($headers), 363 | )); 364 | 365 | return $headers; 366 | } 367 | 368 | /** 369 | * 反馈 370 | * 371 | * @param array $feedbacks 372 | * @return array 373 | */ 374 | public function report($feedback){ 375 | 376 | $data = array(); 377 | 378 | $data['feedback'] = $feedback; 379 | 380 | return $this->request($this->reportUrl, $data); 381 | } 382 | } 383 | -------------------------------------------------------------------------------- /lib/baseocr/AipBCEUtil.php: -------------------------------------------------------------------------------- 1 | $v) { 98 | //跳过Authorization字段 99 | if (strcasecmp('Authorization', $k) == 0) { 100 | continue; 101 | } 102 | if (!isset($k)) { 103 | throw new \InvalidArgumentException( 104 | "parameter key should not be null" 105 | ); 106 | } 107 | if (isset($v)) { 108 | //对于有值的,编码后放在=号两边 109 | $parameterStrings[] = AipHttpUtil::urlEncode($k) 110 | . '=' . AipHttpUtil::urlEncode((string) $v); 111 | } else { 112 | //对于没有值的,只将key编码后放在=号的左边,右边留空 113 | $parameterStrings[] = AipHttpUtil::urlEncode($k) . '='; 114 | } 115 | } 116 | //按照字典序排序 117 | sort($parameterStrings); 118 | 119 | //使用'&'符号连接它们 120 | return implode('&', $parameterStrings); 121 | } 122 | 123 | /** 124 | * 生成标准化uri 125 | * @param string $path 126 | * @return string 127 | */ 128 | public static function getCanonicalURIPath($path) 129 | { 130 | //空路径设置为'/' 131 | if (empty($path)) { 132 | return '/'; 133 | } else { 134 | //所有的uri必须以'/'开头 135 | if ($path[0] == '/') { 136 | return AipHttpUtil::urlEncodeExceptSlash($path); 137 | } else { 138 | return '/' . AipHttpUtil::urlEncodeExceptSlash($path); 139 | } 140 | } 141 | } 142 | 143 | /** 144 | * 生成标准化http请求头串 145 | * @param array $headers 146 | * @return array 147 | */ 148 | public static function getCanonicalHeaders($headers) 149 | { 150 | //如果没有headers,则返回空串 151 | if (count($headers) == 0) { 152 | return ''; 153 | } 154 | 155 | $headerStrings = array(); 156 | foreach ($headers as $k => $v) { 157 | //跳过key为null的 158 | if ($k === null) { 159 | continue; 160 | } 161 | //如果value为null,则赋值为空串 162 | if ($v === null) { 163 | $v = ''; 164 | } 165 | //trim后再encode,之后使用':'号连接起来 166 | $headerStrings[] = AipHttpUtil::urlEncode(strtolower(trim($k))) . ':' . AipHttpUtil::urlEncode(trim($v)); 167 | } 168 | //字典序排序 169 | sort($headerStrings); 170 | 171 | //用'\n'把它们连接起来 172 | return implode("\n", $headerStrings); 173 | } 174 | } 175 | AipHttpUtil::__init(); 176 | 177 | 178 | class AipSignOption 179 | { 180 | const EXPIRATION_IN_SECONDS = 'expirationInSeconds'; 181 | 182 | const HEADERS_TO_SIGN = 'headersToSign'; 183 | 184 | const TIMESTAMP = 'timestamp'; 185 | 186 | const DEFAULT_EXPIRATION_IN_SECONDS = 1800; 187 | 188 | const MIN_EXPIRATION_IN_SECONDS = 300; 189 | 190 | const MAX_EXPIRATION_IN_SECONDS = 129600; 191 | } 192 | 193 | 194 | class AipSampleSigner 195 | { 196 | 197 | const BCE_AUTH_VERSION = "bce-auth-v1"; 198 | const BCE_PREFIX = 'x-bce-'; 199 | 200 | //不指定headersToSign情况下,默认签名http头,包括: 201 | // 1.host 202 | // 2.content-length 203 | // 3.content-type 204 | // 4.content-md5 205 | public static $defaultHeadersToSign; 206 | 207 | public static function __init() 208 | { 209 | AipSampleSigner::$defaultHeadersToSign = array( 210 | "host", 211 | "content-length", 212 | "content-type", 213 | "content-md5", 214 | ); 215 | } 216 | 217 | /** 218 | * 签名 219 | * @param array $credentials 220 | * @param string $httpMethod 221 | * @param string $path 222 | * @param array $headers 223 | * @param string $params 224 | * @param array $options 225 | * @return string 226 | */ 227 | public static function sign( 228 | array $credentials, 229 | $httpMethod, 230 | $path, 231 | $headers, 232 | $params, 233 | $options = array() 234 | ) { 235 | //设定签名有效时间 236 | if (!isset($options[AipSignOption::EXPIRATION_IN_SECONDS])) { 237 | //默认值1800秒 238 | $expirationInSeconds = AipSignOption::DEFAULT_EXPIRATION_IN_SECONDS; 239 | } else { 240 | $expirationInSeconds = $options[AipSignOption::EXPIRATION_IN_SECONDS]; 241 | } 242 | 243 | //解析ak sk 244 | $accessKeyId = $credentials['ak']; 245 | $secretAccessKey = $credentials['sk']; 246 | 247 | //设定时间戳,注意:如果自行指定时间戳需要为UTC时间 248 | if (!isset($options[AipSignOption::TIMESTAMP])) { 249 | //默认值当前时间 250 | $timestamp = gmdate('Y-m-d\TH:i:s\Z'); 251 | } else { 252 | $timestamp = $options[AipSignOption::TIMESTAMP]; 253 | } 254 | 255 | //生成authString 256 | $authString = AipSampleSigner::BCE_AUTH_VERSION . '/' . $accessKeyId . '/' 257 | . $timestamp . '/' . $expirationInSeconds; 258 | 259 | //使用sk和authString生成signKey 260 | $signingKey = hash_hmac('sha256', $authString, $secretAccessKey); 261 | 262 | //生成标准化URI 263 | $canonicalURI = AipHttpUtil::getCanonicalURIPath($path); 264 | 265 | //生成标准化QueryString 266 | $canonicalQueryString = AipHttpUtil::getCanonicalQueryString($params); 267 | 268 | //填充headersToSign,也就是指明哪些header参与签名 269 | $headersToSign = null; 270 | if (isset($options[AipSignOption::HEADERS_TO_SIGN])) { 271 | $headersToSign = $options[AipSignOption::HEADERS_TO_SIGN]; 272 | } 273 | 274 | //生成标准化header 275 | $canonicalHeader = AipHttpUtil::getCanonicalHeaders( 276 | AipSampleSigner::getHeadersToSign($headers, $headersToSign) 277 | ); 278 | 279 | //整理headersToSign,以';'号连接 280 | $signedHeaders = ''; 281 | if ($headersToSign !== null) { 282 | $signedHeaders = strtolower( 283 | trim(implode(";", $headersToSign)) 284 | ); 285 | } 286 | 287 | //组成标准请求串 288 | $canonicalRequest = "$httpMethod\n$canonicalURI\n" 289 | . "$canonicalQueryString\n$canonicalHeader"; 290 | 291 | //使用signKey和标准请求串完成签名 292 | $signature = hash_hmac('sha256', $canonicalRequest, $signingKey); 293 | 294 | //组成最终签名串 295 | $authorizationHeader = "$authString/$signedHeaders/$signature"; 296 | 297 | return $authorizationHeader; 298 | } 299 | 300 | /** 301 | * 根据headsToSign过滤应该参与签名的header 302 | * @param array $headers 303 | * @param array $headersToSign 304 | * @return array 305 | */ 306 | public static function getHeadersToSign($headers, $headersToSign) 307 | { 308 | 309 | //value被trim后为空串的header不参与签名 310 | $filter_empty = function($v) { 311 | return trim((string) $v) !== ''; 312 | }; 313 | $headers = array_filter($headers, $filter_empty); 314 | 315 | //处理headers的key:去掉前后的空白并转化成小写 316 | $trim_and_lower = function($str){ 317 | return strtolower(trim($str)); 318 | }; 319 | $temp = array(); 320 | $process_keys = function($k, $v) use(&$temp, $trim_and_lower) { 321 | $temp[$trim_and_lower($k)] = $v; 322 | }; 323 | array_map($process_keys, array_keys($headers), $headers); 324 | $headers = $temp; 325 | 326 | //取出headers的key以备用 327 | $header_keys = array_keys($headers); 328 | 329 | $filtered_keys = null; 330 | if ($headersToSign !== null) { 331 | //如果有headersToSign,则根据headersToSign过滤 332 | 333 | //预处理headersToSign:去掉前后的空白并转化成小写 334 | $headersToSign = array_map($trim_and_lower, $headersToSign); 335 | 336 | //只选取在headersToSign里面的header 337 | $filtered_keys = array_intersect_key($header_keys, $headersToSign); 338 | 339 | } else { 340 | //如果没有headersToSign,则根据默认规则来选取headers 341 | $filter_by_default = function($k) { 342 | return AipSampleSigner::isDefaultHeaderToSign($k); 343 | }; 344 | $filtered_keys = array_filter($header_keys, $filter_by_default); 345 | } 346 | 347 | //返回需要参与签名的header 348 | return array_intersect_key($headers, array_flip($filtered_keys)); 349 | } 350 | 351 | /** 352 | * 检查header是不是默认参加签名的: 353 | * 1.是host、content-type、content-md5、content-length之一 354 | * 2.以x-bce开头 355 | * @param array $header 356 | * @return boolean 357 | */ 358 | public static function isDefaultHeaderToSign($header) 359 | { 360 | $header = strtolower(trim($header)); 361 | if (in_array($header, AipSampleSigner::$defaultHeadersToSign)) { 362 | return true; 363 | } 364 | return substr_compare($header, AipSampleSigner::BCE_PREFIX, 0, strlen(AipSampleSigner::BCE_PREFIX)) == 0; 365 | } 366 | } 367 | AipSampleSigner::__init(); 368 | -------------------------------------------------------------------------------- /lib/AipOcr.php: -------------------------------------------------------------------------------- 1 | - CHN_ENG:中英文混合;
- ENG:英文;
- POR:葡萄牙语;
- FRE:法语;
- GER:德语;
- ITA:意大利语;
- SPA:西班牙语;
- RUS:俄语;
- JAP:日语;
- KOR:韩语; 127 | * detect_direction 是否检测图像朝向,默认不检测,即:false。朝向是指输入图像是正常方向、逆时针旋转90/180/270度。可选值包括:
- true:检测朝向;
- false:不检测朝向。 128 | * detect_language 是否检测语言,默认不检测。当前支持(中文、英语、日语、韩语) 129 | * probability 是否返回识别结果中每一行的置信度 130 | * @return array 131 | */ 132 | public function basicGeneral($image, $options=array()){ 133 | 134 | $data = array(); 135 | 136 | $data['image'] = base64_encode($image); 137 | 138 | $data = array_merge($data, $options); 139 | 140 | return $this->request($this->generalBasicUrl, $data); 141 | } 142 | 143 | /** 144 | * 通用文字识别接口 145 | * 146 | * @param string $url - 图片完整URL,URL长度不超过1024字节,URL对应的图片base64编码后大小不超过4M,最短边至少15px,最长边最大4096px,支持jpg/png/bmp格式,当image字段存在时url字段失效 147 | * @param array $options - 可选参数对象,key: value都为string类型 148 | * @description options列表: 149 | * language_type 识别语言类型,默认为CHN_ENG。可选值包括:
- CHN_ENG:中英文混合;
- ENG:英文;
- POR:葡萄牙语;
- FRE:法语;
- GER:德语;
- ITA:意大利语;
- SPA:西班牙语;
- RUS:俄语;
- JAP:日语;
- KOR:韩语; 150 | * detect_direction 是否检测图像朝向,默认不检测,即:false。朝向是指输入图像是正常方向、逆时针旋转90/180/270度。可选值包括:
- true:检测朝向;
- false:不检测朝向。 151 | * detect_language 是否检测语言,默认不检测。当前支持(中文、英语、日语、韩语) 152 | * probability 是否返回识别结果中每一行的置信度 153 | * @return array 154 | */ 155 | public function basicGeneralUrl($url, $options=array()){ 156 | 157 | $data = array(); 158 | 159 | $data['url'] = $url; 160 | 161 | $data = array_merge($data, $options); 162 | 163 | return $this->request($this->generalBasicUrl, $data); 164 | } 165 | 166 | /** 167 | * 通用文字识别(高精度版)接口 168 | * 169 | * @param string $image - 图像数据,base64编码,要求base64编码后大小不超过4M,最短边至少15px,最长边最大4096px,支持jpg/png/bmp格式 170 | * @param array $options - 可选参数对象,key: value都为string类型 171 | * @description options列表: 172 | * detect_direction 是否检测图像朝向,默认不检测,即:false。朝向是指输入图像是正常方向、逆时针旋转90/180/270度。可选值包括:
- true:检测朝向;
- false:不检测朝向。 173 | * probability 是否返回识别结果中每一行的置信度 174 | * @return array 175 | */ 176 | public function basicAccurate($image, $options=array()){ 177 | 178 | $data = array(); 179 | 180 | $data['image'] = base64_encode($image); 181 | 182 | $data = array_merge($data, $options); 183 | 184 | return $this->request($this->accurateBasicUrl, $data); 185 | } 186 | 187 | /** 188 | * 通用文字识别(含位置信息版)接口 189 | * 190 | * @param string $image - 图像数据,base64编码,要求base64编码后大小不超过4M,最短边至少15px,最长边最大4096px,支持jpg/png/bmp格式 191 | * @param array $options - 可选参数对象,key: value都为string类型 192 | * @description options列表: 193 | * recognize_granularity 是否定位单字符位置,big:不定位单字符位置,默认值;small:定位单字符位置 194 | * language_type 识别语言类型,默认为CHN_ENG。可选值包括:
- CHN_ENG:中英文混合;
- ENG:英文;
- POR:葡萄牙语;
- FRE:法语;
- GER:德语;
- ITA:意大利语;
- SPA:西班牙语;
- RUS:俄语;
- JAP:日语;
- KOR:韩语; 195 | * detect_direction 是否检测图像朝向,默认不检测,即:false。朝向是指输入图像是正常方向、逆时针旋转90/180/270度。可选值包括:
- true:检测朝向;
- false:不检测朝向。 196 | * detect_language 是否检测语言,默认不检测。当前支持(中文、英语、日语、韩语) 197 | * vertexes_location 是否返回文字外接多边形顶点位置,不支持单字位置。默认为false 198 | * probability 是否返回识别结果中每一行的置信度 199 | * @return array 200 | */ 201 | public function general($image, $options=array()){ 202 | 203 | $data = array(); 204 | 205 | $data['image'] = base64_encode($image); 206 | 207 | $data = array_merge($data, $options); 208 | 209 | return $this->request($this->generalUrl, $data); 210 | } 211 | 212 | /** 213 | * 通用文字识别(含位置信息版)接口 214 | * 215 | * @param string $url - 图片完整URL,URL长度不超过1024字节,URL对应的图片base64编码后大小不超过4M,最短边至少15px,最长边最大4096px,支持jpg/png/bmp格式,当image字段存在时url字段失效 216 | * @param array $options - 可选参数对象,key: value都为string类型 217 | * @description options列表: 218 | * recognize_granularity 是否定位单字符位置,big:不定位单字符位置,默认值;small:定位单字符位置 219 | * language_type 识别语言类型,默认为CHN_ENG。可选值包括:
- CHN_ENG:中英文混合;
- ENG:英文;
- POR:葡萄牙语;
- FRE:法语;
- GER:德语;
- ITA:意大利语;
- SPA:西班牙语;
- RUS:俄语;
- JAP:日语;
- KOR:韩语; 220 | * detect_direction 是否检测图像朝向,默认不检测,即:false。朝向是指输入图像是正常方向、逆时针旋转90/180/270度。可选值包括:
- true:检测朝向;
- false:不检测朝向。 221 | * detect_language 是否检测语言,默认不检测。当前支持(中文、英语、日语、韩语) 222 | * vertexes_location 是否返回文字外接多边形顶点位置,不支持单字位置。默认为false 223 | * probability 是否返回识别结果中每一行的置信度 224 | * @return array 225 | */ 226 | public function generalUrl($url, $options=array()){ 227 | 228 | $data = array(); 229 | 230 | $data['url'] = $url; 231 | 232 | $data = array_merge($data, $options); 233 | 234 | return $this->request($this->generalUrl, $data); 235 | } 236 | 237 | /** 238 | * 通用文字识别(含位置高精度版)接口 239 | * 240 | * @param string $image - 图像数据,base64编码,要求base64编码后大小不超过4M,最短边至少15px,最长边最大4096px,支持jpg/png/bmp格式 241 | * @param array $options - 可选参数对象,key: value都为string类型 242 | * @description options列表: 243 | * recognize_granularity 是否定位单字符位置,big:不定位单字符位置,默认值;small:定位单字符位置 244 | * detect_direction 是否检测图像朝向,默认不检测,即:false。朝向是指输入图像是正常方向、逆时针旋转90/180/270度。可选值包括:
- true:检测朝向;
- false:不检测朝向。 245 | * vertexes_location 是否返回文字外接多边形顶点位置,不支持单字位置。默认为false 246 | * probability 是否返回识别结果中每一行的置信度 247 | * @return array 248 | */ 249 | public function accurate($image, $options=array()){ 250 | 251 | $data = array(); 252 | 253 | $data['image'] = base64_encode($image); 254 | 255 | $data = array_merge($data, $options); 256 | 257 | return $this->request($this->accurateUrl, $data); 258 | } 259 | 260 | /** 261 | * 通用文字识别(含生僻字版)接口 262 | * 263 | * @param string $image - 图像数据,base64编码,要求base64编码后大小不超过4M,最短边至少15px,最长边最大4096px,支持jpg/png/bmp格式 264 | * @param array $options - 可选参数对象,key: value都为string类型 265 | * @description options列表: 266 | * language_type 识别语言类型,默认为CHN_ENG。可选值包括:
- CHN_ENG:中英文混合;
- ENG:英文;
- POR:葡萄牙语;
- FRE:法语;
- GER:德语;
- ITA:意大利语;
- SPA:西班牙语;
- RUS:俄语;
- JAP:日语;
- KOR:韩语; 267 | * detect_direction 是否检测图像朝向,默认不检测,即:false。朝向是指输入图像是正常方向、逆时针旋转90/180/270度。可选值包括:
- true:检测朝向;
- false:不检测朝向。 268 | * detect_language 是否检测语言,默认不检测。当前支持(中文、英语、日语、韩语) 269 | * probability 是否返回识别结果中每一行的置信度 270 | * @return array 271 | */ 272 | public function enhancedGeneral($image, $options=array()){ 273 | 274 | $data = array(); 275 | 276 | $data['image'] = base64_encode($image); 277 | 278 | $data = array_merge($data, $options); 279 | 280 | return $this->request($this->generalEnhancedUrl, $data); 281 | } 282 | 283 | /** 284 | * 通用文字识别(含生僻字版)接口 285 | * 286 | * @param string $url - 图片完整URL,URL长度不超过1024字节,URL对应的图片base64编码后大小不超过4M,最短边至少15px,最长边最大4096px,支持jpg/png/bmp格式,当image字段存在时url字段失效 287 | * @param array $options - 可选参数对象,key: value都为string类型 288 | * @description options列表: 289 | * language_type 识别语言类型,默认为CHN_ENG。可选值包括:
- CHN_ENG:中英文混合;
- ENG:英文;
- POR:葡萄牙语;
- FRE:法语;
- GER:德语;
- ITA:意大利语;
- SPA:西班牙语;
- RUS:俄语;
- JAP:日语;
- KOR:韩语; 290 | * detect_direction 是否检测图像朝向,默认不检测,即:false。朝向是指输入图像是正常方向、逆时针旋转90/180/270度。可选值包括:
- true:检测朝向;
- false:不检测朝向。 291 | * detect_language 是否检测语言,默认不检测。当前支持(中文、英语、日语、韩语) 292 | * probability 是否返回识别结果中每一行的置信度 293 | * @return array 294 | */ 295 | public function enhancedGeneralUrl($url, $options=array()){ 296 | 297 | $data = array(); 298 | 299 | $data['url'] = $url; 300 | 301 | $data = array_merge($data, $options); 302 | 303 | return $this->request($this->generalEnhancedUrl, $data); 304 | } 305 | 306 | /** 307 | * 网络图片文字识别接口 308 | * 309 | * @param string $image - 图像数据,base64编码,要求base64编码后大小不超过4M,最短边至少15px,最长边最大4096px,支持jpg/png/bmp格式 310 | * @param array $options - 可选参数对象,key: value都为string类型 311 | * @description options列表: 312 | * detect_direction 是否检测图像朝向,默认不检测,即:false。朝向是指输入图像是正常方向、逆时针旋转90/180/270度。可选值包括:
- true:检测朝向;
- false:不检测朝向。 313 | * detect_language 是否检测语言,默认不检测。当前支持(中文、英语、日语、韩语) 314 | * @return array 315 | */ 316 | public function webImage($image, $options=array()){ 317 | 318 | $data = array(); 319 | 320 | $data['image'] = base64_encode($image); 321 | 322 | $data = array_merge($data, $options); 323 | 324 | return $this->request($this->webImageUrl, $data); 325 | } 326 | 327 | /** 328 | * 网络图片文字识别接口 329 | * 330 | * @param string $url - 图片完整URL,URL长度不超过1024字节,URL对应的图片base64编码后大小不超过4M,最短边至少15px,最长边最大4096px,支持jpg/png/bmp格式,当image字段存在时url字段失效 331 | * @param array $options - 可选参数对象,key: value都为string类型 332 | * @description options列表: 333 | * detect_direction 是否检测图像朝向,默认不检测,即:false。朝向是指输入图像是正常方向、逆时针旋转90/180/270度。可选值包括:
- true:检测朝向;
- false:不检测朝向。 334 | * detect_language 是否检测语言,默认不检测。当前支持(中文、英语、日语、韩语) 335 | * @return array 336 | */ 337 | public function webImageUrl($url, $options=array()){ 338 | 339 | $data = array(); 340 | 341 | $data['url'] = $url; 342 | 343 | $data = array_merge($data, $options); 344 | 345 | return $this->request($this->webImageUrl, $data); 346 | } 347 | 348 | /** 349 | * 身份证识别接口 350 | * 351 | * @param string $image - 图像数据,base64编码,要求base64编码后大小不超过4M,最短边至少15px,最长边最大4096px,支持jpg/png/bmp格式 352 | * @param string $idCardSide - front:身份证正面;back:身份证背面 353 | * @param array $options - 可选参数对象,key: value都为string类型 354 | * @description options列表: 355 | * detect_direction 是否检测图像朝向,默认不检测,即:false。朝向是指输入图像是正常方向、逆时针旋转90/180/270度。可选值包括:
- true:检测朝向;
- false:不检测朝向。 356 | * detect_risk 是否开启身份证风险类型(身份证复印件、临时身份证、身份证翻拍、修改过的身份证)功能,默认不开启,即:false。可选值:true-开启;false-不开启 357 | * @return array 358 | */ 359 | public function idcard($image, $idCardSide, $options=array()){ 360 | 361 | $data = array(); 362 | 363 | $data['image'] = base64_encode($image); 364 | $data['id_card_side'] = $idCardSide; 365 | 366 | $data = array_merge($data, $options); 367 | 368 | return $this->request($this->idcardUrl, $data); 369 | } 370 | 371 | /** 372 | * 银行卡识别接口 373 | * 374 | * @param string $image - 图像数据,base64编码,要求base64编码后大小不超过4M,最短边至少15px,最长边最大4096px,支持jpg/png/bmp格式 375 | * @param array $options - 可选参数对象,key: value都为string类型 376 | * @description options列表: 377 | * @return array 378 | */ 379 | public function bankcard($image, $options=array()){ 380 | 381 | $data = array(); 382 | 383 | $data['image'] = base64_encode($image); 384 | 385 | $data = array_merge($data, $options); 386 | 387 | return $this->request($this->bankcardUrl, $data); 388 | } 389 | 390 | /** 391 | * 驾驶证识别接口 392 | * 393 | * @param string $image - 图像数据,base64编码,要求base64编码后大小不超过4M,最短边至少15px,最长边最大4096px,支持jpg/png/bmp格式 394 | * @param array $options - 可选参数对象,key: value都为string类型 395 | * @description options列表: 396 | * detect_direction 是否检测图像朝向,默认不检测,即:false。朝向是指输入图像是正常方向、逆时针旋转90/180/270度。可选值包括:
- true:检测朝向;
- false:不检测朝向。 397 | * @return array 398 | */ 399 | public function drivingLicense($image, $options=array()){ 400 | 401 | $data = array(); 402 | 403 | $data['image'] = base64_encode($image); 404 | 405 | $data = array_merge($data, $options); 406 | 407 | return $this->request($this->drivingLicenseUrl, $data); 408 | } 409 | 410 | /** 411 | * 行驶证识别接口 412 | * 413 | * @param string $image - 图像数据,base64编码,要求base64编码后大小不超过4M,最短边至少15px,最长边最大4096px,支持jpg/png/bmp格式 414 | * @param array $options - 可选参数对象,key: value都为string类型 415 | * @description options列表: 416 | * detect_direction 是否检测图像朝向,默认不检测,即:false。朝向是指输入图像是正常方向、逆时针旋转90/180/270度。可选值包括:
- true:检测朝向;
- false:不检测朝向。 417 | * accuracy normal 使用快速服务,1200ms左右时延;缺省或其它值使用高精度服务,1600ms左右时延 418 | * @return array 419 | */ 420 | public function vehicleLicense($image, $options=array()){ 421 | 422 | $data = array(); 423 | 424 | $data['image'] = base64_encode($image); 425 | 426 | $data = array_merge($data, $options); 427 | 428 | return $this->request($this->vehicleLicenseUrl, $data); 429 | } 430 | 431 | /** 432 | * 车牌识别接口 433 | * 434 | * @param string $image - 图像数据,base64编码,要求base64编码后大小不超过4M,最短边至少15px,最长边最大4096px,支持jpg/png/bmp格式 435 | * @param array $options - 可选参数对象,key: value都为string类型 436 | * @description options列表: 437 | * multi_detect 是否检测多张车牌,默认为false,当置为true的时候可以对一张图片内的多张车牌进行识别 438 | * @return array 439 | */ 440 | public function licensePlate($image, $options=array()){ 441 | 442 | $data = array(); 443 | 444 | $data['image'] = base64_encode($image); 445 | 446 | $data = array_merge($data, $options); 447 | 448 | return $this->request($this->licensePlateUrl, $data); 449 | } 450 | 451 | /** 452 | * 营业执照识别接口 453 | * 454 | * @param string $image - 图像数据,base64编码,要求base64编码后大小不超过4M,最短边至少15px,最长边最大4096px,支持jpg/png/bmp格式 455 | * @param array $options - 可选参数对象,key: value都为string类型 456 | * @description options列表: 457 | * @return array 458 | */ 459 | public function businessLicense($image, $options=array()){ 460 | 461 | $data = array(); 462 | 463 | $data['image'] = base64_encode($image); 464 | 465 | $data = array_merge($data, $options); 466 | 467 | return $this->request($this->businessLicenseUrl, $data); 468 | } 469 | 470 | /** 471 | * 通用票据识别接口 472 | * 473 | * @param string $image - 图像数据,base64编码,要求base64编码后大小不超过4M,最短边至少15px,最长边最大4096px,支持jpg/png/bmp格式 474 | * @param array $options - 可选参数对象,key: value都为string类型 475 | * @description options列表: 476 | * recognize_granularity 是否定位单字符位置,big:不定位单字符位置,默认值;small:定位单字符位置 477 | * probability 是否返回识别结果中每一行的置信度 478 | * accuracy normal 使用快速服务,1200ms左右时延;缺省或其它值使用高精度服务,1600ms左右时延 479 | * detect_direction 是否检测图像朝向,默认不检测,即:false。朝向是指输入图像是正常方向、逆时针旋转90/180/270度。可选值包括:
- true:检测朝向;
- false:不检测朝向。 480 | * @return array 481 | */ 482 | public function receipt($image, $options=array()){ 483 | 484 | $data = array(); 485 | 486 | $data['image'] = base64_encode($image); 487 | 488 | $data = array_merge($data, $options); 489 | 490 | return $this->request($this->receiptUrl, $data); 491 | } 492 | 493 | /** 494 | * 自定义模版文字识别接口 495 | * 496 | * @param string $image - 图像数据,base64编码,要求base64编码后大小不超过4M,最短边至少15px,最长边最大4096px,支持jpg/png/bmp格式 497 | * @param string $templateSign - 您在自定义文字识别平台制作的模版的ID 498 | * @param array $options - 可选参数对象,key: value都为string类型 499 | * @description options列表: 500 | * @return array 501 | */ 502 | public function custom($image, $templateSign, $options=array()){ 503 | 504 | $data = array(); 505 | 506 | $data['image'] = base64_encode($image); 507 | $data['templateSign'] = $templateSign; 508 | 509 | $data = array_merge($data, $options); 510 | 511 | return $this->request($this->customUrl, $data); 512 | } 513 | 514 | /** 515 | * 表格文字识别接口 516 | * 517 | * @param string $image - 图像数据,base64编码,要求base64编码后大小不超过4M,最短边至少15px,最长边最大4096px,支持jpg/png/bmp格式 518 | * @param array $options - 可选参数对象,key: value都为string类型 519 | * @description options列表: 520 | * @return array 521 | */ 522 | public function tableRecognitionAsync($image, $options=array()){ 523 | 524 | $data = array(); 525 | 526 | $data['image'] = base64_encode($image); 527 | 528 | $data = array_merge($data, $options); 529 | 530 | return $this->request($this->tableRecognizeUrl, $data); 531 | } 532 | 533 | /** 534 | * 表格识别结果接口 535 | * 536 | * @param string $requestId - 发送表格文字识别请求时返回的request id 537 | * @param array $options - 可选参数对象,key: value都为string类型 538 | * @description options列表: 539 | * result_type 期望获取结果的类型,取值为“excel”时返回xls文件的地址,取值为“json”时返回json格式的字符串,默认为”excel” 540 | * @return array 541 | */ 542 | public function getTableRecognitionResult($requestId, $options=array()){ 543 | 544 | $data = array(); 545 | 546 | $data['request_id'] = $requestId; 547 | 548 | $data = array_merge($data, $options); 549 | 550 | return $this->request($this->tableResultGetUrl, $data); 551 | } 552 | 553 | /** 554 | * 同步请求 555 | * @param string $image 图像读取 556 | * @param options 接口可选参数 557 | * @return array 558 | */ 559 | public function tableRecognition($image, $options=array(), $timeout=10000){ 560 | $result = $this->tableRecognitionAsync($image); 561 | if(isset($result['error_code'])){ 562 | return $result; 563 | } 564 | $requestId = $result['result'][0]['request_id']; 565 | $count = ceil($timeout / 1000); 566 | for($i=0; $i<$count; $i++){ 567 | $result = $this->getTableRecognitionResult($requestId, $options); 568 | // 完成 569 | if($result['result']['ret_code'] == 3){ 570 | break; 571 | } 572 | sleep(1); 573 | } 574 | return $result; 575 | } 576 | 577 | } 578 | 579 | --------------------------------------------------------------------------------