企微短剧业务系统

YXRequestService.php 4.6KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131
  1. <?php
  2. namespace App\Service\YunXuan;
  3. use App\Log;
  4. use App\Service\HttpService;
  5. use App\Support\EmailQueue;
  6. class YXRequestService
  7. {
  8. const FORM_URLENCODED = "application/x-www-form-urlencoded";
  9. public static function getSortedParameterStr($paramArr)
  10. {
  11. ksort($paramArr);
  12. $tmpArr = array();
  13. foreach ($paramArr as $k => $v) {
  14. $tmp = $k;
  15. if (!empty($v)) {
  16. $tmp .= ("=" . $v);
  17. }
  18. array_push($tmpArr, $tmp);
  19. }
  20. return join('&', $tmpArr);
  21. }
  22. /**
  23. * Send a HTTP request with App Authorization
  24. *
  25. * @param $apiAppKey string AppKey
  26. * @param $apiAppSecret string AppSecret
  27. * @param $method string HTTP Method of API
  28. * @param $url string Request URL of API, note that environment path (/release) is not allowed
  29. * @param $contentType string Request Content-Type header, set empty if request body is not needed
  30. * @param $acceptHeader string Accept HTTP request header
  31. * @param $reqBody string Request Body, set null if request body is not needed
  32. * @param $formParam array form parameters array, set null if not form request
  33. * @param $algorithm string Encryption algorithm: sha1, sha256, sha384, sha512, SM3, default to sha1
  34. * @param $customHeaders array Custom HTTP Headers, such as `array('x-header-a' => 1)`
  35. */
  36. public static function sendRequestWithAppAuth(
  37. $apiAppKey, $apiAppSecret, $method, $url, $contentType, $acceptHeader, $reqBody=null,
  38. $formParam=null, $algorithm=null, $customHeaders=null
  39. )
  40. {
  41. $contentMD5 = "";
  42. $isForm = ($contentType == self::FORM_URLENCODED);
  43. if ($isForm) {
  44. assert(!is_null($formParam), "formParam is required for form request");
  45. // generate request body from form parameters
  46. $reqBody = self::getSortedParameterStr($formParam);
  47. } elseif (!is_null($reqBody)) {
  48. // get content md5 for signing the request later
  49. $contentMD5 = base64_encode(md5($reqBody));
  50. }
  51. if (null === $algorithm) {
  52. $algorithm = "sha1";
  53. }
  54. $paramArr = array();
  55. $parsedUrl = parse_url($url);
  56. if (isset($parsedUrl['query']) && !is_null($parsedUrl['query']) && !empty($parsedUrl['query'])) {
  57. parse_str($parsedUrl['query'], $paramArr);
  58. }
  59. if (!empty($formParam)) {
  60. $paramArr = array_merge($paramArr, $formParam);
  61. }
  62. $pathAndParam = $parsedUrl['path'];
  63. if (!empty($paramArr)) {
  64. $pathAndParam = $pathAndParam . '?' . self::getSortedParameterStr($paramArr);
  65. }
  66. $xDateHeader = gmstrftime('%a, %d %b %Y %T %Z', time());
  67. $strToSign = sprintf(
  68. "x-date: %s\n%s\n%s\n%s\n%s\n%s", $xDateHeader, $method, $acceptHeader, $contentType, $contentMD5, $pathAndParam
  69. );
  70. // $strToSignDebug = str_replace("\n", "#", $strToSign);
  71. $sign = base64_encode(hash_hmac($algorithm, $strToSign, $apiAppSecret, TRUE));
  72. $authHeader = sprintf(
  73. 'hmac id="%s", algorithm="hmac-%s", headers="x-date", signature="%s"',
  74. $apiAppKey, $algorithm, $sign
  75. );
  76. $headers = array(
  77. 'Host:' . $parsedUrl['host'],
  78. 'Accept:' . $acceptHeader,
  79. 'X-Date:' . $xDateHeader,
  80. 'Authorization:' . $authHeader,
  81. );
  82. if (!empty($contentType)) {
  83. array_push($headers, "Content-Type:" . $contentType);
  84. }
  85. if (!empty($contentMD5)) {
  86. array_push($headers, "Content-MD5:" . $contentMD5);
  87. }
  88. if (!is_null($customHeaders) && is_array($customHeaders)) {
  89. foreach ($customHeaders as $k => $v) {
  90. array_push($headers, $k . ":" . $v);
  91. }
  92. }
  93. $ch = curl_init();
  94. curl_setopt($ch, CURLOPT_URL, $url);
  95. curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
  96. curl_setopt($ch, CURLOPT_TIMEOUT, 60);
  97. if (!empty($reqBody)) {
  98. curl_setopt($ch, CURLOPT_POSTFIELDS, $reqBody); // only required if request body is present
  99. }
  100. curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
  101. curl_setopt($ch, CURLOPT_CUSTOMREQUEST, $method);
  102. $data = curl_exec($ch);
  103. if (curl_errno($ch)) {
  104. Log::logError('云选联盟接口请求失败', ['error' => curl_error($ch)], 'YXRequest');
  105. return false;
  106. }
  107. Log::logError('云选联盟接口返回结果', [
  108. 'method' => $method, 'url' => $url, 'form_param' => $formParam, 'data' => $data, 'req_body' => $reqBody
  109. ], 'YXRequest');
  110. curl_close($ch);
  111. return $data;
  112. }
  113. }