PHP對(duì)接抖音開發(fā)平臺(tái)接口的詳細(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 = '你的抖音后臺(tái)的appKey'; $this->appSecret = '你的抖音后臺(tái)的appSecret'; $this->versionNumber = '2'; $this->versionNumberStr = 'v' . $this->versionNumber; //獲取access_token,refresh_token放到最后,如果其他的如versionNumber在后面設(shè)置則報(bào)錯(cuò):"v不可為空",因?yàn)閔andleToken中調(diào)用了versionNumber,但versionNumber此時(shí)的值為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)成功店鋪對(duì)應(yīng)的token信息 ]; $method = 'token.create'; } else { //調(diào)用刷新Token方法 $param = [ // 'app_id' => '', //應(yīng)用key ,長度19位字母和數(shù)字組合的字符串,可不傳 'refresh_token' => $this->refreshToken, //注意:傳真實(shí)的refreshToken值,而不是傳REFRESH_TOKEN 'grant_type' => 'refresh_token', ]; $method = 'token.refresh'; } $timestamp = time(); //接口請(qǐng)求前記錄開始時(shí)間,防止過期時(shí)間$expireTime失效 $result = self::fetch($method, $param); if ($result['code'] != 10000) { //請(qǐng)求失敗 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過期時(shí)間 = 當(dāng)前時(shí)間 + 有效時(shí)間(秒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 請(qǐng)求接口需要的參數(shù)名 * @param bool $accessToken url中是否要加上access_token,默認(rèn)否。 * 為什么不直接傳accessToken的值:在本類中,可以獲取到accessToken的值,直接傳,但是如果在其他的地方調(diào)用就獲取不到access_token的值,需要傳true/false標(biāo)識(shí)在本類中獲取。 * @param bool $paramJsonAddToUrl 是否把paramJson放到 url 中,根據(jù)實(shí)際情況 * 例:實(shí)際過程中【訂單批量解密接口】不需要放到url中(猜測(cè)是這個(gè)接口paramJson內(nèi)容太多,會(huì)超出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)前時(shí)間戳 $timestamp = time(); //PHP中:如果數(shù)組為空轉(zhuǎn)為json之后是[]。但接口可能是強(qiáng)類型語言編寫的,需要傳{}。所以$param為空時(shí),需要把$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'); //官方接口為非必填,但是不加簽名會(huì)驗(yàn)證失敗 //處理句柄數(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); } //計(jì)算簽名 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ù)組(鍵值對(duì)數(shù)組) function marshal(array $param) { self::rec_ksort($param); // 對(duì)關(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); } } }
三、代碼運(yùn)行需知
- 在
__construct()
方法$this->appKey
中加上你的真實(shí)appKey - 在
__construct()
方法$this->appSecret
中加上你的真實(shí)appSecret - 在
handleToken()
方法shop_id
中加上你真實(shí)的抖音店鋪ID
四、功能擴(kuò)展
- 加一張數(shù)據(jù)表
third_shop(第三方店鋪表)
:存放第三方店鋪(比如:抖音)的信息,表的字段大致有:id;shop_name:店鋪名;third_shop_id:第三方店鋪的ID,source:店鋪來源(抖音,京東,天貓);app_key,app_secret,access_token,refresh_token,expire_time:過期時(shí)間;status:狀態(tài)(0-關(guān)閉;1-啟用),create_time,update_time ...
- 我們要對(duì)接抖音前,在
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過期時(shí)間 小于 當(dāng)前時(shí)間
,則需要重新生成access_token,refresh_token,expire_time:過期時(shí)間
在handleToken()
中加上third_shop 表
更新操作;否則取數(shù)據(jù)表中未過期的access_token,refresh_token
用于接口調(diào)用
五、接口調(diào)用需要注意的點(diǎn)
1、param為空的問題:param為空,$paramJson字符串的值為 {}
,而不是 []
2、rec_ksort遞歸調(diào)用的問題:rec_ksort中調(diào)用rec_ksort方式要和marshal中調(diào)用rec_ksort方式一致
3、paramJson何時(shí)傳的問題:如果接口請(qǐng)求數(shù)據(jù)太大,GET請(qǐng)求可能會(huì)超出最大值,則 fetch()
中 $paramJsonAddToUrl
可試著傳 false
六、接口文檔中的 ‘坑'(以訂單列表接口為例)
1、請(qǐng)求參數(shù)、響應(yīng)參數(shù) 代表的具體值不清晰
訂單列表中 請(qǐng)求參數(shù)、響應(yīng)參數(shù) main_status
,每個(gè)數(shù)字代表什么意思,沒有清楚的給出,如下圖:
給了,在訂單詳情 接口的 響應(yīng)參數(shù)
中,如下圖:
2、頁碼從第0頁開始(這個(gè)屬于需要注意的點(diǎn))
3、金額 是元 還是 分,不清晰
不給的話,那就默認(rèn)為:分
到此這篇關(guān)于PHP對(duì)接抖音開發(fā)平臺(tái)接口的詳細(xì)教程的文章就介紹到這了,更多相關(guān)PHP 抖音開發(fā)平臺(tái)接口內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
php解決crontab定時(shí)任務(wù)不能寫入文件問題的方法分析
這篇文章主要介紹了php解決crontab定時(shí)任務(wù)不能寫入文件問題的方法,結(jié)合實(shí)例形式分析了crontab定時(shí)任務(wù)無法正常執(zhí)行的原因與解決方法,需要的朋友可以參考下2019-09-09php常用字符串String函數(shù)實(shí)例總結(jié)【轉(zhuǎn)換,替換,計(jì)算,截取,加密】
這篇文章主要介紹了php常用字符串String函數(shù),結(jié)合實(shí)例形式總結(jié)分析了php常用字符串函數(shù)的功能與使用技巧,包括字符串的轉(zhuǎn)換、替換、計(jì)算、截取、加密等各種常用操作相關(guān)函數(shù),需要的朋友可以參考下2016-12-12php 啟動(dòng)時(shí)報(bào)錯(cuò)的簡(jiǎn)單解決方法
php啟動(dòng)時(shí)報(bào)錯(cuò)的情況,想必很多朋友都有遇到吧,下面為大家介紹下比較不錯(cuò)的解決方法2014-01-01PHP調(diào)用MySQL存儲(chǔ)過程并返回值的方法
這篇文章主要介紹了PHP調(diào)用MySQL存儲(chǔ)過程并返回值的方法,較為詳細(xì)的分析了存儲(chǔ)過程的使用技巧,具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2014-12-12thinkphp關(guān)于簡(jiǎn)單的權(quán)限判定方法
下面小編就為大家?guī)硪黄猼hinkphp關(guān)于簡(jiǎn)單的權(quán)限判定方法。小編覺得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧2017-04-04php 無限級(jí)分類,超級(jí)簡(jiǎn)單的無限級(jí)分類,支持輸出樹狀圖
php 無限級(jí)分類,超級(jí)簡(jiǎn)單的無限級(jí)分類,支持輸出樹狀圖,代碼來自網(wǎng)絡(luò), 只是自己用了挺長時(shí)間特地拿出來分享給大家2014-06-06php面向?qū)ο缶幊蘳elf和static的區(qū)別
這篇文章主要介紹了PHP中static關(guān)鍵字以及與self關(guān)鍵字的區(qū)別,本文講解了static關(guān)鍵字的定義、遲綁定(Late Static Bindings)、以及與self關(guān)鍵字的區(qū)別等內(nèi)容,需要的朋友可以參考下2016-05-05