Appearance
PHP调用示例
php
<?php
if (1) {
$phpCaller = new HttpCaller();
$url = "https://api-one.digitalhainan.com.cn/apione";
$api = "getUserIdByAuthCode";// getUserIdByAuthCode
$version = '1.0';
$ak = 'ak';
$sk = 'sk';
$data = ['tenantId' => 1];
$region = "INTER";
$result = null;
$inputHeaders[] = "Authorization:Bearer token";
$inputHeaders[] = "Uaa-App-Key:xxx";
try {
$result = $phpCaller->doPostJsonString($url, $data, $region, $api, $version, $ak, $sk, $inputHeaders);
// $result = $phpCaller->doPostFormString($url, $data, $region, $api, $version, $ak, $sk);
} catch (customException $e) {
echo $e->errorMessage();
} catch (Exception $e) {
echo $e->getMessage();
}
print_r($result);
}
exit;
class HttpCaller
{
// 全局常量 标识是否打印调试信息
var $PRINT_DEBUG = false;
var $HMAC_SHA256 = "sha256";
// 打印调试信息的方法
protected function myPrint($msg)
{
if ($this->PRINT_DEBUG) {
echo $msg . "<br>";
}
}
/** 获取毫秒级时间戳
*/
protected function get_millistime()
{
$microtime = microtime();
$comps = explode(' ', $microtime);
return sprintf('%d%03d', $comps[1], $comps[0] * 1000);
}
function get_mac_address()
{
$mac_address = "";
$os = strtolower(PHP_OS);
if(strpos($os, 'win') !== false) {
exec('ipconfig /all', $output);
foreach ($output as $line) {
if (strpos($line, "Physical") !== false) {
$mac_address = trim(str_replace(array('Physical Address', ':', '-', '.'), '', $line));
break;
}
}
} else {
exec('/sbin/ifconfig', $output);
foreach($output as $line) {
if (preg_match('/ether/i', $line)) {
$mac_address = preg_replace('/.*?(\w{2}:\w{2}:\w{2}:\w{2}:\w{2}:\w{2}).*/', '$1', $line);
break;
}
}
}
return $mac_address;
}
/**
* 生成签名的方法
* params 原始的输入参数数组 keyValuePairs
* api 调用服务API名
* version 服务版本
* ak accessKey
* sk secretKey
*
* 返回 签名过的url请求数组
*/
protected function sign($params = array(), $method, $region, $api, $version, $ak, $sk)
{
$path = $api;
if (strpos($api, '/') !== false) {
// Replace all slashes with dots
$api = str_replace('/', '.', $api);
// Check if the first character is a dot and remove it if necessary
if ($api[0] === '.') {
$api = substr($api, 1);
}
}
$headers = array();
$headers['_api_name'] = $api;
$headers['_api_version'] = $version;
$headers['_api_access_key'] = $ak;
$headers['_api_timestamp'] = $this->get_millistime();
$signParams = array();
// foreach ($params as $k => $v) {
// $signParams[$k] = $v;
// }
foreach ($headers as $k => $v) {
$signParams[$k] = $v;
}
ksort($signParams);
$signstr = '';
foreach ($signParams as $k => $v) {
if ($k == '_api_signature')
continue;
if ($signstr != '')
$signstr = $signstr . "&";
$signstr = $signstr . $k . '=' . $v;
}
$this->myPrint('signstr=' . http_build_query($signParams));
$signature = base64_encode(hash_hmac('sha1', $signstr, $sk, true));
$this->myPrint('signature=' . $signature);
$headers['_api_signature'] = $signature;
$timestamp = gmdate('Y-m-d\TH:i:s\Z');
$nonce = uniqid() . rand(1000, 9999);
$ip = gethostbyname(gethostname());
$sign = $this->generateSignature($sk, $method, $timestamp, $nonce, $path, $params);
$headers["X-Hmac-Auth-Signature"] = $sign;
$headers["X-Hmac-Auth-Timestamp"] = $timestamp;
$headers["X-Hmac-Auth-Nonce"] = $nonce;
$headers["apiKey"] = $ak;
$headers["X-Hmac-Auth-Version"] = "1.0";
$headers["X-Hmac-Auth-IP"] = $ip;
$headers["X-Hmac-Auth-MAC"] = $this->get_mac_address();
if ($this->PRINT_DEBUG) {
echo "<br>headers:<br>";
print_r($headers);
}
//transfer header
$theaders = array();
foreach ($headers as $k => $v) {
$theaders[] = $k . ":" . $v;
}
$theaders[] = "region:" . $region;
return $theaders;
}
/* * 使用GET方式调用HTTP服务的方法
data 原始的输入参数数组
api 调用服务API名
version 服务版本
ak accessKey
sk secretKey
inputHeaders 自定义请求头信息
返回 从Http服务端返回的串
*/
public function doGet($url, $data = array(), $region, $api, $version, $ak, $sk, $inputHeaders)
{
$headers = $this->sign($data, "GET", $region, $api, $version, $ak, $sk);
if (!is_null($inputHeaders)) {
$headers = array_merge($headers, $inputHeaders);
}
$ch = curl_init(); // 初始化一个curl资源类型变量
/* 设置访问的选项 */
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true); // 启用时会将服务器返回的Location: 放在header中递归的返回给服务器,即允许跳转
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); // 将获得的数据返回而不是直接在页面上输出
//curl_setopt($ch, CURLOPT_PROTOCOLS, CURLPROTO_HTTP ); // 设置访问地址用的协议类型为HTTP
curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 15); // 访问的超时时间限制为15s
// curl_setopt($ch, CURLOPT_TIMEOUT, 15); //返回的超时设置
curl_setopt($ch, CURLOPT_BINARYTRANSFER, true); // 在启用 CURLOPT_RETURNTRANSFER 时候将获取数据返回
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false); // 对认证证书来源的检查
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false); // 从证书中检查SSL加密算法是否存在
$url = $url . '?' . http_build_query($data);
$this->myPrint("request url=" . $url . "<br>");
curl_setopt($ch, CURLOPT_URL, $url); // 设置即将访问的URL
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers); //put signature-related headers
curl_setopt($ch, CURLOPT_HEADER, false); // 设置不显示头信息
$result = curl_exec($ch); // 执行本次访问,返回一个结果
$this->myPrint("<br>returnStr=<xmp>" . $result . "</xmp><br>");
curl_close($ch); // 关闭
// ... // 针对结果的正确与否做一些操作
return $result;
}
/**
* 供doPostXXX调用的内部方法,进行实际的POST调用,并返回调用结果
*/
protected function postInner($ch, $url, $headers)
{
/* 设置访问的选项 */
curl_setopt($ch, CURLOPT_POST, true); // 设置为POST传递形式
$headers[] = 'Expect:';
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers); //put signature-related headers
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true); // 启用时会将服务器返回的Location: 放在header中递归的返回给服务器,即允许跳转
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); // 将获得的数据返回而不是直接在页面上输出
//curl_setopt($ch, CURLOPT_PROTOCOLS, CURLPROTO_HTTP ); // 设置访问地址用的协议类型为HTTP
curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 15); // 访问的超时时间限制为15s
curl_setopt($ch, CURLOPT_BINARYTRANSFER, true); // 在启用 CURLOPT_RETURNTRANSFER 时候将获取数据返回
//curl_setopt($ch, CURLOPT_HTTPHEADER, array('Expect:'));
curl_setopt($ch, CURLOPT_USERAGENT, ''); // 将用户代理置空
curl_setopt($ch, CURLOPT_HEADER, false); // 设置不显示头信息
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false); // 对认证证书来源的检查
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false); // 从证书中检查SSL加密算法是否存在
$this->myPrint("<br>request url=" . $url);
curl_setopt($ch, CURLOPT_URL, $url); // 设置即将访问的URL
$result = curl_exec($ch); // 执行本次访问,返回一个结果
$info = curl_getinfo($ch); // 获取本次访问资源的相关信息
//echo $info."<br>";
$this->myPrint("<br>returnStr=<xmp>" . $result . "</xmp><br>");
curl_close($ch); // 关闭
// ... // 针对结果的正确与否做一些操作
return $result;
}
/* * 使用POST方式调用HTTP服务的方法
data 请求参数数组 (Key-Vale pairs)
api 调用服务API名
version 服务版本
ak accessKey
sk secretKey
inputHeaders 自定义请求头信息
返回 从Http服务端返回的串
*/
public function doPost($url, $data, $region, $api, $version, $ak, $sk, $inputHeaders)
{
$ch = curl_init(); // 初始化一个curl资源类型变量
$headers = $this->sign($data, "POST", $region, $api, $version, $ak, $sk);
if (!is_null($inputHeaders)) {
$headers = array_merge($headers, $inputHeaders);
}
$pd = http_build_query($data, "", "&");
curl_setopt($ch, CURLOPT_POSTFIELDS, $pd); // 设置POST传递的数据
return $this->postInner($ch, $url, $headers);
}
/* * 使用POST方式调用HTTP服务的方法
data 请求的json格式串 (例如: "{"name" : "Banana"}")
api 调用服务API名
version 服务版本
ak accessKey
sk secretKey
inputHeaders 自定义请求头信息
返回 从Http服务端返回的串
*/
public function doPostJsonString($url, $data, $region, $api, $version, $ak, $sk, $inputHeaders)
{
$jsonStr = json_encode($data);
$ch = curl_init(); // 初始化一个curl资源类型变量
$data = array();
$headers = $this->sign($data, "POST", $region, $api, $version, $ak, $sk);
if (!is_null($inputHeaders)) {
$headers = array_merge($headers, $inputHeaders);
}
$headers[] = 'Content-Type:application/json';
curl_setopt($ch, CURLOPT_POSTFIELDS, $jsonStr); // 设置POST传递的数据
return $this->postInner($ch, $url, $headers);
}
public function doPostFormString($url, $form, $region, $api, $version, $ak, $sk, $inputHeaders)
{
$ch = curl_init(); // 初始化一个curl资源类型变量
$data = array();
$headers = $this->sign($data, "POST", $region, $api, $version, $ak, $sk);
if (!is_null($inputHeaders)) {
$headers = array_merge($headers, $inputHeaders);
}
$headers[] = 'Content-Type:application/x-www-form-urlencoded';
printf(http_build_query($form));
curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query($form)); // 设置POST传递的数据
return $this->postInner($ch, $url, $headers);
}
/* * 使用POST方式调用HTTP服务的方法
data 请求的byte[] 这个byte数组可以是从一个文件中读取的内容
api 调用服务API名
version 服务版本
ak accessKey
sk secretKey
inputHeaders 自定义请求头信息
返回 从Http服务端返回的串
*/
public function doPostByteArray($url, $byteArray, $region, $api, $version, $ak, $sk, $inputHeaders)
{
$ch = curl_init(); // 初始化一个curl资源类型变量
$data = array();
$headers = $this->sign($data, "GET", $region, $api, $version, $ak, $sk);
if (!is_null($inputHeaders)) {
$headers = array_merge($headers, $inputHeaders);
}
$headers[] = 'Content-Type: application/octet-stream';
curl_setopt($ch, CURLOPT_POSTFIELDS, $byteArray); // 设置POST传递的数据
return $this->postInner($ch, $url, $headers);
}
/** 一个帮助方法,读取文件内容并且转换为二进制数组
*
*/
public function readFileAsByteArray($filename)
{
$handle = fopen($filename, "rb");
$fsize = filesize($filename);
$contents = fread($handle, $fsize);
fclose($handle);
return $contents;
}
protected function generateSignature($secretKey, $method, $timestamp, $nonce, $urlPath, $params)
{
// Step 1: Create the StringToSign
$canonicalRequest = $this->createCanonicalRequest($method, $timestamp, $nonce, $urlPath, $params);
// Step 2: HmacSHA256
$signature = hash_hmac($this->HMAC_SHA256, $canonicalRequest, $secretKey, true);
// Step 3: Base64 encode
return base64_encode($signature);
}
private function createCanonicalRequest($method, $timestamp, $nonce, $urlPath, $params)
{
$canonicalRequest = strtoupper($method) . "\n";
$canonicalRequest .= $timestamp . "\n";
$canonicalRequest .= $nonce . "\n";
$canonicalRequest .= $urlPath;
if (!empty($params)) {
$canonicalRequest .= "\n" . $this->formatParams($params);
}
return $canonicalRequest;
}
private function formatParams($params)
{
// Sort the params by key, ignoring case
uksort($params, 'strcasecmp');
$formattedParams = [];
foreach ($params as $key => $value) {
$formattedParams[] = urlencode($key) . '=' . urlencode($value);
}
return implode('&', $formattedParams);
}
}
?>