1. <?php
  2. namespace app\component\AliSdk;
  3. use think\facade\Env;
  4. use Monolog\Logger;
  5. use Monolog\Handler\StreamHandler;
  6. use app\common\ImgConverToData;
  7. use app\common\exception\CommonException;
  8. use app\common\exception\RuntimeException;
  9. /**
  10. * 身份证自动识别
  11. */
  12. class IdcardOcrService
  13. {
  14. /**
  15. * API url
  16. *
  17. * @var string
  18. */
  19. protected $url = 'https://dm-51.data.aliyun.com/rest/160601/ocr/ocr_idcard.json';
  20. /**
  21. * API appCode
  22. *
  23. * @var string
  24. */
  25. protected $appCode = 'f29a4ae1e9104be5b8b2473434a897f5';
  26. protected $sideType = array('face', 'back');
  27. /**
  28. * API errorMsg
  29. *
  30. * @var string
  31. */
  32. protected $errorMsg = array(
  33. '400' => 'URL错误',
  34. '403' => '没有购买,或者购买次数用尽,或者URL错误',
  35. '408' => '超时',
  36. '413' => 'request body太大',
  37. '450' => '后端服务队列满,请求被拒绝,重试即可',
  38. '460' => '上传的body不符合json格式要求,是非法json',
  39. '461' => '输入Json中缺少image键',
  40. '462' => '从URL下载图像失败',
  41. '463' => '输入图像不是对应服务的图像,如身份证服务请求的不是身份证',
  42. '464' => 'OCR识别失败',
  43. '469' => '内部异常',
  44. '502' => '识别程序超时并断开连接',
  45. '503' => 'API网关等待超时断开连接',
  46. );
  47. /**
  48. * Logger
  49. *
  50. * @var LoggerInterface
  51. */
  52. protected $logger;
  53. public function __construct()
  54. {
  55. $this->setLogger();
  56. }
  57. public function setLogger()
  58. {
  59. $logger = new Logger('AliyunSDK');
  60. $logger->pushHandler(new StreamHandler(rtrim(Env::get('RUNTIME_PATH'), '/') . '/log/aliyun.log', Logger::DEBUG));
  61. $this->logger = $logger;
  62. return $this;
  63. }
  64. /**
  65. * 身份证识别
  66. *
  67. * @param [type] $idcardPath 身份证路径
  68. * @param [type] $side 正面/反面 face/back
  69. * @return void
  70. */
  71. public function ocr($idcardPath, $side = 'face')
  72. {
  73. if (empty($idcardPath)) {
  74. throw new RuntimeException('文件不存在!');
  75. }
  76. if (!in_array($side, $this->sideType)) {
  77. throw CommonException::IDCARD_SIDE_ERROR();
  78. }
  79. $imgConverToData = new ImgConverToData();
  80. $imgConverToData->getImgDir($idcardPath);
  81. $imgData = $imgConverToData->img2Data();
  82. $params = array();
  83. $params['image'] = base64_encode($imgData);
  84. $params["configure"] = json_encode(array(
  85. "side" => $side
  86. ));
  87. return $this->_post($this->url, $params);
  88. }
  89. protected function _post($url, $params = array())
  90. {
  91. $headers = array();
  92. $headers[] = 'Authorization: APPCODE ' . $this->appCode;
  93. $headers[] = 'Content-type: application/json; charset=UTF-8';
  94. $curl = curl_init();
  95. curl_setopt($curl, CURLOPT_CUSTOMREQUEST, 'POST');
  96. curl_setopt($curl, CURLOPT_URL, $url);
  97. curl_setopt($curl, CURLOPT_HTTPHEADER, $headers);
  98. curl_setopt($curl, CURLOPT_FAILONERROR, false);
  99. curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
  100. curl_setopt($curl, CURLOPT_HEADER, true);
  101. if (1 == strpos("$" . $url, "https://")) {
  102. curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, false);
  103. curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, false);
  104. }
  105. curl_setopt($curl, CURLOPT_POSTFIELDS, json_encode($params));
  106. $response = curl_exec($curl);
  107. $curlinfo = curl_getinfo($curl);
  108. $header = substr($response, 0, $curlinfo['header_size']);
  109. $body = substr($response, $curlinfo['header_size']);
  110. $code = curl_getinfo($curl, CURLINFO_HTTP_CODE);
  111. curl_close($curl);
  112. $context = array(
  113. 'CURLINFO' => $curlinfo,
  114. 'HEADER' => $header,
  115. 'BODY' => $body,
  116. );
  117. if ($code != 200) {
  118. $this->logger && $this->logger->error('IDCARD_OCR_ERROR', $context);
  119. throw new RuntimeException($this->errorMsg[$code], $code);
  120. }
  121. $result = json_decode($body, true);
  122. if (empty($result)) {
  123. $result = array('detailedMsg' => $body);
  124. }
  125. return $result;
  126. }
  127. }

返回示例

  1. 正面返回结果:
  2. {
  3. "address" : "浙江省杭州市余杭区文一西路969号", #地址信息
  4. "config_str" : "{\\\"side\\\":\\\"face\\\"}", #配置信息,同输入configure
  5. "face_rect":{
  6. "angle": -90,
  7. "center":{
  8. "x" : 952,
  9. "y" : 325.5
  10. },
  11. "size":{
  12. "height":181.99,
  13. "width":164.99
  14. }
  15. }, #人脸位置,center表示人脸矩形中心坐标,size表示人脸矩形长宽,angle表示矩形顺时针旋转的度数。
  16. "name" : "张三", #姓名
  17. "nationality": "汉" #民族
  18. "num" : "1234567890", #身份证号
  19. "sex" : "男", #性别
  20. "birth" : "20000101", #出生日期
  21. "nationality" : "汉", #民族
  22. "success" : true #识别结果,true表示成功,false表示失败
  23. }
  24. 反面返回结果:
  25. {
  26. "config_str" : "{\\\"side\\\":\\\"back\\\"}",#配置信息,同输入configure
  27. "start_date" : "19700101", #有效期起始时间
  28. "end_date" : "19800101", #有效期结束时间
  29. "issue" : "杭州市公安局", #签发机关
  30. "success" : true #识别结果,true表示成功,false表示失败
  31. }