一、说明

抖音开放平台-开发指南

二、代码

<?php
namespace app\common\libs;

use app\common\exception\BaseException;

/**
 * Class DouYinApi
 * @package app\common\libs
 */
class DouYinApi
{
    private $host; //抖音接口API,API调用指南:https://op.jinritemai.com/docs/guide-docs/148/814
    private $appKey; //appKey
    private $appSecret; //appSecret
    private $accessToken; //访问令牌
    private $refreshToken; //刷新令牌
    private $versionNumber; //API协议版本,当前版本为 2
    private $versionNumberStr; //API协议版本,当前版本为 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在后面设置则报错:"v不可为空",因为handleToken中调用了versionNumber,但versionNumber此时的值为NULL
        $result = self::handleToken(); //创建Token
//        $result = self::handleToken(false); //刷新Token:提示-"缺少code",需要建一张第三方表存抖音该店铺的access_token,refresh_token,expire_time信息
        $this->accessToken = $result['access_token']; //用于出创建token接口之外的其他接口
        $this->refreshToken = $result['refresh_token']; //用于刷新token接口
    }

    /**
     * 处理(创建/刷新)Token的方法
     * 开发指南 > 产品功能 > 授权介绍 -> 自用型应用店铺授权流程:https://op.jinritemai.com/docs/guide-docs/9/21
     * @param bool $createToken 是否调用创建Token的方法
     * @return array
     * @throws BaseException
     */
    public function handleToken($createToken = true)
    {
        if ($createToken) { //调用创建token接口
            $param = [
                'code' => '',
                'grant_type' => 'authorization_self',
                'shop_id' => '你抖音店铺的ID', //店铺ID,仅自用型应用有效;若不传,则默认返回最早授权成功店铺对应的token信息
            ];
            $method = 'token.create';

        } else { //调用刷新Token方法
            $param = [
//                'app_id' => '', //应用key ,长度19位字母和数字组合的字符串,可不传
                '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过期时间 = 当前时间   有效时间(秒s)

            return [
                'access_token' => $accessToken,
                'refresh_token' => $refreshToken,
            ];
        }
    }

    /**
     * 封装抖音接口公共方法
     * PHP调用说明:https://op.jinritemai.com/docs/guide-docs/151/811
     * @param $method 方法名:格式 token.create 方法中转为 token/create
     * @param $param 请求接口需要的参数名
     * @param bool $accessToken url中是否要加上access_token,默认否。
     *              为什么不直接传accessToken的值:在本类中,可以获取到accessToken的值,直接传,但是如果在其他的地方调用就获取不到access_token的值,需要传true/false标识在本类中获取。
     * @param bool $paramJsonAddToUrl 是否把paramJson放到 url 中,根据实际情况
     *          例:实际过程中【订单批量解密接口】不需要放到url中(猜测是这个接口paramJson内容太多,会超出GET的最大内容)
     *              订单批量解密接口:https://op.jinritemai.com/docs/api-docs/15/982
     * @return false|mixed|string
     */
    function fetch($method, $param, $accessToken = false, $paramJsonAddToUrl = true)
    {
        //当前时间戳
        $timestamp = time();

        //PHP中:如果数组为空转为json之后是[]。但接口可能是强类型语言编写的,需要传{}。所以$param为空时,需要把$paramJson设置为{}
        $paramJson = $param ? self::marshal($param) : '{}';

        //获取签名
        $sign = self::sign($method, $timestamp, $paramJson);

        //调用的方法.替换为/
        $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 .= '&timestamp=' . urlencode(strval($timestamp)) .
            '&v=' . urlencode($this->versionNumber) .
            '&sign=' . $sign;

        if ($paramJsonAddToUrl) {
            $url .= '&param_json=' . $paramJson;
        }

        $url .= '&sign_method=' . urlencode('hmac-sha256'); //官方接口为非必填,但是不加签名会验证失败

        //处理句柄数据
        $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);
    }

    //序列化参数,入参必须为关联数组(键值对数组)
    function marshal(array $param)
    {
        self::rec_ksort($param); // 对关联数组中的kv,执行排序,需要递归
        $s = json_encode($param, JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE); // 重新序列化,确保所有key按字典序排序
        // 加入flag,确保斜杠不被escape,汉字不被escape
        return $s;
    }

    //关联数组排序,递归
    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); //这里的调用方式要和marshal中调用方式一致
            }
        }
        if ($kstring) {
            ksort($arr);
        }
    }
}

三、代码运行需知

  • __construct() 方法 $this->appKey 中加上你的真实appKey
  • __construct() 方法 $this->appSecret 中加上你的真实appSecret
  • handleToken() 方法 shop_id 中加上你真实的抖音店铺ID

四、功能扩展

  • 加一张数据表 third_shop(第三方店铺表):存放第三方店铺(比如:抖音)的信息,表的字段大致有:id;shop_name:店铺名;third_shop_id:第三方店铺的ID,source:店铺来源(抖音,京东,天猫);app_key,app_secret,access_token,refresh_token,expire_time:过期时间;status:状态(0-关闭;1-启用),create_time,update_time ...
  • 我们要对接抖音前,在third_shop中写好 id;shop_name:店铺名;third_shop_id:第三方店铺的ID,source:店铺来源(抖音,京东,天猫);app_key,app_secret;status:状态(0-关闭;1-启用),create_time,update_time ....
  • __construct()中先查询店铺的信息,如果 access_token为空 或者 expire_time过期时间 小于 当前时间,则需要重新生成 access_token,refresh_token,expire_time:过期时间handleToken() 中加上third_shop 表更新操作;否则取数据表中未过期的 access_token,refresh_token用于接口调用

五、接口调用需要注意的点

1、param为空的问题:param为空,$paramJson字符串的值为 {},而不是 []

2、rec_ksort递归调用的问题:rec_ksort中调用rec_ksort方式要和marshal中调用rec_ksort方式一致

3、paramJson何时传的问题:如果接口请求数据太大,GET请求可能会超出最大值,则 fetch()$paramJsonAddToUrl 可试着传 false

六、接口文档中的 ‘坑'(以订单列表接口为例)

1、请求参数、响应参数 代表的具体值不清晰

订单列表中 请求参数、响应参数main_status,每个数字代表什么意思,没有清楚的给出,如下图:

在这里插入图片描述

给了,在订单详情 接口的 响应参数 中,如下图:

在这里插入图片描述

2、页码从第0页开始(这个属于需要注意的点)

在这里插入图片描述

3、金额 是元 还是 分,不清晰

不给的话,那就默认为:

在这里插入图片描述

到此这篇关于PHP对接抖音开发平台接口的详细教程的文章就介绍到这了,更多相关PHP 抖音开发平台接口内容请搜索Devmax以前的文章或继续浏览下面的相关文章希望大家以后多多支持Devmax!

PHP对接抖音开发平台接口的详细教程的更多相关文章

  1. Html5页面二次分享的实现

    这篇文章主要介绍了Html5页面二次分享的实现的相关资料,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧

  2. HTML5跳转小程序wx-open-launch-weapp的示例代码

    这篇文章主要介绍了HTML5跳转小程序wx-open-launch-weapp的相关知识,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下

  3. ios – Objective C接口,委托和协议

    所以我试图围绕Objctive-C接口,代理和协议.所以我有一个问题:委托是否必须在单独的文件中,或者它是否是您班级中定义的方法?协议就像java接口吗?

  4. 从iOS应用程序发送帖子到PHP脚本不工作…简单的解决方案就像

    我之前已经做了好几次了但是由于某些原因我无法通过这个帖子…我尝试了设置为_POST且没有的变量的PHP脚本……当它们未设置为发布时它工作精细.这是我的iOS代码:这里是PHP的一大块,POST变量不在正确的位置?我想这对于更有经验的开发人员来说是一个相当简单的答案,感谢您的帮助!解决方法$_POST是一个数组,而不是一个函数.您需要使用方括号来访问数组索引:

  5. ios – watchOS错误:控制器的接口描述中的未知属性

    解决方法创建IBOutlet作为WKInterfacePicker的属性,您将不会收到消息.

  6. 泛型 – MonoTouch和支持变体通用接口

    如果是这样,MonoTouch中针对这种情况的推荐解决方法是什么?解决方法这实际上取决于编译器而不是Mono版本.IOW有些东西可能适用于Mono2.10而不适用于MonoTouch6.x.当前版本的MonoTouch附带了smcs编译器和基于2.1的配置文件.较新的功能,如协方差,需要一个完整的4.0编译器和运行时.未来版本的MonoTouch将提供4.0/4.5运行时和编译器.

  7. ios – 用于 – 在Counterparts中的ViewController.swift(接口)文件是什么

    有人可以这么善良并解释这个文件的目的是什么?

  8. ios6 – 检测UIViewController上的接口旋转,即使未在 – (NSUInteger)supportedInterfaceOrientations中定义

    解决方法尝试使用UIDevice实例来检测设备物理方向的变化.要开始接收通知,您可以使用类似的内容:要取消注册接收设备旋转事件,请使用此选项:这是deviceDidRotate函数的一个例子:

  9. 接口和扩展

    classSimpleClass:ExampleProtocol{String="Averysimpleclass."varanotherProperty:Int=120funcadjust(){simpleDescription+="Now100%adjust."}funcadd(){simpleDescription+="Now50%add."}}vara=SimpleClass()a.adjust()letaDescription=a.simpleDescriptionstructSimpleStr

  10. swift类和接口的使用

    1类的使用2接口的使用

随机推荐

  1. PHP个人网站架设连环讲(一)

    先下一个OmnihttpdProffesinalV2.06,装上就有PHP4beta3可以用了。PHP4给我们带来一个简单的方法,就是使用SESSION(会话)级变量。但是如果不是PHP4又该怎么办?我们可以假设某人在15分钟以内对你的网页的请求都不属于一个新的人次,这样你可以做个计数的过程存在INC里,在每一个页面引用,访客第一次进入时将访问时间送到cookie里。以后每个页面被访问时都检查cookie上次访问时间值。

  2. PHP函数学习之PHP函数点评

    PHP函数使用说明,应用举例,精简点评,希望对您学习php有所帮助

  3. ecshop2.7.3 在php5.4下的各种错误问题处理

    将方法内的函数,分拆为2个部分。这个和gd库没有一点关系,是ecshop程序的问题。会出现这种问题,不外乎就是当前会员的session或者程序对cookie的处理存在漏洞。进过本地测试,includes\modules\integrates\ecshop.php这个整合自身会员的类中没有重写integrate.php中的check_cookie()方法导致,验证cookie时返回的username为空,丢失了登录状态,在ecshop.php中重写了此方法就可以了。把他加到ecshop.php的最后面去就可

  4. NT IIS下用ODBC连接数据库

    $connection=intodbc_connect建立数据库连接,$query_string="查询记录的条件"如:$query_string="select*fromtable"用$cur=intodbc_exec检索数据库,将记录集放入$cur变量中。再用while{$var1=odbc_result;$var2=odbc_result;...}读取odbc_exec()返回的数据集$cur。最后是odbc_close关闭数据库的连接。odbc_result()函数是取当前记录的指定字段值。

  5. PHP使用JpGraph绘制折线图操作示例【附源码下载】

    这篇文章主要介绍了PHP使用JpGraph绘制折线图操作,结合实例形式分析了php使用JpGraph的相关操作技巧与注意事项,并附带源码供读者下载参考,需要的朋友可以参考下

  6. zen_cart实现支付前生成订单的方法

    这篇文章主要介绍了zen_cart实现支付前生成订单的方法,结合实例形式详细分析了zen_cart支付前生成订单的具体步骤与相关实现技巧,需要的朋友可以参考下

  7. Thinkphp5框架实现获取数据库数据到视图的方法

    这篇文章主要介绍了Thinkphp5框架实现获取数据库数据到视图的方法,涉及thinkPHP5数据库配置、读取、模型操作及视图调用相关操作技巧,需要的朋友可以参考下

  8. PHP+jquery+CSS制作头像登录窗(仿QQ登陆)

    本篇文章介绍了PHP结合jQ和CSS制作头像登录窗(仿QQ登陆),实现了类似QQ的登陆界面,很有参考价值,有需要的朋友可以了解一下。

  9. 基于win2003虚拟机中apache服务器的访问

    下面小编就为大家带来一篇基于win2003虚拟机中apache服务器的访问。小编觉得挺不错的,现在就分享给大家,也给大家做个参考。一起跟随小编过来看看吧

  10. Yii2中组件的注册与创建方法

    这篇文章主要介绍了Yii2之组件的注册与创建的实现方法,非常不错,具有参考借鉴价值,需要的朋友可以参考下

返回
顶部