当前位置:首页 » 编程语言 » arraytostringphp

arraytostringphp

发布时间: 2022-02-17 19:15:31

php 后台生成微信预支付订单 为什么查询不到

<?php
namespace common\services\WechatPay;
class WechatAppPay extends WechatPayBase
{
//package参数
public $package = [];
//异步通知参数
public $notify = [];
//推送预支付订单参数
protected $config = [];
//存储access token和获取时间的文件
protected $file;
//access token
protected $accessToken;
//取access token的url
const ACCESS_TOKEN_URL = 'https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=%s&secret=%s';
//生成预支付订单提交地址
const POST_ORDER_URL = 'https://api.weixin.qq.com/pay/genprepay?access_token=%s';
public function __construct()
{
$this->file = __DIR__ . '/payAccessToken.txt';
}
/**
* 创建APP支付最终返回参数
* @throws \Exception
* @return multitype:string NULL
*/
public function createAppPayData()
{
$this->generateConfig();
$prepayid = $this->getPrepayid();
try{
$array = [
'appid' => $this->appid,
'appkey' => $this->paySignkey,
'noncestr' => $this->getRandomStr(),
'package' => 'Sign=WXPay',
'partnerid' => $this->partnerId,
'prepayid' => $prepayid,
'timestamp' => (string)time(),
];
$array['sign'] = $this->sha1Sign($array);
unset($array['appkey']);
} catch(\Exception $e) {
throw new \Exception($e->getMessage());
}
return $array;
}
/**
* 验证支付成功后的通知参数
*
* @throws \Exception
* @return boolean
*/
public function verifyNotify()
{
try{
$staySignStr = $this->notify;
unset($staySignStr['sign']);
$sign = $this->signData($staySignStr);
return $this->notify['sign'] === $sign;
} catch(\Exception $e) {
throw new \Exception($e->getMessage());
}
}
/**
* 魔术方法,给添加支付参数进来
*
* @param string $name 参数名
* @param string $value 参数值
*/
public function __set($name, $value)
{
$this->$name = $value;
}
/**
* 设置access token
* @param string $token
* @throws \Exception
* @return boolean
*/
public function setAccessToken()
{
try{
if(!file_exists($this->file) || !is_file($this->file)) {
$f = fopen($this->file, 'a');
fclose($f);
}
$content = file_get_contents($this->file);
if(!empty($content)) {
$info = json_decode($content, true);
if( time() - $info['getTime'] < 7150 ) {
$this->accessToken = $info['accessToken'];
return true;
}
}
//文件内容为空或access token已失效,重新获取
$this->outputAccessTokenToFile();
} catch(\Exception $e) {
throw new \Exception($e->getMessage());
}
return true;
}
/**
* 写入access token 到文件
* @throws \Exception
* @return boolean
*/
protected function outputAccessTokenToFile()
{
try{
$f = fopen($this->file, 'wb');
$token = [
'accessToken' => $this->getAccessToken(),
'getTime' => time(),
];
flock($f, LOCK_EX);
fwrite($f, json_encode($token));
flock($f, LOCK_UN);
fclose($f);
$this->accessToken = $token['accessToken'];
} catch(\Exception $e) {
throw new \Exception($e->getMessage());
}
return true;
}
/**
* 取access token
*
* @throws \Exception
* @return string
*/
protected function getAccessToken()
{
$url = sprintf(self::ACCESS_TOKEN_URL, $this->appid, $this->appSecret);
$result = json_decode( $this->getUrl($url), true );
if(isset($result['errcode'])) {
throw new \Exception("get access token failed:{$result['errmsg']}");
}
return $result['access_token'];
}
/**
* 取预支付会话标识
*
* @throws \Exception
* @return string
*/
protected function getPrepayid()
{
$data = json_encode($this->config);
$url = sprintf(self::POST_ORDER_URL, $this->accessToken);
$result = json_decode( $this->postUrl($url, $data), true );
if( isset($result['errcode']) && $result['errcode'] != 0 ) {
throw new \Exception($result['errmsg']);
}
if( !isset($result['prepayid']) ) {
throw new \Exception('get prepayid failed, url request error.');
}
return $result['prepayid'];
}
/**
* 组装预支付参数
*
* @throws \Exception
*/
protected function generateConfig()
{
try{
$this->config = [
'appid' => $this->appid,
'traceid' => $this->traceid,
'noncestr' => $this->getRandomStr(),
'timestamp' => time(),
'package' => $this->generatePackage(),
'sign_method' => $this->sign_method,
];
$this->config['app_signature'] = $this->generateSign();
} catch(\Exception $e) {
throw new \Exception($e->getMessage());
}
}
/**
* 生成package字段
*
* 生成规则:
* 1、生成sign的值signValue
* 2、对package参数再次拼接成查询字符串,值需要进行urlencode
* 3、将sign=signValue拼接到2生成的字符串后面得到最终的package字符串
*
* 第2步urlencode空格需要编码成%20而不是+
*
* RFC 1738会把 空格编码成+
* RFC 3986会把空格编码成%20
*
* @return string
*/
protected function generatePackage()
{
$this->package['sign'] = $this->signData($this->package);
return http_build_query($this->package, '', '&', PHP_QUERY_RFC3986);
}
/**
* 生成签名
*
* @return string
*/
protected function generateSign()
{
$signArray = [
'appid' => $this->appid,
'appkey' => $this->paySignkey,
'noncestr' => $this->config['noncestr'],
'package' => $this->config['package'],
'timestamp' => $this->config['timestamp'],
'traceid' => $this->traceid,
];
return $this->sha1Sign($signArray);
}
/**
* 签名数据
*
* 生成规则:
* 1、字典排序,拼接成查询字符串格式,不需要urlencode
* 2、上一步得到的字符串最后拼接上key=paternerKey
* 3、MD5哈希字符串并转换成大写得到sign的值signValue
*
* @param array $data 待签名数据
* @return string 最终签名结果
*/
protected function signData($data)
{
ksort($data);
$str = $this->arrayToString($data);
$str .= "&key={$this->partnerKey}";
return strtoupper( $this->signMd5($str) );
}
/**
* sha1签名
* 签名规则
* 1、字典排序
* 2、拼接查询字符串
* 3、sha1运算
*
* @param array $arr
* @return string
*/
protected function sha1Sign($arr)
{
ksort($arr);
return sha1( $this->arrayToString($arr) );
}
}

java代码如何反序列化PHP序列化数组后的字符串

public class ByteTest { public static void main(String[] args) { String str = "Hello world!"; // string转byte byte[] bs = str.getBytes(); System.out.println(Arrays.toString(bs)); // byte转string String str2 = new String(bs); System.out.println(str2); } }

㈢ PHP实现多维数组转字符串和多维数组转一维数组的方法

本文实例讲述了PHP实现多维数组转字符串和多维数组转一维数组的方法。分享给大家供大家参考。具体实现方法如下:
/**
*
@method
多维数组转字符串
*
@param
type
$array
*
@return
type
$srting
*
@author
yanhuixian
*/
function
arrayToString($arr)
{
if
(is_array($arr)){
return
implode(',',
array_map('arrayToString',
$arr));
}
return
$arr;
}
/**
*
@method
多维数组变成一维数组
*
@staticvar
array
$result_array
*
@param
type
$array
*
@return
type
$array
*
@author
yanhuixian
*/
function
multi2array($array)
{
static
$result_array
=
array();
foreach
($array
as
$key
=>
$value)
{
if
(is_array($value))
{
array_multi2array($value);
}
else
$result_array[$key]
=
$value;
}
return
$result_array;
}
希望本文所述对大家的php程序设计有所帮助。

㈣ 用php写一个网页程序,功能是判断服务器上QQ程序运行了多长时间

CGIC介绍
怎样写CGIC应用程序
怎样产生图片在CGIC中?
CGI调试特征: 利用捕获
cgic函数参考
cgic变量参考
cgic结果编码参考
cgic快速索引

一般的UNIX系统都支持ANSIC,增加相应的库函数(和相应的h文件)就可以实现CGI。在此我向大家推荐一个用于CGI编程的ANSIC库:cgic。

cgic是用来生成基于CGI的WWW应用程序的C语言函数库,它有以下功能:

*对数据进行语法分析

*接收以GET和PSOT两种方式发送的数据

*把FORM中的不同域连接成连续的串

*为检索FORM数据而提供字符串,整数,浮点以及单项和多项选择功能

*为数字字段提供边界检测

*把CGI环境变量加载到非空的C串中

*为调试而捕捉CGI状态

*提供相对安全的系统调用功能

用一般ANSI C或C++编译器就可以编译cgic程序,不过与通常C程序不同的是,用cgic写的源码其主函数是cgiMain(),而不是通常的main()。cgic的函数库会自动把cgiMain连接到相应的main()上去。

--------------------------------------------------------------------------------

写CGIC程序
Note: 所有的cgic应用程序必须连接cgic.c.
用cgimain()替代main() 必须包含: #include"cgic.h."

基本结构cgictest.c:

int cgiMain() {
#if DEBUG
/* Load a saved CGI scenario if we're debugging */
cgiReadEnvironment("/path/to/capcgi.dat");
#endif
/* Important: we must indicate the type of document */
cgiHeaderContentType("text/html");
/* Now invoke other functions to handle each part of the form */
fprintf(cgiOut, "<HTML><HEAD>\n");
fprintf(cgiOut, "<TITLE>cgic test</TITLE></HEAD>\n"):
fprintf(cgiOut, "<BODY><H1>cgic test</H1>\n");
Name();
Address();
Hungry();
Temperature();
Frogs();
Color();
Flavors();
NonExButtons();
RadioButtons();
fprintf(cgiOut, "</BODY></HTML>\n");
/* This value will be the exit code of the program; 0
generally indicates success among Unix and DOS programs */
return 0;
}

capture
输出标头
cgiHeaderContentType()在输出文挡之前简要说明MIME内型,如 "text/html"。
cgiHeaderStatus()代替输出错误代码 cgiHeaderLocation()代替重新引导至其他页面。在一个独立的应用程序中只能有一个cgiHeader函数。

重点:在cgiHeader函数组中, cgiHeaderContentType(), 在任何向浏览器输出之前被调用. 否则将出错或浏览器不能识别。 cgiOut

接着, cgiMain() 调用不同的函数.当函数结束后,将返回0

处理输入文本
void Name() {
char name[81];
cgiFormStringNoNewlines("name", name, 81);
fprintf(cgiOut, "Name: %s<BR>\n", name);
}

这个函数的功能就是取的并显示由用户输入的name .
处理输出
Important: cgiOut通常相当于stdout

cgiFormString 确保断航

处理单一Checkboxes输入
这个Hungry() function确定用户是否选择"hungry"这个 checkbox:
void Hungry() {
if (cgiFormCheckboxSingle("hungry") == cgiFormSuccess) {
fprintf(cgiOut, "I'm Hungry!<BR>\n");
} else {
fprintf(cgiOut, "I'm Not Hungry!<BR>\n");
}
}

这个函数依靠 cgiFormCheckboxSingle() 确定单一的checkbox 被选择。 cgiFormCheckboxSingle() 接受checkbox名字的属性值,如果存在就返回 cgiFormSuccess,否则返回cgiFormNotFound 如果是多项checkboxes,就用 cgiFormCheckboxMultiple()和cgiFormStringMultiple() 函数.
处理数字输入
Temperature() 返回浮点书的值确保在特定的返回内。
void Temperature() {
double temperature;
cgiFormDoubleBounded("temperature", &temperature, 80.0, 120.0, 98.6);
fprintf(cgiOut, "My temperature is %f.<BR>\n", temperature);
}

依靠cgiFormDoubleBounded()得到数据.第一个数据是返回数据中输入域的名字。最后一个值是用户没有提交时的默认值。
这个函数总是找回在特定返回内合适的值; cgiFormDoubleBounded返回的值被检查确信用户输入的资料在规定范围内, 而不是其他无效的数据。查看 cgiFormDoubleBounded() 更多的资料. 如果限度检查不理想,可以用 cgiFormDouble() 替代.

在整数输入,cgiFormInteger 和 cgiFormIntegerBounded 可以利用. 这些函数的功能类似.

处理单一选择输入
<SELECT> HTML标签被用于向用户提供几个选择. Radio buttons 和checkboxes 椰油这样的用途,大门、能够选择的数量很小时. Color()
char *colors[] = {
"Red",
"Green",
"Blue"
};

void Color() {
int colorChoice;
cgiFormSelectSingle("colors", colors, 3, &colorChoice, 0);
fprintf(cgiOut, "I am: %s<BR>\n", colors[colorChoice]);
}

这个函数确定用户选择了几个选项从<SELECT> 在表但的列表. cgiFormSelectSingle()
cgiFormSelectSingle() 总是显示合理的选项值.

radio button也可以用这个函数.另外还有 cgiFormRadio(), 也是一样的

处理多项选择的输入
NonExButtons()
char *votes[] = {
"A",
"B",
"C",
"D"
};

void NonExButtons() {
int voteChoices[4];
int i;
int result;
int invalid;

char **responses;

/* Method #1: check for valid votes. This is a good idea,
since votes for nonexistent candidates should probably
be discounted... */
fprintf(cgiOut, "Votes (method 1):<BR>\n");
result = cgiFormCheckboxMultiple("vote", votes, 4,
voteChoices, &invalid);
if (result == cgiFormNotFound) {
fprintf(cgiOut, "I hate them all!<p>\n");
} else {
fprintf(cgiOut, "My preferred candidates are:\n");
fprintf(cgiOut, "<ul>\n");
for (i=0; (i < 4); i++) {
if (voteChoices[i]) {
fprintf(cgiOut, "<li>%s\n", votes[i]);
}
}
fprintf(cgiOut, "</ul>\n");
}

参考cgiFormCheckboxMultiple(), cgiFormSelectMultiple().
cgiFormCheckboxMultiple() cgiFormCheckboxMultiple

NonExButtons() 函数在 cgictest.c:

/* Method #2: get all the names voted for and trust them.
This is good if the form will change more often
than the code and invented responses are not a danger
or can be checked in some other way. */
fprintf(cgiOut, "Votes (method 2):<BR>\n");
result = cgiFormStringMultiple("vote", &responses);
if (result == cgiFormNotFound) {
fprintf(cgiOut, "I hate them all!<p>\n");
} else {
int i = 0;
fprintf(cgiOut, "My preferred candidates are:\n");
fprintf(cgiOut, "<ul>\n");
while (responses[i]) {
fprintf(cgiOut, "<li>%s\n", responses[i]);
i++;
}
fprintf(cgiOut, "</ul>\n");
}
/* We must be sure to free the string array or a memory
leak will occur. Simply calling free() would free
the array but not the indivial strings. The
function cgiStringArrayFree() does the job completely. */
cgiStringArrayFree(responses);
}

参考cgiFormStringMultiple()
cgiFormStringMultiple()

/* An array of strings; each C string is an array of characters */
char **responses;

cgiFormStringMultiple("vote", &responses);

检查CGI环境变量
将用到的变量 这里,
产生图象

#include "cgic.h"
#include "gd.h"

char *colors[] = {
"red", "green", "blue"
};

#define colorsTotal 3

int cgiMain() {
int colorChosen;
gdImagePtr im;
int r, g, b;
/* Use gd to create an image */
im = gdImageCreate(64, 64);
r = gdImageColorAllocate(im, 255, 0, 0);
g = gdImageColorAllocate(im, 0, 255, 0);
b = gdImageColorAllocate(im, 0, 0, 255);
/* Now use cgic to find out what color the user requested */
cgiFormSelectSingle("color", 3, &colorChosen, 0);
/* Now fill with the desired color */
switch(colorChosen) {
case 0:
gdImageFill(im, 32, 32, r);
break;
case 1:
gdImageFill(im, 32, 32, g);
break;
case 2:
gdImageFill(im, 32, 32, b);
break;
}
/* Now output the image. Note the content type! */
cgiHeaderContentType("image/gif");
/* Send the image to cgiOut */
gdImageGif(im, cgiOut);
/* Free the gd image */
gdImageDestroy(im);
return 0;
}

为调试而捕捉CGI状态
cgic函数参考
cgiFormResultType cgiFormString( char *name, char *result, int max)
用于从输入域中字符串。他将域名max-1字节中的字符到缓冲区result。若域不存在,则一个空串到result缓冲区。在此函数中所有的新行由换行符代表。

cgiFormResultType cgiFormStringNoNewlines( char *name, char *result, int max)
它与cgiFormString函数相似,只是所有的CR和LF都被去掉了。

cgiFormResultType cgiFormStringSpaceNeeded( char *name, int *length)
它返回指向name的字符串的长度,并将长度放入length中。

cgiFormResultType cgiFormStringMultiple( char *name, char ***ptrToStringArray)
若同一名字有多个输入域,或域中的字符串可以动态变化,那么你可以使用本函数。它把名为name的所有输入域的值放在prtToStringArray中。

void cgiStringArrayFree(char **stringArray)
它释放了分配给stringArray的内存。

cgiFormResultType cgiFormInteger( char *name, int *result, int defaultV)
从输入域中取出整数放入result中。

cgiFormResultType cgiFormIntegerBounded( char *name, int *result, int min, int max, int defaultV)
若输入域中的整数在界限内则取出并放入result中。

cgiFormResultType cgiFormDouble( char *name, double *result, double defaultV)
从输入域中取出浮点数放入result中。

cgiFormResultType cgiFormDoubleBounded( char *name, double *result, double min, double max, double defaultV)
若输入域中的浮点数在界限内则取出并放入result中。

cgiFormResultType cgiFormSelectSingle( char *name, char **choicesText, int choicesTotal, int *result, int defaultV)
取出复选框(跟在select语句之后的),把选择的名字到choicesText,把选择的个数到choicesTotal,把当前的选择到result。
cgiFormResultType cgiFormSelectMultiple( char *name, char **choicesText, int choicesTotal, int *result, int *invalid)
与cgiFormSelectSingle类似,只指向整型数组的result代表了选择的项。

cgiFormResultType cgiFormCheckboxSingle( char *name)
若复选框被选中,则函数返回cgiFormSuccess,否则返回cgiFormNotFound。

cgiFormResultType cgiFormCheckboxMultiple( char *name, char **valuesText, int valuesTotal, int *result, int *invalid)
与cgiFormCheckboxSingle类似,但它处理同一名字有多个复选框的情况。name指向复选框的名字;valuesText指向包含有每个复选框中参数的一个数组;valuesTotal指向复选框的总数;result是一个整型数组,每个复选框选中的用1代表,没选中的用0代表。

cgiFormResultType cgiFormRadio( char *name, char **valuesText, int valuesTotal, int *result, int defaultV)
与cgiFormCheckboxMultiple相似,只是这里是单选按钮而不是复选框。

void cgiHeaderLocation(char *redirectUrl)
重定向到redirectUrl指定的URL。

void cgiHeaderStatus(int status, char *statusMessage)
输出状态代码status和消息statusMessage。

void cgiHeaderContentType(char *mimeType)
用于告知浏览器返回的是什么类型的文档。

cgiEnvironmentResultType cgiWriteEnvironment(char *filename)
本函数把当前CGI环境写入filename文件中以便以后调试时使用

cgiEnvironmentResultType cgiReadEnvironment(char *filename)
本函数从filename文件中读取CGI环境以便用来调试。

int cgiMain()
一个程序必须要写这个函数, 这是主程序开始之处。
cgic变量参考
This section provides a reference guide to the various global variables provided by cgic for the programmer to utilize. These variables should always be used in preference to stdin, stdout, and calls to getenv() in order to ensure compatibility with the cgic CGI debugging features.
大多数的变量相当于各种CGI变量,重要的是VGIC的变量不能为空.

char *cgiServerSoftware
服务器软件名称,或者一个空的字符串 or to an empty string if unknown.
char *cgiServerName
返回服务器名称或空
char *cgiGatewayInterface
网关接口 (通常是 CGI/1.1),或空
char *cgiServerProtocol
网络协议(usually HTTP/1.0),或空
char *cgiServerPort
服务器端口(usually 80),或空
char *cgiRequestMethod
请求方式 (usually GET or POST),或空
char *cgiPathInfo
指出附加虚拟路径
char *cgiPathTranslated
指出附加虚拟路径并由服务器转为本地路径
char *cgiScriptName
调用程序的名字
char *cgiQueryString
包含 GET-method 请求或者 <ISINDEX> 标签. 这个信息不需要解吸,除非用<ISINDEX>标签通常由CGIC函数库自动解析。
char *cgiRemoteHost
从浏览器返回客户主机的名字
char *cgiRemoteAddr
从浏览器返回客户的IP地址
char *cgiAuthType
返回用户授权信息
char *cgiRemoteUser
鉴别用户 cgiAuthType.
char *cgiRemoteIdent
返回用户的名字(用户通过用户坚定协议)这个消息是不安全的,特别是Windows系统。
char *cgiContentType
返回MIME内型
char *cgiAccept
参考 cgiHeaderContentType() cgiUserAgent
char *cgiUserAgent
取的用户浏览器信息
char *cgiReferrer
指向用户访问的URL.
int cgiContentLength
表单或查询数据的字节被认为是标准的.
FILE *cgiOut
CGI输出. cgiHeader函数,象cgiHeaderContentType, 首先被用于输出mime头; 用于 fprintf() 和fwrite(). cgiOut通常相当于stdout。
FILE *cgiIn
CGI输入. 在决大部分时间你都不会需要这个函数。
cgic结果编码参考
在大量的按列中, cgic函数有计划的产生合理的结果,甚至浏览器和用户不合理时。无论如何, 有时候知道不合理的事情发生,尤其赋予一个值或定义一个范围是一个不充分的解决方案。下面的这些结果编码有助更好了解。

cgiFormSuccess
提交信息成功
cgiFormTruncated
删除部分字节.
cgiFormBadType
错误的输入信息(没有按要求)
cgiFormEmpty
提交信息为空.
cgiFormNotFound
提交信息没有找到.
cgiFormConstrained
数字属于某个特定的范围,被迫低于或高于适当范围。
cgiFormNoSuchChoice
单一选择提交的值是不被接受。通常说明表但和程序之间存在矛盾。
cgiEnvironmentIO
从CGI环境或获取的文件读或写的企图失败,报出I/O的错误。
cgiEnvironmentMemory
从CGI环境或获取的文件读或写的企图失败,报出out-of-memory的错误。
cgiEnvironmentSuccess
从CGI环境或获取的文件读或写的企图成功。
cgic快速索引

㈤ 如何把action中的json数组传到页面呢 在用面怎么接受这个json数组呢

你好,你可以放session 啊
在return this.SUCCESS之前加:

ServletActionContext.getRequest().setAttribute("data", aa);
页面上这样处理:
String ajson = getAttribute("data");

这里开始解析,就行了

配置文件:
<result type="json">
<!-- 这里指定将被Struts2序列化的属性,该属性在action中必须有对应的getter方法 -->
<param name="root">dataMap</param>
</result>

O(∩_∩)O~温馨提示O(∩_∩)O~
真心希望你能采纳我的回答,如有不明白,可以继续追问,若满意,记得及时采纳。

㈥ android怎么传一个数组给PHP,大神帮我改改下面的代码

你好。
把JSONArray直接toString,
发到server,php直接转换成jsonarray就是了

希望回答对你有帮助,如果有疑问,请继续追问
答题不易,互相理解,您的采纳是我前进的动力,感谢您。

㈦ 求php银联支付简单demo(unionpay)

<?php
namespace common\services;
class UnionPay
{
/**
* 支付配置
* @var array
*/
public $config = [];
/**
* 支付参数,提交到银联对应接口的所有参数
* @var array
*/
public $params = [];
/**
* 自动提交表单模板
* @var string
*/
private $formTemplate = <<<'HTML'
<!DOCTYPE HTML>
<html>
<head>
<meta charset="utf-8">
<title>支付</title>
</head>
<body>
<div style="text-align:center">跳转中...</div>
<form id="pay_form" name="pay_form" action="%s" method="post">
%s
</form>
<script type="text/javascript">
document.onreadystatechange = function(){
if(document.readyState == "complete") {
document.pay_form.submit();
}
};
</script>
</body>
</html>
HTML;
/**
* 构建自动提交HTML表单
* @return string
*/
public function createPostForm()
{
$this->params['signature'] = $this->sign();
$input = '';
foreach($this->params as $key => $item) {
$input .= "\t\t<input type=\"hidden\" name=\"{$key}\" value=\"{$item}\">\n";
}
return sprintf($this->formTemplate, $this->config['frontUrl'], $input);
}
/**
* 验证签名
* 验签规则:
* 除signature域之外的所有项目都必须参加验签
* 根据key值按照字典排序,然后用&拼接key=value形式待验签字符串;
* 然后对待验签字符串使用sha1算法做摘要;
* 用银联公钥对摘要和签名信息做验签操作
*
* @throws \Exception
* @return bool
*/
public function verifySign()
{
$publicKey = $this->getVerifyPublicKey();
$verifyArr = $this->filterBeforSign();
ksort($verifyArr);
$verifyStr = $this->arrayToString($verifyArr);
$verifySha1 = sha1($verifyStr);
$signature = base64_decode($this->params['signature']);
$result = openssl_verify($verifySha1, $signature, $publicKey);
if($result === -1) {
throw new \Exception('Verify Error:'.openssl_error_string());
}
return $result === 1 ? true : false;
}
/**
* 取签名证书ID(SN)
* @return string
*/
public function getSignCertId()
{
return $this->getCertIdPfx($this->config['signCertPath']);
}
/**
* 签名数据
* 签名规则:
* 除signature域之外的所有项目都必须参加签名
* 根据key值按照字典排序,然后用&拼接key=value形式待签名字符串;
* 然后对待签名字符串使用sha1算法做摘要;
* 用银联颁发的私钥对摘要做RSA签名操作
* 签名结果用base64编码后放在signature域
*
* @throws \InvalidArgumentException
* @return multitype|string
*/
private function sign() {
$signData = $this->filterBeforSign();
ksort($signData);
$signQueryString = $this->arrayToString($signData);
if($this->params['signMethod'] == 01) {
//签名之前先用sha1处理
//echo $signQueryString;exit;
$datasha1 = sha1($signQueryString);
$signed = $this->rsaSign($datasha1);
} else {
throw new \InvalidArgumentException('Nonsupport Sign Method');
}
return $signed;
}
/**
* 数组转换成字符串
* @param array $arr
* @return string
*/
private function arrayToString($arr)
{
$str = '';
foreach($arr as $key => $value) {
$str .= $key.'='.$value.'&';
}
return substr($str, 0, strlen($str) - 1);
}
/**
* 过滤待签名数据
* signature域不参加签名
*
* @return array
*/
private function filterBeforSign()
{
$tmp = $this->params;
unset($tmp['signature']);
return $tmp;
}
/**
* RSA签名数据,并base64编码
* @param string $data 待签名数据
* @return mixed
*/
private function rsaSign($data)
{
$privatekey = $this->getSignPrivateKey();
$result = openssl_sign($data, $signature, $privatekey);
if($result) {
return base64_encode($signature);
}
return false;
}
/**
* 取.pfx格式证书ID(SN)
* @return string
*/
private function getCertIdPfx($path)
{
$pkcs12certdata = file_get_contents($path);
openssl_pkcs12_read($pkcs12certdata, $certs, $this->config['signCertPwd']);
$x509data = $certs['cert'];
openssl_x509_read($x509data);
$certdata = openssl_x509_parse($x509data);
return $certdata['serialNumber'];
}
/**
* 取.cer格式证书ID(SN)
* @return string
*/
private function getCertIdCer($path)
{
$x509data = file_get_contents($path);
openssl_x509_read($x509data);
$certdata = openssl_x509_parse($x509data);
return $certdata['serialNumber'];
}
/**
* 取签名证书私钥
* @return resource
*/
private function getSignPrivateKey()
{
$pkcs12 = file_get_contents($this->config['signCertPath']);
openssl_pkcs12_read($pkcs12, $certs, $this->config['signCertPwd']);
return $certs['pkey'];
}
/**
* 取验证签名证书
* @throws \InvalidArgumentException
* @return string
*/
private function getVerifyPublicKey()
{
//先判断配置的验签证书是否银联返回指定的证书是否一致
if($this->getCertIdCer($this->config['verifyCertPath']) != $this->params['certId']) {
throw new \InvalidArgumentException('Verify sign cert is incorrect');
}
return file_get_contents($this->config['verifyCertPath']);
}
}

//银联支付设置
'unionpay' => [
//测试环境参数
'frontUrl' => 'https://101.231.204.80:5000/gateway/api/frontTransReq.do', //前台交易请求地址
//'singleQueryUrl' => 'https://101.231.204.80:5000/gateway/api/queryTrans.do', //单笔查询请求地址
'signCertPath' => __DIR__.'/../keys/unionpay/test/sign/700000000000001_acp.pfx', //签名证书路径
'signCertPwd' => '000000', //签名证书密码
'verifyCertPath' => __DIR__.'/../keys/unionpay/test/verify/verify_sign_acp.cer', //验签证书路径
'merId' => 'xxxxxxx',
//正式环境参数
//'frontUrl' => 'https://101.231.204.80:5000/gateway/api/frontTransReq.do', //前台交易请求地址
//'singleQueryUrl' => 'https://101.231.204.80:5000/gateway/api/queryTrans.do', //单笔查询请求地址
//'signCertPath' => __DIR__.'/../keys/unionpay/test/sign/PM_700000000000001_acp.pfx', //签名证书路径
//'signCertPwd' => '000000', //签名证书密码
//'verifyCertPath' => __DIR__.'/../keys/unionpay/test/verify/verify_sign_acp.cer', //验签证书路径
//'merId' => 'xxxxxxxxx', //商户代码
],

㈧ android怎么传一个数组给PHP,大神帮我改改下面的代码

你好。 把JSONArray直接toString, 发到server,php直接转换成jsonarray就是了 希望回答对你有帮助,如果有疑问,请继续追问 答题不易,互相理解,您的采纳是我前进的动力,感谢您。

㈨ php内存优化,哪位大神帮我做下优化,现在内存占用很高

组合数本来就巨大,长度为100的时候,结果数组是100的100次方个,不可能有这么大内存的服务器。

热点内容
在c语言编译器编辑程序视频 发布:2025-01-07 07:33:22 浏览:284
不卡顿机顶盒需什么配置 发布:2025-01-07 07:33:19 浏览:778
群晖读写缓存掉电 发布:2025-01-07 07:32:42 浏览:236
玩崩坏3安卓用什么手机好 发布:2025-01-07 07:31:53 浏览:3
大数进位算法 发布:2025-01-07 07:26:23 浏览:81
一闪安卓版在哪里下 发布:2025-01-07 07:26:18 浏览:943
哈佛第三代最高配有什么配置 发布:2025-01-07 07:19:09 浏览:408
电脑配置不高用ps什么版本 发布:2025-01-07 07:16:52 浏览:187
没用的车有哪些配置 发布:2025-01-07 07:16:50 浏览:675
电脑打开服务器卡的很 发布:2025-01-07 07:16:45 浏览:982