當您將PDT交易ID發回貝寶時,您將返回交易數據列表。它在第一行有SUCCESS,然後是鍵=值對列表。每行一對。例如:PHP:如何快速將密鑰=值文件分割爲關聯數組
SUCCESS
[email protected]
charset=windows-1252
custom=
first_name=Alice
handling_amount=0.00
invoice=NN0005
item_name=Bear
item_number=BEAR05
last_name=Foobar
mc_currency=SEK
mc_fee=13.00
mc_gross=250.00
[email protected]
payer_id=UC9DXVX7GRSTN
payer_status=unverified
payment_date=09:08:06 Oct 18, 2010 PDT
payment_fee=
payment_gross=
payment_status=Completed
payment_type=instant
protection_eligibility=Ineligible
quantity=1
receipt_id=2479-2605-1192-2880
[email protected]
receiver_id=8Y670ENTB8BY6
residence_country=NO
shipping=0.00
tax=0.00
transaction_subject=Bear
txn_id=1PH815997L239283J
txn_type=web_accept
什麼是檢查第一行是否等於SUCCESS然後將其轉換爲關聯數組的好方法,快速而乾淨的方法?我能夠做到這一點,但它很有用,但我很好奇,如果有更好或更乾淨的做法,導致我最終結果並不總是那麼好。請注意,某些鍵也沒有任何值。
所以,我想直到結束本質是:
array(
'business' => '[email protected]',
'charset' => 'windows-1252',
'custom' => NULL,
'first_name' => Alice,
// And so on
);
的順序並不重要。
更新:感謝您的偉大建議!現在測試它們。順便把字符串拆分成不同的行也是我的問題的一部分。忘了說明一下。看到有些人已經考慮到了這一點,有些則沒有。它可以產生影響,因爲某些方法需要首先分割成線條,然後再分割成兩條線,而另一些方法則可以將整個東西整體分割。
更新:我還應該提到,有空的結束爲NULL將是一個獎金,但可能不是必需的。他們在我的版本中也沒有這樣做,這並不重要。
基準測試結果
得到了好奇,我應該選擇這裏什麼,所以我爲基準我應該怎麼做不同的部分。我自己有各種各樣的想法,也從這裏和其他地方得到了一些。當我找到了我能夠管理的最快速度時,我創建了一個基準並針對迄今爲止的所有答案進行了測試。對於跳過分裂或成功檢查的人,我添加了一個explode
和strpos
相應的檢查。我還爲所有的解決方案添加了urldecode,除了@dynamism,他們很好地解決了這個問題。不管怎麼說,這裏的結果:
基準是使用codebench 模塊運行。下面是基準代碼:
<?php defined('SYSPATH') or die('No direct script access.');
/**
* Test various methods of checking for SUCCESS
*
* @package PayPal
* @category PDT
* @author Torleif Berger
*/
class Bench_ProcessPDT extends Codebench
{
public $description = 'Various ways of checking that a string starts with SUCCESS';
public $loops = 100000;
public function bench_mine($subject)
{
if(strpos($subject, 'SUCCESS') === 0)
{
$subject = urldecode(substr($subject, 7));
preg_match_all('/^([^=]++)=(.*+)/m', $subject, $result, PREG_PATTERN_ORDER);
$result = array_combine($result[1], $result[2]);
return array(count($result), array_shift($result), array_shift($result));
}
return FALSE;
}
// http://stackoverflow.com/questions/3964219/3964308#3964308
public function bench_dynamism_substr($subject)
{
if(substr($subject, 0, 7) == 'SUCCESS')
{
$subject = substr_replace($subject, '', 0, 7);
$subject = str_replace(array("\n", "\r", "\r\n"), '&', $subject);
parse_str($subject, $result);
return array(count($result), array_shift($result), array_shift($result));
}
return FALSE;
}
// http://stackoverflow.com/questions/3964219/3964308#3964308
public function bench_dynamism_strpos($subject)
{
if(strpos($subject, 'SUCCESS') === 0)
{
$subject = substr_replace($subject, '', 0, 7);
$subject = str_replace("\r\n", '&', $subject);
parse_str($subject, $result);
return array(count($result), array_shift($result), array_shift($result));
}
return FALSE;
}
// http://stackoverflow.com/questions/3964219/3964520#3964520
public function bench_mellowsoon($subject)
{
$subject = urldecode($subject);
$lines = explode("\r\n", $subject);
$lines = array_map('trim', $lines);
$status = array_shift($lines);
if($status == 'SUCCESS')
{
$result = array();
foreach($lines as $line)
{
list($key, $value) = explode('=', $line, 2);
$result[$key] = $value;
}
return array(count($result), array_shift($result), array_shift($result));
}
return FALSE;
}
// http://stackoverflow.com/questions/3964219/3964265#3964265
public function bench_amber($subject)
{
if(strpos($subject, 'SUCCESS') === 0)
{
$subject = explode("\r\n", urldecode($subject));
array_shift($subject); // Remove is empty
$result = array();
foreach($subject as $line)
{
$bits = explode('=', $line);
$field_name = array_shift($bits);
$field_contents = implode('=', $bits);
$result[$field_name] = $field_contents;
}
return array(count($result), array_shift($result), array_shift($result));
}
return FALSE;
}
// http://stackoverflow.com/questions/3964219/3964366#3964366
public function bench_GigaWatt($subject)
{
if(strpos($subject, 'SUCCESS') === 0)
{
$subject = explode("\r\n", urldecode($subject));
$result = array();
foreach($subject as $line)
{
if (strpos($line, "=") === FALSE)
continue;
list($var, $value) = explode("=", trim($line));
$result[$var] = empty($value) ? NULL : $value;
}
return array(count($result), array_shift($result), array_shift($result));
}
return FALSE;
}
// http://stackoverflow.com/questions/3964219/3964366#3964366
public function bench_GigaWatt2($subject)
{
if(strpos($subject, 'SUCCESS') === 0)
{
$subject = explode("\r\n", urldecode($subject));
$result = array();
foreach($subject as $line)
{
if (strpos($line, "=") === FALSE)
continue;
list($var, $value) = explode("=", trim($line));
$result[$var] = $value;
}
return array(count($result), array_shift($result), array_shift($result));
}
return FALSE;
}
// http://stackoverflow.com/questions/3964219/3964323#3964323
public function bench_dvhh($subject)
{
if(strpos($subject, 'SUCCESS') === 0)
{
$subject = explode("\r\n", urldecode($subject));
$result = array();
foreach($subject as $line)
{
$lineData = preg_split("/\s*=\s*/", $line);
if(count($lineData) == 2)
{
$result[$lineData[0]] = $lineData[1];
}
}
return array(count($result), array_shift($result), array_shift($result));
}
return FALSE;
}
public $subjects = array
(
"SUCCESS\r\[email protected]\r\ncharset=windows-1252\r\ncustom=\r\nfirst_name=Alice\r\nhandling_amount=0.00\r\ninvoice=AF000001\r\nitem_name=Stuffed bear\r\nitem_number=BEAR05\r\nlast_name=Foobar\r\nmc_currency=USD\r\nmc_fee=2.00\r\nmc_gross=20.00\r\[email protected]\r\npayer_id=UC9DXVX7GRSTN\r\npayer_status=unverified\r\npayment_date=09:08:06 Oct 18, 2010 PDT\r\npayment_fee=\r\npayment_gross=\r\npayment_status=Completed\r\npayment_type=instant\r\nprotection_eligibility=Ineligible\r\nquantity=1\r\nreceipt_id=2479-2605-1192-2880\r\[email protected]\r\nreceiver_id=8Y670ENTB8BY6\r\nresidence_country=USD\r\nshipping=0.00\r\ntax=0.00\r\ntransaction_subject=Bear\r\ntxn_id=1PH815997L239283J\r\ntxn_type=web_accept",
"FAIL\r\nError: 4003",
"INVALID",
);
}
如果任何人有任何改進的進一步的建議,請讓我知道分開:)
PHP將把「」和NULL作爲大多數操作是相同的,所以這不是什麼可擔心的。 – mellowsoon 2010-10-19 00:26:05
是的,只是不要使用完全匹配('==='),它應該是好的。 – tonyhb 2010-10-19 00:30:07