PHP對接抖音開發(fā)平臺接口的詳細(xì)教程
一、說明
二、代碼
<?php
namespace app\common\libs;
use app\common\exception\BaseException;
/**
* Class DouYinApi
* @package app\common\libs
*/
class DouYinApi
{
private $host; //抖音接口API,API調(diào)用指南:https://op.jinritemai.com/docs/guide-docs/148/814
private $appKey; //appKey
private $appSecret; //appSecret
private $accessToken; //訪問令牌
private $refreshToken; //刷新令牌
private $versionNumber; //API協(xié)議版本,當(dāng)前版本為 2
private $versionNumberStr; //API協(xié)議版本,當(dāng)前版本為 v2
public function __construct()
{
$this->host = 'https://openapi-fxg.jinritemai.com'; //接口訪問地址
$this->appKey = '你的抖音后臺的appKey';
$this->appSecret = '你的抖音后臺的appSecret';
$this->versionNumber = '2';
$this->versionNumberStr = 'v' . $this->versionNumber;
//獲取access_token,refresh_token放到最后,如果其他的如versionNumber在后面設(shè)置則報錯:"v不可為空",因為handleToken中調(diào)用了versionNumber,但versionNumber此時的值為NULL
$result = self::handleToken(); //創(chuàng)建Token
// $result = self::handleToken(false); //刷新Token:提示-"缺少code",需要建一張第三方表存抖音該店鋪的access_token,refresh_token,expire_time信息
$this->accessToken = $result['access_token']; //用于出創(chuàng)建token接口之外的其他接口
$this->refreshToken = $result['refresh_token']; //用于刷新token接口
}
/**
* 處理(創(chuàng)建/刷新)Token的方法
* 開發(fā)指南 > 產(chǎn)品功能 > 授權(quán)介紹 -> 自用型應(yīng)用店鋪授權(quán)流程:https://op.jinritemai.com/docs/guide-docs/9/21
* @param bool $createToken 是否調(diào)用創(chuàng)建Token的方法
* @return array
* @throws BaseException
*/
public function handleToken($createToken = true)
{
if ($createToken) { //調(diào)用創(chuàng)建token接口
$param = [
'code' => '',
'grant_type' => 'authorization_self',
'shop_id' => '你抖音店鋪的ID', //店鋪ID,僅自用型應(yīng)用有效;若不傳,則默認(rèn)返回最早授權(quán)成功店鋪對應(yīng)的token信息
];
$method = 'token.create';
} else { //調(diào)用刷新Token方法
$param = [
// 'app_id' => '', //應(yīng)用key ,長度19位字母和數(shù)字組合的字符串,可不傳
'refresh_token' => $this->refreshToken, //注意:傳真實的refreshToken值,而不是傳REFRESH_TOKEN
'grant_type' => 'refresh_token',
];
$method = 'token.refresh';
}
$timestamp = time(); //接口請求前記錄開始時間,防止過期時間$expireTime失效
$result = self::fetch($method, $param);
if ($result['code'] != 10000) { //請求失敗
throw new BaseException($result['message']);
} else {
$data = $result['data'];
$accessToken = $data['access_token']; //accessToken
$refreshToken = $data['refresh_token']; //refreshToken
$expireTime = $timestamp + $data['expires_in']; //Token過期時間 = 當(dāng)前時間 + 有效時間(秒s)
return [
'access_token' => $accessToken,
'refresh_token' => $refreshToken,
];
}
}
/**
* 封裝抖音接口公共方法
* PHP調(diào)用說明:https://op.jinritemai.com/docs/guide-docs/151/811
* @param $method 方法名:格式 token.create 方法中轉(zhuǎn)為 token/create
* @param $param 請求接口需要的參數(shù)名
* @param bool $accessToken url中是否要加上access_token,默認(rèn)否。
* 為什么不直接傳accessToken的值:在本類中,可以獲取到accessToken的值,直接傳,但是如果在其他的地方調(diào)用就獲取不到access_token的值,需要傳true/false標(biāo)識在本類中獲取。
* @param bool $paramJsonAddToUrl 是否把paramJson放到 url 中,根據(jù)實際情況
* 例:實際過程中【訂單批量解密接口】不需要放到url中(猜測是這個接口paramJson內(nèi)容太多,會超出GET的最大內(nèi)容)
* 訂單批量解密接口:https://op.jinritemai.com/docs/api-docs/15/982
* @return false|mixed|string
*/
function fetch($method, $param, $accessToken = false, $paramJsonAddToUrl = true)
{
//當(dāng)前時間戳
$timestamp = time();
//PHP中:如果數(shù)組為空轉(zhuǎn)為json之后是[]。但接口可能是強類型語言編寫的,需要傳{}。所以$param為空時,需要把$paramJson設(shè)置為{}
$paramJson = $param ? self::marshal($param) : '{}';
//獲取簽名
$sign = self::sign($method, $timestamp, $paramJson);
//調(diào)用的方法.替換為/
$methodPath = str_replace('.', '/', $method);
//拼接url路徑
$url = $this->host . '/' . $methodPath .
'?method=' . urlencode($method) .
'&app_key=' . urlencode($this->appKey);
if ($accessToken) {
$url .= '&access_token=' .urlencode($this->accessToken);
}
$url .= '×tamp=' . urlencode(strval($timestamp)) .
'&v=' . urlencode($this->versionNumber) .
'&sign=' . $sign;
if ($paramJsonAddToUrl) {
$url .= '¶m_json=' . $paramJson;
}
$url .= '&sign_method=' . urlencode('hmac-sha256'); //官方接口為非必填,但是不加簽名會驗證失敗
//處理句柄數(shù)據(jù)
$opts = array('http' =>
array(
'method' => 'POST',
'header' => "Accept: */*\r\n" .
"Content-type: application/json;charset=UTF-8\r\n",
'content' => $paramJson
)
);
$context = stream_context_create($opts);
$result = file_get_contents($url, false, $context);
return json_decode($result,true);
}
//計算簽名
function sign($method, $timestamp, $paramJson)
{
$paramPattern = 'app_key' . $this->appKey . 'method' . $method . 'param_json' . $paramJson . 'timestamp' . $timestamp . $this->versionNumberStr;
$signPattern = $this->appSecret . $paramPattern . $this->appSecret;
return hash_hmac("sha256", $signPattern, $this->appSecret);
}
//序列化參數(shù),入?yún)⒈仨殲殛P(guān)聯(lián)數(shù)組(鍵值對數(shù)組)
function marshal(array $param)
{
self::rec_ksort($param); // 對關(guān)聯(lián)數(shù)組中的kv,執(zhí)行排序,需要遞歸
$s = json_encode($param, JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE); // 重新序列化,確保所有key按字典序排序
// 加入flag,確保斜杠不被escape,漢字不被escape
return $s;
}
//關(guān)聯(lián)數(shù)組排序,遞歸
function rec_ksort(array &$arr)
{
$kstring = true;
foreach ($arr as $k => &$v) {
if (!is_string($k)) {
$kstring = false;
}
if (is_array($v)) {
self::rec_ksort($v); //這里的調(diào)用方式要和marshal中調(diào)用方式一致
}
}
if ($kstring) {
ksort($arr);
}
}
}
三、代碼運行需知
- 在
__construct()方法$this->appKey中加上你的真實appKey - 在
__construct()方法$this->appSecret中加上你的真實appSecret - 在
handleToken()方法shop_id中加上你真實的抖音店鋪ID
四、功能擴展
- 加一張數(shù)據(jù)表
third_shop(第三方店鋪表):存放第三方店鋪(比如:抖音)的信息,表的字段大致有:id;shop_name:店鋪名;third_shop_id:第三方店鋪的ID,source:店鋪來源(抖音,京東,天貓);app_key,app_secret,access_token,refresh_token,expire_time:過期時間;status:狀態(tài)(0-關(guān)閉;1-啟用),create_time,update_time ... - 我們要對接抖音前,在
third_shop中寫好id;shop_name:店鋪名;third_shop_id:第三方店鋪的ID,source:店鋪來源(抖音,京東,天貓);app_key,app_secret;status:狀態(tài)(0-關(guān)閉;1-啟用),create_time,update_time .... - 在
__construct()中先查詢店鋪的信息,如果access_token為空或者expire_time過期時間 小于 當(dāng)前時間,則需要重新生成access_token,refresh_token,expire_time:過期時間在handleToken()中加上third_shop 表更新操作;否則取數(shù)據(jù)表中未過期的access_token,refresh_token用于接口調(diào)用
五、接口調(diào)用需要注意的點
1、param為空的問題:param為空,$paramJson字符串的值為 {},而不是 []
2、rec_ksort遞歸調(diào)用的問題:rec_ksort中調(diào)用rec_ksort方式要和marshal中調(diào)用rec_ksort方式一致
3、paramJson何時傳的問題:如果接口請求數(shù)據(jù)太大,GET請求可能會超出最大值,則 fetch() 中 $paramJsonAddToUrl 可試著傳 false
六、接口文檔中的 ‘坑'(以訂單列表接口為例)
1、請求參數(shù)、響應(yīng)參數(shù) 代表的具體值不清晰
訂單列表中 請求參數(shù)、響應(yīng)參數(shù) main_status,每個數(shù)字代表什么意思,沒有清楚的給出,如下圖:

給了,在訂單詳情 接口的 響應(yīng)參數(shù) 中,如下圖:

2、頁碼從第0頁開始(這個屬于需要注意的點)

3、金額 是元 還是 分,不清晰
不給的話,那就默認(rèn)為:分

到此這篇關(guān)于PHP對接抖音開發(fā)平臺接口的詳細(xì)教程的文章就介紹到這了,更多相關(guān)PHP 抖音開發(fā)平臺接口內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
php+mysql實現(xiàn)的無限分類方法類定義與使用示例
這篇文章主要介紹了php+mysql實現(xiàn)的無限分類方法類定義與使用,結(jié)合實例形式分析了php+mysql無限分類方法類基本定義與使用方法,需要的朋友可以參考下2020-05-05
為Plesk PHP7啟用Oracle OCI8擴展方法總結(jié)
在本篇文章里小編給大家總結(jié)了關(guān)于為Plesk PHP7啟用Oracle OCI8擴展方法和相關(guān)代碼,需要的朋友們學(xué)習(xí)下。2019-03-03
PHP載入圖像imagecreatefrom_gif_jpeg_png系列函數(shù)用法分析
這篇文章主要介紹了PHP載入圖像imagecreatefrom_gif_jpeg_png系列函數(shù)用法,結(jié)合實例形式分析了php的圖像載入函數(shù)imagecreatefromgif、imagecreatefromjpeg、imagecreatefrompng、imagecreatefromwbmp及imagecreatefromstring使用技巧,需要的朋友可以參考下2016-11-11

