<?phpnamespace app\component\AliSdk;use think\facade\Env;use Monolog\Logger;use Monolog\Handler\StreamHandler;use app\common\ImgConverToData;use app\common\exception\CommonException;use app\common\exception\RuntimeException;/** * 身份证自动识别 */class IdcardOcrService{ /** * API url * * @var string */ protected $url = 'https://dm-51.data.aliyun.com/rest/160601/ocr/ocr_idcard.json'; /** * API appCode * * @var string */ protected $appCode = 'f29a4ae1e9104be5b8b2473434a897f5'; protected $sideType = array('face', 'back'); /** * API errorMsg * * @var string */ protected $errorMsg = array( '400' => 'URL错误', '403' => '没有购买,或者购买次数用尽,或者URL错误', '408' => '超时', '413' => 'request body太大', '450' => '后端服务队列满,请求被拒绝,重试即可', '460' => '上传的body不符合json格式要求,是非法json', '461' => '输入Json中缺少image键', '462' => '从URL下载图像失败', '463' => '输入图像不是对应服务的图像,如身份证服务请求的不是身份证', '464' => 'OCR识别失败', '469' => '内部异常', '502' => '识别程序超时并断开连接', '503' => 'API网关等待超时断开连接', ); /** * Logger * * @var LoggerInterface */ protected $logger; public function __construct() { $this->setLogger(); } public function setLogger() { $logger = new Logger('AliyunSDK'); $logger->pushHandler(new StreamHandler(rtrim(Env::get('RUNTIME_PATH'), '/') . '/log/aliyun.log', Logger::DEBUG)); $this->logger = $logger; return $this; } /** * 身份证识别 * * @param [type] $idcardPath 身份证路径 * @param [type] $side 正面/反面 face/back * @return void */ public function ocr($idcardPath, $side = 'face') { if (empty($idcardPath)) { throw new RuntimeException('文件不存在!'); } if (!in_array($side, $this->sideType)) { throw CommonException::IDCARD_SIDE_ERROR(); } $imgConverToData = new ImgConverToData(); $imgConverToData->getImgDir($idcardPath); $imgData = $imgConverToData->img2Data(); $params = array(); $params['image'] = base64_encode($imgData); $params["configure"] = json_encode(array( "side" => $side )); return $this->_post($this->url, $params); } protected function _post($url, $params = array()) { $headers = array(); $headers[] = 'Authorization: APPCODE ' . $this->appCode; $headers[] = 'Content-type: application/json; charset=UTF-8'; $curl = curl_init(); curl_setopt($curl, CURLOPT_CUSTOMREQUEST, 'POST'); curl_setopt($curl, CURLOPT_URL, $url); curl_setopt($curl, CURLOPT_HTTPHEADER, $headers); curl_setopt($curl, CURLOPT_FAILONERROR, false); curl_setopt($curl, CURLOPT_RETURNTRANSFER, true); curl_setopt($curl, CURLOPT_HEADER, true); if (1 == strpos("$" . $url, "https://")) { curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, false); curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, false); } curl_setopt($curl, CURLOPT_POSTFIELDS, json_encode($params)); $response = curl_exec($curl); $curlinfo = curl_getinfo($curl); $header = substr($response, 0, $curlinfo['header_size']); $body = substr($response, $curlinfo['header_size']); $code = curl_getinfo($curl, CURLINFO_HTTP_CODE); curl_close($curl); $context = array( 'CURLINFO' => $curlinfo, 'HEADER' => $header, 'BODY' => $body, ); if ($code != 200) { $this->logger && $this->logger->error('IDCARD_OCR_ERROR', $context); throw new RuntimeException($this->errorMsg[$code], $code); } $result = json_decode($body, true); if (empty($result)) { $result = array('detailedMsg' => $body); } return $result; }}
返回示例
正面返回结果:{ "address" : "浙江省杭州市余杭区文一西路969号", #地址信息 "config_str" : "{\\\"side\\\":\\\"face\\\"}", #配置信息,同输入configure "face_rect":{ "angle": -90, "center":{ "x" : 952, "y" : 325.5 }, "size":{ "height":181.99, "width":164.99 } }, #人脸位置,center表示人脸矩形中心坐标,size表示人脸矩形长宽,angle表示矩形顺时针旋转的度数。 "name" : "张三", #姓名 "nationality": "汉", #民族 "num" : "1234567890", #身份证号 "sex" : "男", #性别 "birth" : "20000101", #出生日期 "nationality" : "汉", #民族 "success" : true #识别结果,true表示成功,false表示失败}反面返回结果:{ "config_str" : "{\\\"side\\\":\\\"back\\\"}",#配置信息,同输入configure "start_date" : "19700101", #有效期起始时间 "end_date" : "19800101", #有效期结束时间 "issue" : "杭州市公安局", #签发机关 "success" : true #识别结果,true表示成功,false表示失败}