arraytostringphp
㈠ 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次方個,不可能有這么大內存的伺服器。