php程序调试微信支付回调请求参数的日记

前言: 

在调试之前,也走了很多弯路,先是学习了http_build_query的使用

PHP 中 http_build_query 函数的作用是使用给定的数组生产 URL-encode 查询字符串
 
先来看一下http_build_query函数的基本语法: 

string http_build_query ( mixed $query_data [, string $numeric_prefix [, string $arg_separator [, int $enc_type = PHP_QUERY_RFC1738 ]]] )

简单来说,http_build_query()就是将一个数组转换成url 问号?后面的参数字符串,并且会自动进行urlencode处理。 

http_build_query参数说明

参数
query_data 可以是数组或包含属性的对象。
一个 query_data 数组可以是简单的一维结构,也可以是由数组组成的数组(其依次可以包含其它数组)。
如果 query_data 是一个对象,只有 public 的属性会加入结果。
numeric_prefix 如果在基础数组中使用了数字下标同时给出了该参数,此参数值将会作为基础数组中的数字下标元素的前缀。
这是为了让 PHP 或其它 CGI 程序在稍后对数据进行解码时获取合法的变量名。
arg_separator 除非指定并使用了这个参数,否则会用 arg_separator.output 来分隔参数。
enc_type

默认使用 PHP_QUERY_RFC1738。

如果 enc_type 是 PHP_QUERY_RFC1738,则编码将会以 » RFC 1738 标准和 application/x-www-form-urlencoded 媒体类型进行编码,空格会被编码成加号(+)。

如果 enc_type 是 PHP_QUERY_RFC3986,将根据 » RFC 3986 编码,空格会被百分号编码(%20)。

http_build_query实例
1、使用一维关联数组:

<?php
$vars = array('page' => 4, 'search' => 'this & that');
$qs = http_build_query($vars);
$url = 'http://www.example.com/search.php?' . $qs;
echo $url;
?>

运行结果:http://www.example.com/search.php?page=4&search=this+%26+that


2、如果是索引数组与关联数组混合而成的数组又如何呢? 它会自动添加数字索引。

http_build_query 还有一个参数,可以给数字索引加前缀,我们再试试:

$data = array(
    'foo',
    'bar',
    'site'=>'www.yumingku.net',
    'name'=>'nowa magic');
echo http_build_query($data, "nm_");

/* output
nm_0=foo&nm_1=bar&site=www.yumingku.net&name=nowa+magic
*/

3、使用二维数组

<?php
$vars = array("database"=>array("sql","mysql"),"dev"=>array('a'=>'php','b'=>'java'));
$qs = http_build_query($vars);
$url = 'http://www.example.com/search.php?' . $qs;
echo $url;
?>

运行结果:http://www.example.com/search.php?database%5B0%5D=sql&database%5B1%5D=mysql&dev%5Ba%5D=php&dev%5Bb%5D=java

4、使用对象

<?php
class myClass { 
   var $foo; 
   var $baz; 
   function myClass() { 
    $this->foo = 'bar'; 
    $this->baz = 'boom'; 
   } 
} 
$data = new myClass(); 
echo 'http://www.example.com/search.php?'.http_build_query($data); 

  运行结果为:http://www.example.com/search.php?foo=bar&baz=boom

使用给出的关联(或下标)数组生成一个 url-encoded 请求字符串。参数 formdata 可以是数组或包含属性的对象。一个 formdata 数组可以是简单的一维结构,也可以是由数组组成的数组(其依次可以包含其它数组)。如果在基础数组中使用了数字下标同时给出了 numeric_prefix 参数,此参数值将会作为基础数组中的数字下标元素的前缀。这是为了让 PHP 或其它 CGI 程序在稍后对数据进行解码时获取合法的变量名。

言归正传

写这篇文章的原因是今天在调试微信支付时发生一件事儿, 能回调成功,却无法成功执行逻辑,预测应该是参数名的问题.想解决这个问题首先要知道回调请求回来到服务器都携带了什么参数!

方法有多种,这里介绍一下其中一二

先把微信支付回调请求的数据解析出来

        $postStr = file_get_contents('php://input');
		//禁止引用外部xml实体
		libxml_disable_entity_loader(true);        
        $postObj = simplexml_load_string($postStr, 'SimpleXMLElement', LIBXML_NOCDATA);
        if ($postObj === false) {
            exit;
            die('parse xml error');
        }
        if ($postObj->return_code != 'SUCCESS') {
            exit;
            die($postObj->return_msg);
        }
        if ($postObj->result_code != 'SUCCESS') {
            exit;
            die($postObj->err_code);
        }
        $arr = (array)$postObj;//参数数组

上面微信支付返回的xml结果参考是通过file_put_content函数写出到txt文档便于查看分析的

file_put_content和fopen,fwrite,fclose组合的使用区别如下

将字符串写入或者追加到文件,file_put_content是一次性向文件写入字符串或追加字符串内容的最合适选择,返回字节数
写入的数据data类型:string、array(多维数组不行)、stream资源
说明:
1、文件不存在则创建
2、文件存在而且已经有内容,默认将清空文件内容,参数中设置FILE_APPEND,可避免清空
       例如:file_put_contents("test.txt", "This is another something.", FILE_APPEND);追加字符串到末尾

注意:
1、file_put_contents文件必须是绝对路劲,相对的不行,而且http协议也不行(无法远程写入)
2、file_get_contents可以使用http协议远程读取
3、一般情况下file_put_contents可替代fopen,fwrite,fclose三个的组合使用,不过他们不是完全等价的,尤其是写入大数据时差异就更加明显了,当输入大数据(超过了当前分配内存)时,应该使用fwrite等三个的组合写入,因为fwrite函数,是一边写入,一边读取的,而file_put_contents是一次性写入的,所以此时file_put_contents写入会出现内存溢出,导致出现诡异的问题,当输入数据小的时候,则file_put_contents执行速率更快
    小结:a、文件大,高并发使用fwrite写入
               b、数据小使用file_put_contents

实例:


$file = 'log.txt';
 
$site =  $postObj;//回调通知参数 
// 向文件追加写入内容
// 使用 FILE_APPEND 标记,可以在文件末尾追加内容
// LOCK_EX 标记可以防止多人同时写入
file_put_contents($file, $site, FILE_APPEND | LOCK_EX);


执行成功后,打开 log.txt 文件,内容为:

<xml><appid><![CDATA[appid]]></appid>
<bank_type><![CDATA[OTHERS]]></bank_type>
<cash_fee><![CDATA[1]]></cash_fee>
<fee_type><![CDATA[CNY]]></fee_type>
<is_subscribe><![CDATA[N]]></is_subscribe>
<mch_id><![CDATA[1596799561]]></mch_id>
<nonce_str><![CDATA[if380wsc1pxekh9juxyk29yoqlzrzvdf]]></nonce_str>
<openid><![CDATA[oRCfRwZdSsUhbXrMtIaQ9CNfOjMM]]></openid>
<out_trade_no><![CDATA[202006102028252]]></out_trade_no>
<result_code><![CDATA[SUCCESS]]></result_code>
<return_code><![CDATA[SUCCESS]]></return_code>
<sign><![CDATA[FC607BEAD46E4FE2E4CB0B812E9836A0]]></sign>
<time_end><![CDATA[20200610202834]]></time_end>
<total_fee>1</total_fee>
<trade_type><![CDATA[JSAPI]]></trade_type>
<transaction_id><![CDATA[4200000547202006103632209909]]></transaction_id>
</xml>



支付结果通知官方文档
https://pay.weixin.qq.com/wiki/doc/api/jsapi.php?chapter=9_7&index=8

看到了回调通知参数的详细信息后,剩下的知道该怎么做了吧,其他支付接口的调试方法基本类似!还是要先看官方的返回类型和请求类型略有不同

另外附上fopen,fwrite,fclose的使用实例

<?php
$myfile = fopen("newfile.txt", "w") or die("Unable to open file!");
$txt = "Bill Gates\n";
fwrite($myfile, $txt);
$txt = "Steve Jobs\n";
fwrite($myfile, $txt);
fclose($myfile);
?>

C函数fopen中可对打开的文件设置多种读写模式,需要说明下fwrite的追加模式是怎么回事,网上很多文章都说的不清不楚,只说a是追加,w不能追加,其实很多误解,这里需要澄清:


w:表示fopen文件时会清空掉原文件(如果存在)的信息,并重新写入,在不fclose文件的情况下,多次fwrite也是追加写入到文件末尾的,不会覆盖之前fwrite的内容。
a:表示fopen文件时会保留原文件(如果存在)的信息,并追加到末尾写入,每次fwrite写入到文件末尾。

其他说明:
w:  文本写入,只写
w+:可读可写
wb:  二进制写入,只写
wb+:  二进制写入或读出,可读可写
a:对fopen的文件追加写入,文本形式
ab:对fopen的文件追加写入,二进制形式
ab+:对fopen的文件追加写入或读出,二进制形式
————————————————
//获取域名或主机地址
echo $_SERVER['HTTP_HOST']."<br />"; #mp.csdn.net

//获取网页地址
echo $_SERVER['PHP_SELF']."<br />"; #/p/1.html

//获取网址参数
echo $_SERVER["QUERY_STRING"]."<br />"; #id=1

//获取用户代理
echo $_SERVER['HTTP_REFERER']."<br />";

//获取完整的url
echo 'http://'.$_SERVER['HTTP_HOST'].$_SERVER['REQUEST_URI'];
echo 'http://'.$_SERVER['HTTP_HOST'].$_SERVER['PHP_SELF'].'?'.$_SERVER['QUERY_STRING'];
#http://mp.csdn.net/p/1.html?id=1

//包含端口号的完整url
echo 'http://'.$_SERVER['SERVER_NAME'].':'.$_SERVER["SERVER_PORT"].$_SERVER["REQUEST_URI"];
#http://mp.csdn.net:80/p/1.html?id=1

//只取路径
$url='http://'.$_SERVER['SERVER_NAME'].$_SERVER["REQUEST_URI"];
echo dirname($url);
#http://mp.csdn.net/p

猜你喜欢

转载自blog.csdn.net/Sncdma/article/details/106686164