之前使用的是 获取 Access token 接口,与稳定版区别在于,稳定版默认的普通模式,access_token 有效期内重复调用该接口不会更新 access_token。且稳定版接口仅支持 POST JSON 形式的调用。

默认调用不会更新 access_token,在有效期结束的 5 分钟内,新旧 access_token 都有效,这对于分布式服务来说,需要使用中心化的存储服务。之前使用的本地文件存储,显然并不适合。相对来说,一些基于内存的缓存数据库会比较适合,比如 redis。可以设置过期时间为 expires_in - 5 * 60 s。

请求可以使用 curl ,或者 file_get_content。因为之前打开文件使用了后者,所以需要找到 file_get_content POST 方法的样例

$url = "http://localhost/test/test.php";
$data=array('author '=> 'szy','intro'=> '哎呦,错了');
 
$data = http_build_query ($data);
 
$opts = array(
    'http' => array(
        'method' => 'POST',
        'heade' => "Content-type:application/x-www-form-urlencoded Content-Length:".strlen ($data),
        'content' =>$data
    )
);
 
$context = stream_context_create($opts);
$html = file_get_contents($url,false,$context);
print_r($html);

测试不行,提示参数缺失。看到文档里提到稳定版接口仅支持 POST JSON 形式的调用,修改后:

$url = "http://localhost/test/test.php";
$data=array('author '=> 'szy','intro'=> '哎呦,错了');
 
$data = json_encode ($data);
 
$opts = array(
    'http' => array(
        'method' => 'POST',
        'heade' => "Content-type:application/json Content-Length:".strlen ($data),
        'content' =>$data
    )
);
 
$context = stream_context_create($opts);
$html = file_get_contents($url,false,$context);
print_r($html);

最终代码:

if ($data = json_decode(Cache::store("redis")->get('access_token'))) {
    return $data->access_token;
} else {
    // 稳定版获取 token 需要 POST
    // 创建 stream
    $content = json_encode(array(
        'grant_type' => 'client_credential',
        'appid' => env('WECHAT_MINI_PROGRAM_ID'),
        'secret' => env('WECHAT_MINI_PROGRAM_SECRET'),
        'force_refresh' => false
    ));
    $context = stream_context_create(
        array(
            'http' => array(
                'method'=>"POST",
                'header' => 'Content-type: application/json'."\r\n"
                    . "Content-Length: " . strlen($content) . "\r\n",
                'content' => $content
            )
        )
    );
    $result = json_decode(file_get_contents('https://api.weixin.qq.com/cgi-bin/stable_token', false, $context));

    if (!empty($result->errcode)) {
        Log::info('get access_token failed : ' . json_encode($result));
        return '';
    } else {
        // Laravel 5.2 以上(不包含)缓存计量单位为秒
        Cache::store("redis")->put("access_token", json_encode($result), $result->expires_in - 5 * 60);

        return $result->access_token;
    }
}