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

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

PHP crifan 2840浏览 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

<?php
/*
[Filename]
crifanLib.php

[Function]
crifan's php lib, implement common functions

[Author]
Crifan Li

[Contact]
https://www.crifan.com/contact_me/

[Note]
1.online see code:
http://code.google.com/p/crifanlib/source/browse/trunk/php/crifanLib.php

[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中如何实现路径拼接(两个路径合并)以及合并文件夹路径和文件名
     * https://www.crifan.com/php_path_concatenation_combine_directory_and_filename
     * 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中把字符串文本等数据保存到文件中
     * https://www.crifan.com/php_how_to_save_string_text_data_into_file/
     */
    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文件
        https://www.crifan.com/php_log_info_write_to_server_log_file
        
        【已解决】将Log函数的参数改变为类似于sprintf的动态个数的可变参数
        https://www.crifan.com/change_log_function_para_similar_to_sprintf_variable_number/
    */
    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
    ***********************************************************************************************/
    
    //http://php.net/manual/en/book.curl.php
    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;
        }
    }

    //http://cn2.php.net/manual/zh/function.fsockopen.php
    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;
    }

    //http://cn2.php.net/curl_setopt
    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:

<?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

// https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=APPID&secret=APPSECRET

$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");
$tokenUrlPattern = "https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=%s&secret=%s";
$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

 

输出是:

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.201 seconds, using 22.11MB memory