最新消息:20210816 当前crifan.com域名已被污染,为防止失联,请关注(页面右下角的)公众号

【已解决】微信公众号开发期间申请ACCESS_TOKEN

PHP crifan 2919浏览 0评论

【背景】

折腾:

【已解决】安全模式下实现微信添加自定义菜单

期间,先要去搞懂并申请ACCESS_TOKEN。

 

【折腾过程】

1.参考官网文档:

获取access token – 微信公众平台开发者文档

已经注意到,对于获取ACCESS_TOKEN,官网也是有限定的:

接口频率限制说明 – 微信公众平台开发者文档

接口

每日限额

获取access_token

2000

 

2.然后去写代码,获取ACCESS_TOKEN。

其中所需要的值:

AppID和AppSecret

是可以在微信的开发者中心中看到的:

weixin public platform see AppID AppSecret

3.然后就是去写代码去了。

期间,需要利用我自己之前的功能CrifanLib.php,然后继续丰富内容,便于后续调用。

其中遇到:

【记录】php中如何写类和如何使用类

4.然后接着去利用crifanLib.php中的getUrlRespHtml去实现https访问。

然后为了写的URL更加通用,所以再去研究:

【已解决】PHP中如何实现sprinf

5.然后接着为了优化log函数,希望支持类似于sprintf的动态参数:

【已解决】将Log函数的参数改变为类似于sprintf的动态参数

 

【总结】

然后再去调用自己的库函数crifanLib.php中的getUrlRespHtml,然后就可以正常获得access_token了:

对应代码是:

crifanLib.php

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
<?php
/*
[Filename]
crifanLib.php
 
[Function]
crifan's php lib, implement common functions
 
[Author]
Crifan Li
 
[Contact]
 
[Note]
1.online see code:
 
[TODO]
 
[History]
[v2015-07-29]
1.add logInit, logWrite
2.change to joinPath
 
[v1.0]
1.initial version, need clean up later
 
*/
 
class crifanLib {
    private $logFile;
 
    function __construct() {
        $this->logInit();
    }
     
   function __destruct() {
 
   }
 
    /***********************************************************************************************
    * String/Path/Data
    ***********************************************************************************************/
     
    /*
     * 【已解决】PHP中如何实现路径拼接(两个路径合并)以及合并文件夹路径和文件名
     * eg:
     * from:
     * D:\tmp\WordPress\DevRoot\httpd-2.2.19-win64\httpd-2.2-x64\htdocs\php_test\35934503_data
     * cookie_jar.txt
     * to:
     * D:\tmp\WordPress\DevRoot\httpd-2.2.19-win64\httpd-2.2-x64\htdocs\php_test\35934503_data\cookie_jar.txt
     */
    function joinPath($headPath, $tailPath) {
        $realHeadPath = realpath($headPath);
 
        $joinedPath = $realHeadPath.DIRECTORY_SEPARATOR.$tailPath;
        return $joinedPath;
    }
     
    /*
     *【已解决】PHP中把字符串文本等数据保存到文件中
     */
    function saveToFile($dataToOutput, $fullFilename) {
        $saveResult = file_put_contents($fullFilename, $dataToOutput);
        // $this->printAutoNewline("Write data to ".$fullFilename." ok.");
         
        return $saveResult;
    }
 
    /***********************************************************************************************
    * Log
    ***********************************************************************************************/
 
    /*
        Init log file
    */
    function logInit($inputLogFile = null) {
        // set default log file name, path is current php file
 
        //logFolder=/var/www/1.2.3.4/public_html/php/access_token
        $logFolder = getcwd();
        //logFilename=log_20150727131103.log
        $logFilename = "log_".date('YmdHis').".log";
        //defautLogFile=/var/www/1.2.3.4/public_html/php/access_token/log_20150727131103.log
        $defautLogFile = $this->joinPath($logFolder, $logFilename);
 
        $this->logFile = $inputLogFile ? $inputLogFile : $defautLogFile;
    }
 
    /*
        Write log info to file
        【已解决】PHP将log信息写入服务器中的log文件
         
        【已解决】将Log函数的参数改变为类似于sprintf的动态个数的可变参数
    */
    function logWrite() {
        $logArgList = func_get_args();
        // print_r("logArgList=".$logArgList."<br />");
        $logArgFirst = array_shift($logArgList);
        // print_r("logArgFirst=".$logArgFirst."<br />");
        // print_r("remaing logArgList=".$logArgList."<br />");
 
        $logFormat = $logArgFirst;
        $logArgs = $logArgList;
       
        $logFormatedContent = vsprintf($logFormat, $logArgs);
        // print_r("logFormatedContent=".$logFormatedContent."<br />");
         
        // define script name
        $phpSelfFilename = pathinfo($_SERVER['PHP_SELF'], PATHINFO_FILENAME);
        // define current time and suppress E_WARNING if using the system TZ settings
        // (don't forget to set the INI setting date.timezone)
        $curTimeStr = @date('[Y-m-d H:i:s]');
         
        // write current time, script name and message to the log file
        //[2015-07-27 13:11:03] (wx_access_token) This is crifanLib log test
        file_put_contents($this->logFile, "$curTimeStr ($phpSelfFilename) $logFormatedContent" . PHP_EOL, FILE_APPEND);
    }
 
    /**
     * add newline for print
     */
    function printAutoNewline($contentToPrint) {
        print_r($contentToPrint."<br />");
    }
 
    /***********************************************************************************************
    * Http
    ***********************************************************************************************/
     
    function getUrlResponse($url, $status = null, $wait = 3) {
        $time = microtime(true);
        $expire = $time + $wait;
 
        // we fork the process so we don't have to wait for a timeout
        $pid = pcntl_fork();
        if ($pid == -1) {
            die('could not fork');
        } else if ($pid) {
            // we are the parent
            $ch = curl_init();
            curl_setopt($ch, CURLOPT_URL, $url);
 
            curl_setopt($ch, CURLOPT_HEADER, TRUE);
            //curl_setopt($ch, CURLOPT_NOBODY, TRUE); // remove body
            //curl_setopt($ch, CURLOPT_RETURNTRANSFER, TRUE);
            $head = curl_exec($ch);
            $httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
            curl_close($ch);
            
            if(!$head)
            {
                return FALSE;
            }
            
            if($status === null)
            {
                if($httpCode < 400)
                {
                    return TRUE;
                }
                else
                {
                    return FALSE;
                }
            }
            elseif($status == $httpCode)
            {
                return TRUE;
            }
            
            return FALSE;
            pcntl_wait($status); //Protect against Zombie children
        } else {
            // we are the child
            while(microtime(true) < $expire)
            {
            sleep(0.5);
            }
            return FALSE;
        }
    }
 
    function getUrlRespHtml_fsockopen($url) {
        // $this->printAutoNewline("input url=".$url);
 
        $respHtml = "";
         
        //resource fsockopen ( string $hostname [, int $port = -1 [, int &$errno [, string &$errstr [, float $timeout = ini_get("default_socket_timeout") ]]]] )
        // $testHostname = "www.yell.com";
        // $fp = fsockopen($testHostname, 80, $errno, $errstr, 30);
        // if (!$fp) {
            // echo "$errstr ($errno)<br />\n";
        // } else {
            // $getRequest = "GET / HTTP/1.1\r\n";
            // $getRequest .= "Host: ".$testHostname."\r\n";
            // $getRequest .= "Connection: Close\r\n\r\n";
            // fwrite($fp, $getRequest);
            // while (!feof($fp)) {
                // $curRespHtml = fgets($fp, 128);
                // $this->printAutoNewline($curRespHtml);
                // $respHtml += $curRespHtml;
            // }
            // fclose($fp);
        // }
        //$this->printAutoNewline($respHtml);
         
        getUrlResponse($url,'200',3); // returns true if the response takes less than 3 seconds and the response code is 200
         
        return $respHtml;
    }
 
    function getUrlRespHtml($url) {
        $this->logWrite("Get response html from url=%s", $url);
         
        //get the file (e.g. image) and output it to the browser
        $ch = curl_init(); //open curl handle
        curl_setopt($ch, CURLOPT_URL, $url); //set an url
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); //do not output directly, use variable
        curl_setopt($ch, CURLOPT_BINARYTRANSFER, 1); //do a binary transfer
        curl_setopt($ch, CURLOPT_FAILONERROR, 1); //stop if an error occurred
         
        curl_setopt($ch, CURLOPT_AUTOREFERER, 1); //当根据Location:重定向时,自动设置header中的Referer:信息。
         
        $this->logWrite("now add CURLOPT_COOKIEJAR support");
        $cookieJarFilename = "cookie_jar.txt";
        //$cookieJarFullname = dirname(__FILE__).$cookieJarFilename;
        $cookieJarFullname = $this->joinPath(dirname(__FILE__), $cookieJarFilename);
        $this->logWrite("cookieJarFullname=%s", $cookieJarFullname);
        curl_setopt($ch, CURLOPT_COOKIEJAR, $cookieJarFullname);
        curl_setopt($ch, CURLOPT_COOKIEFILE, $cookieJarFullname);
         
        curl_setopt($ch, CURLOPT_USERAGENT, "Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 6.1; WOW64; Trident/5.0)");
         
        $requestHeader[0] = "Accept: text/html, application/xhtml+xml, */*,";
        //$requestHeader[] = "Cache-Control: max-age=0";
        $requestHeader[] = "Connection: keep-alive";
        //$requestHeader[] = "Keep-Alive: 300";
        //$requestHeader[] = "Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.7";
        //$requestHeader[] = "Accept-Language: en-us,en;q=0.5";
        //$requestHeader[] = "Pragma: "; // browsers keep this blank.
        curl_setopt($ch, CURLOPT_HTTPHEADER, $requestHeader);
 
        $urlResp = curl_exec($ch); //store the content in variable
         
        if(!curl_errno($ch))
        {
            //send out headers and output
            header("Content-type: ".curl_getinfo($ch, CURLINFO_CONTENT_TYPE)."");
            header("Content-Length: ".curl_getinfo($ch, CURLINFO_CONTENT_LENGTH_DOWNLOAD)."");
 
            $this->logWrite("urlResp=%s", $urlResp);
        }
        else{
            $this->logWrite('Curl for url=%s error=%s', $url, curl_error($ch));
        }
 
        curl_close($ch); //close curl handle
 
        return $urlResp;
    }
}
 
 ?>

调用文件wx_access_token.php:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
<?php
/*
    File:       wx_access_token.php
    Author:     Crifan Li
    Version:    2015-07-28
    Contact:    https://www.crifan.com/about/me/
    Function:   Wechat get access token
*/
 
include_once "crifanLib.php";
 
//global definition
// define("TOKEN", "didaosuzhou");
define("APPID", "xxx"); //18 characters
// define("EncodingAESKey", "zzz"); //43 characters
define("APPSECRET", "yyy"); //32 characters
 
 
$crifanLib = new crifanLib();
// $crifanLib->logWrite("str1=%s,num1=%d", "hello crifan", 123);
 
// $crifanLib->logWrite("This is crifanLib log test message not pass log file name");
$crifanLib->logWrite("tokenUrlPattern=%s", $tokenUrlPattern);
$getTokenUrl = sprintf($tokenUrlPattern, APPID, APPSECRET);
$crifanLib->logWrite("getTokenUrl=%s", $getTokenUrl);
 
$respHtml = $crifanLib->getUrlRespHtml($getTokenUrl);
$crifanLib->logWrite("respHtml=%s", $respHtml);
 
?>

去运行:

run appid test but no output

 

输出是:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
root@chantyou:access_token# ll
total 20
-rw-r--r-- 1 root   root   9932 Jul 29 11:26 crifanLib.php
-rw-r--r-- 1 apache apache 1118 Jul 29 11:29 log_20150729032943.log
-rwxrwxrwx 1 root   root   1208 Jul 29 11:27 wx_access_token.php
root@chantyou:access_token# cat log_20150729032943.log
[2015-07-29 03:29:43] (wx_access_token) tokenUrlPattern=https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=%s&secret=%s
[2015-07-29 03:29:43] (wx_access_token) getTokenUrl=https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=xxx&secret=yyy
[2015-07-29 03:29:43] (wx_access_token) Get response html from url=https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=xxx&secret=yyy
[2015-07-29 03:29:43] (wx_access_token) now add CURLOPT_COOKIEJAR support
[2015-07-29 03:29:43] (wx_access_token) cookieJarFullname=/xxxx/access_token/cookie_jar.txt
[2015-07-29 03:29:44] (wx_access_token) urlResp={"access_token":"f_FvmMYUVcjEDcy2-qjduh51ffm9h0cqxDBgYVo6JtCBApbtWGnq9GMIsLoh-tVj5R-8Mq-S7ALaxSeY8qzv1tSAGusP8nFq3Eh1Y-1qzkE","expires_in":7200}
[2015-07-29 03:29:44] (wx_access_token) respHtml={"access_token":"f_FvmMYUVcjEDcy2-qjduh51ffm9h0cqxDBgYVo6JtCBApbtWGnq9GMIsLoh-tVj5R-8Mq-S7ALaxSeY8qzv1tSAGusP8nFq3Eh1Y-1qzkE","expires_in":7200}
root@chantyou:access_token#

 

后续就可以拿着这个access_token去处理其他事情了,继续处理自定义微信公众号的菜单了。

转载请注明:在路上 » 【已解决】微信公众号开发期间申请ACCESS_TOKEN

发表我的评论
取消评论

表情

Hi,您需要填写昵称和邮箱!

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址
86 queries in 0.370 seconds, using 22.21MB memory