I have received a response from server as a string, which I converted as array, but still I am not able to make out, how I can access values from this array like
myarrray['txn_status'];
as also from the string clnt_rqst_meta
array(13) {
[0]=>
string(15) "txn_status=0399"
[1]=>
string(15) "txn_msg=failure"
[2]=>
string(55) "txn_err_msg=Transaction Cancelled : ERROR CODE TPPGE161"
[3]=>
string(17) "clnt_txn_ref=9178"
[4]=>
string(15) "tpsl_bank_cd=NA"
[5]=>
string(19) "tpsl_txn_id=T245107"
[6]=>
string(14) "txn_amt=121.00"
[7]=>
string(47) "clnt_rqst_meta={mob:9937253528}{custname:pawan}"
[8]=>
string(16) "tpsl_txn_time=NA"
[9]=>
string(15) "tpsl_rfnd_id=NA"
[10]=>
string(10) "bal_amt=NA"
[11]=>
string(47) "rqst_token=cd3f6f55-5990-4c3b-bb12-238eede827a0"
[12]=>
string(45) "hash=3cf25909ec73865d3200bc267119d3fcc21df463"
}
I know that the same can be achieved using regex/preg_match, but I am sure there must be some straight forward way to achieve it.
update: the actual string received from response is like this:
string(342) "txn_status=0399|txn_msg=failure|txn_err_msg=Transaction Cancelled : ERROR CODE TPPGE161|clnt_txn_ref=9178|tpsl_bank_cd=NA|tpsl_txn_id=T245107|txn_amt=121.00|clnt_rqst_meta={mob:9937253528}{custname:pawan}|tpsl_txn_time=NA|tpsl_rfnd_id=NA|bal_amt=NA|rqst_token=cd3f6f55-5990-4c3b-bb12-238eede827a0|hash=3cf25909ec73865d3200bc267119d3fcc21df463"
so I used $response =explode("|",$response_str);
You could let the PHP function parse_str()
do the heavy lifting for you but it expects to receive a standard query string, with the entries separated by &
. Your input string uses a different separator (|
) and parse_str()
does not provide a way to tell it what character to use as separator.
The problem has a very simple solution: use str_replace()
to replace |
to &
in the input string then pass the result to parse_str()
:
$input = 'txn_status=0399|txn_msg=failure|txn_err_msg=Transaction Cancelled : ERROR CODE TPPGE161|clnt_txn_ref=9178|tpsl_bank_cd=NA|tpsl_txn_id=T245107|txn_amt=121.00|clnt_rqst_meta={mob:9937253528}{custname:pawan}|tpsl_txn_time=NA|tpsl_rfnd_id=NA|bal_amt=NA|rqst_token=cd3f6f55-5990-4c3b-bb12-238eede827a0|hash=3cf25909ec73865d3200bc267119d3fcc21df463';
parse_str(str_replace('|', '&', $input), $output);
print_r($output);
It produces:
Array
(
[txn_status] => 0399
[txn_msg] => failure
[txn_err_msg] => Transaction Cancelled : ERROR CODE TPPGE161
[clnt_txn_ref] => 9178
[tpsl_bank_cd] => NA
[tpsl_txn_id] => T245107
[txn_amt] => 121.00
[clnt_rqst_meta] => {mob:9937253528}{custname:pawan}
[tpsl_txn_time] => NA
[tpsl_rfnd_id] => NA
[bal_amt] => NA
[rqst_token] => cd3f6f55-5990-4c3b-bb12-238eede827a0
[hash] => 3cf25909ec73865d3200bc267119d3fcc21df463
)
See it in action: https://3v4l.org/KBaof
The solution exposed above works fine only if the input string does not contain &
and %
. These characters are special in query strings, parse_str()
tries to interpret them using their special meaning and the code above breaks.
&
or %
is present in the input string$input = 'txn_status=0399|txn_msg=failure|txn_err_msg=Transaction Cancelled : ERROR CODE TPPGE161|clnt_txn_ref=9178|tpsl_bank_cd=NA|tpsl_txn_id=T245107|txn_amt=121.00|clnt_rqst_meta={mob:9937253528}{custname:pawan}|tpsl_txn_time=NA|tpsl_rfnd_id=NA|bal_amt=NA|rqst_token=cd3f6f55-5990-4c3b-bb12-238eede827a0|hash=3cf25909ec73865d3200bc267119d3fcc21df463';
$output = array_reduce(
explode('|', $input),
function($acc, $item) {
list($key, $value) = explode('=', $item, 2);
$acc[$key] = $value;
return $acc;
},
[]
);
print_r($output);
It still fails if |
is present in the values (e.g. ...|txn_err_msg=a|b|clnt_txn_ref=...
) but this issue doesn't have a solution because of the naive encoding of the input string.
If you can modify the server that produces the input data, change it to produce JSON output. JSON is a format that allows validation of the input string and PHP provides functions to encode and decode it. The code becomes cleaner on both sides.
Try this:
$newArray = [];
foreach ($myArray as $element) {
$exploded = explode('=', $element);
$newArray[$exploded[0]] = $exploded[1];
}
I'm guessing that this expression might return the desired matches:
([^=]+)=([^=]+)(?:\||$)
$re = '/([^=]+)=([^=]+)(?:\||$)/m';
$str = 'txn_status=0399|txn_msg=failure|txn_err_msg=Transaction Cancelled : ERROR CODE TPPGE161|clnt_txn_ref=9178|tpsl_bank_cd=NA|tpsl_txn_id=T245107|txn_amt=121.00|clnt_rqst_meta={mob:9937253528}{custname:pawan}|tpsl_txn_time=NA|tpsl_rfnd_id=NA|bal_amt=NA|rqst_token=cd3f6f55-5990-4c3b-bb12-238eede827a0|hash=3cf25909ec73865d3200bc267119d3fcc21df463';
preg_match_all($re, $str, $matches, PREG_SET_ORDER, 0);
var_dump($matches);
The expression is explained on the top right panel of this demo if you wish to explore/simplify/modify it.
This any help?
$string = "txn_status=0399|txn_msg=failure|txn_err_msg=Transaction Cancelled : ERROR CODE TPPGE161|clnt_txn_ref=9178|tpsl_bank_cd=NA|tpsl_txn_id=T245107|txn_amt=121.00|clnt_rqst_meta={mob:9937253528}{custname:pawan}|tpsl_txn_time=NA|tpsl_rfnd_id=NA|bal_amt=NA|rqst_token=cd3f6f55-5990-4c3b-bb12-238eede827a0|hash=3cf25909ec73865d3200bc267119d3fcc21df463";
txn_status = "";
foreach(explode('|', $string) as $val){
$temp = explode('=', $val);
//$temp[0] is left side of =
//$temp[1] is right side of =
if($temp[0] == "txn_status"){
txn_status = $temp[1];
}
}
you also can use sscanf. this is not regex but still using some pattern but is more clean than preg_match
$arr = ['key1=value1', 'key2=value2', 'key3=value3'];
foreach ($arr as $str) {
sscanf($str, "%[^=]=%[^=]", $key, $value);
echo "[$key => $value]";
}