Parsing Decoded JSON in PHP (blokchain API) - php

Hello I am trying to extract some info from a json format page
The page is : https://blockchain.info/fr/rawaddr/1BQLNJtMDKmMZ4PyqVFfRuBNvoGhjigBKF
this link allows to get all bitcoin transactions from an address.
All the quotation marks confuse me, I can not see clearly
I want to display everything like the original blockchain website
Blockchain Display view
The beginning will be something like that
$json = file_get_contents("https://blockchain.info/fr/rawaddr/1BQLNJtMDKmMZ4PyqVFfRuBNvoGhjigBKF");
var_dump(json_decode($json));
I can extract basic info from JSO to php, but here there is too much transactions and I think we need to use a loop to display everything but I don't know how to do that
If someone can display for me in php the 5 first transactions it will be very sympathic.
Thanks a lot in advance youw ill really help me if you can do that !

If you goal is to display all Tx info you want to do that.
$json = file_get_contents("http://blockchain.info/fr/rawaddr/1BQLNJtMDKmMZ4PyqVFfRuBNvoGhjigBKF");
$txs = json_decode($json,1)['txs'];
echo"<pre>"; //just to get a human readable display
foreach($txs as $txinfo){
echo"A new tx";
//will display the full tx data
print_r($txinfo);
}
echo"</pre>";
Note a blockchain transaction can be a little complexe since one transaction can have multiple input and multiple outputs.
you might want to cycle trough outputs as well to display all addresses who received bitcoin from a transaction
in that case you can simply add another foreach output
$json = file_get_contents("http://blockchain.info/fr/rawaddr/1BQLNJtMDKmMZ4PyqVFfRuBNvoGhjigBKF");
$txs = json_decode($json,1)['txs'];
echo"<pre>"; //just to get a human readable display
foreach($txs as $txinfo){
echo"A new tx";
//will display the full tx data
print_r($txinfo);
// will cycle trough all output for each tx
foreach ($txinfo['out'] as $outgoingTransaction)
{
//Will display the receiving address
$receivingAddress = $outgoingTransaction['addr'];
//will get the amount sent in satoshis
$receivingAmountInSatoshi = $outgoingTransaction['value'];
echo"<br>1BQLNJtMDKmMZ4PyqVFfRuBNvoGhjigBKF sent to $receivingAddress $receivingAmountInSatoshi satoshis <br>";
}
}
a more advanced code to add tx understanding logic
$walletAddress = '1AWKFrvFYuCC7ef2m2zX73pWu1C15FRGjR' ;
$json = file_get_contents("http://blockchain.info/fr/rawaddr/$walletAddress");
$txs = json_decode($json,1)['txs'];
echo"<pre>"; //just to get a human readable display
foreach($txs as $txinfo){
$spendingTx = false ;
$totalSpent = 0 ;
$totalReceived = 0;
echo"<p>Txid = $txinfo[hash]<br>";
//print_r($txinfo);
// we need to find out if the address is the sender or the receiver
$senderData = reset($txinfo['inputs']); //using reset to get only the first input
if ($senderData['prev_out']['addr'] ==$walletAddress ){
//the address is the sender meaning the address is spending
$spendingTx = true ;
}
//it's a spend tx then we cycle trough receivers
if ($spendingTx) {
foreach ($txinfo['out'] as $outgoingTransaction) {
//Will display the receiving address
$receivingAddress = $outgoingTransaction['addr'];
//will get the amount sent in satoshis
$receivingAmountInSatoshi = $outgoingTransaction['value'];
$totalSpent = $totalSpent + $receivingAmountInSatoshi ;
echo "<br>$walletAddress sent to $receivingAddress $receivingAmountInSatoshi satoshis <br>";
}
echo "<br>Total spent = $totalSpent" ;
}
//it is not a spending tx so it's a receceiving tx
else {
foreach ($txinfo['out'] as $outgoingTransaction) {
//We keep only receiving data concerning current wallet
if ($outgoingTransaction['addr'] == $walletAddress) {
//Will display the receiving address
$receivingAddress = $outgoingTransaction['addr'];
//will get the amount sent in satoshis
$receivingAmountInSatoshi = $outgoingTransaction['value'];
$senderAddress = $senderData['prev_out']['addr'];
$totalReceived = $receivingAmountInSatoshi;
echo "<br>$walletAddress received $receivingAmountInSatoshi satoshis from $senderAddress<br>";
}
}
echo "<br>Total received = $totalReceived" ;
}
echo"<br>end tx </p>";
}
echo"</pre>";

Related

How to count JSON response and output how many lines there are

Hello fellow developers,
I have been trying to manipulate the output and display the total amount of workers there are instead of outputting the workers name as a string.
Bellow you will find the data that i am receiving and further down i will explain how i would like to handle the JSON response.
{
"result":
{
"addr":"ADDRESS_HERE",
"workers":
[
["worker1080",{},2,1,"200000",0,22],
["worker1080",{"a":"899.4"},3,1,"512",0,24]
],
"algo":-1
},
"method":"stats.provider.workers"
}
So basically as you can see from the above response that there are 2 workers named "worker1080" active on that address.
The bellow php code is how i retrieve the data and output only the names of the workers:
<?php
$btcwallet = get_btc_addy();
if (isset($cur_addy)) {
$method4 = new methods();
$worker_stats = new urls();
$get_data = file_get_contents(utf8_encode($worker_stats->nice_url.$method4->m4.$cur_addy));
$get_json = json_decode($get_data, true);
foreach ($get_json['result']['workers'] as $v) {
$i = 0;
print $v[$i++]."<br />";
}
}
?>
$get_json is the variable that decodes the data from $get_data and displays the worker names and increments every time a worker is added or online.
now i currently have 2 workers online as shown in the JSON response.
it outputs:
worker1080
worker1080
which is perfect although if i try using a foreach statement and try to display the the total amount of workers online it should display 2 instead of the names, it has to also increment for each worker that the json repsonse outputs.
EG: i have 2 workers online now, but in an hour i will connect 10 more it would display the following:
worker1080
worker1080
worker1070
worker1070
worker1080ti
worker1080ti
workerASIC
workerASIC
workerASIC
workerCPU
workerCPU
workerCPU
Now i try to use the following to display the total:
count($v[$i++]);
and i have tried using a foreach within the foreach, and both count and the foreach both will either display "0" by all the workers or "1"
bellow is an example of the output.
0
0
0
0
0
How would i go about counting each line in the output and display the total number of workers ?
Thanks #symcbean for the solution.
<?php
$btcwallet = get_btc_addy();
if (isset($cur_addy)) {
$method4 = new methods();
$worker_stats = new urls();
$get_data = file_get_contents(utf8_encode($worker_stats->nice_url.$method4->m4.$cur_addy));
$get_json = json_decode($get_data, true);
print count($get_json['result']['workers'])."<br />"; // <-- solution *removed foreach and $i incrementation as its not needed for count
}
?>
it now displays the correct number of workers :)

Looping through Amazon MWS orders API by using NextToken PHP

I am making a curl request to Amazon MWS orders API to get ListOrders then I loop through the xml response using foreach loop and prints the response in html table.
But as per Amazon MWS Orders API it only returns 100 results in one request and to get more results I need to make another curl request by using other parameter NextToken that I got from the last response of previous request which then will return next 100 orders and so on until there is no more NextToken available.
So my question is how can I iterate to the new response of NextToken request again and again and print the response in html table until there is no more NextToken available?
Report response is also avilable in XML format
For those who is still struggling and want an easy way to get orders data. Please use Amazon MWS Reports API and request a report using -
ReportType:_GET_XML_ALL_ORDERS_DATA_BY_ORDER_DATE_
For more info see
https://docs.developer.amazonservices.com/en_UK/reports/Reports_ReportType.html
This is what I use to convert the report's csv response to an array for saving into database.
$report_listing = explode("\n", $report_data["report_data"]);
$orders_list = '';
$i = 0;
$headers = '';
// Building an Associative array of CSV report
foreach($report_listing as $listing)
{
if($i == 0)
{
$headers = explode("\t", trim($listing));
}
else
{
$csv_data = explode("\t", $listing);
if(!isset($csv_data[1]))
continue;
foreach($headers as $key => $index)
{
$orders_list[$i - 1][$index] = $csv_data[$key];
}
}
$i++;
}
$new_order = array();
// Combining order items into one order array
foreach($orders_list as $orders)
{
$new_order[$orders['amazon-order-id']][] = $orders;
}

Compare time difference

I want to compare the time between sent messages, so that i know how quick someone would respond.
message_sent is the unix timestamp when a message has been sent.
ID: 0000000005 is the start, ID: 0000000006 is a response on the message of ID: 0000000005.
With this data: 0000000006 sent a message on 1483021773. The original question was asked in 0000000005 on 1483021687. So the reaction time is 1483021773 - 1483021687. How should i approach this so i get an average response time?
The data
Assuming that a response time is defined by the time it takes for a user to respond to the last message of another user:
$response_times = array(); // array of response times
// let's define a variable to keep track of the person
// to which another person will respond. initially, variable will hold
// the first message
$initiator = array_shift($messages);
// now iterator through messages
foreach ($messages as $message) {
// if this message belongs to the initiator, just update the timestamp
if ($message['from_user_id'] == $initiator['from_user_id']) {
$initiator['message_sent'] = $message['message_sent'];
continue; // and go to the next message
}
// otherwise, calculate the time difference and put it in response times
array_push($response_times, $message['message_sent'] - $initiator['message_sent']);
// and update the initiator
$initiator = $message;
}
// finally, calculate average of response time
$avg_response_time = array_sum($response_times) / count($response_times);
Since i don't know the exact code here is some sudo code with an example:
$total_items = count($array_of_items);
$starting_time_total = "0";
// Some code here to do your message_sent - message_sent = $some_value;
// Do the following for every single item for the $total_items in array
$starting_time_total = $starting_time_total + $some_value;
//Now to get the average we do this
$average = $starting_time_total / $total_items;
So if you have 4 items in the array, with response times of 423, 395, 283, 583 respectively, you are left with an average response time of 421 which you can then convert to seconds of minutes or whatever.

How to invoke the demo url using VinceG php-first-data-api

I am trying to integrate First Data e4 Gateway using PHP. I downloaded the VinceG/php-first-data-api PHP First Data Service API class. The code comes with some examples.
I have my Terminal ID (API_LOGIN) and Password (32 character string).
What confuses me is that when I use one of the examples, I don't know how to tell the class that I want to use the demo url, not the production url.
The class comes with two constants:
const LIVE_API_URL = 'https://api.globalgatewaye4.firstdata.com/transaction/';
const TEST_API_URL = 'https://api.demo.globalgatewaye4.firstdata.com/transaction/';
In the First Data console, when I generated my password, it said to use the v12 api, /transaction/v12, so I changed the protected $apiVersion = 'v12';
All I want to do is write my first development transaction using First Data e4. I have yet to get any kind of response. Obviously I need a lot of hand holding to get started.
When I set up a website to use BalancedPayments, they have a support forum that's pretty good, and I was able to get that running fairly quickly. First Data has a lot of documentation, but for some reason not much of it has good PHP examples.
My hope is that some expert has already mastered the VinceG/php-first-data-api, and can help me write one script that works.
Here's the pre-auth code I'm using, that invokes the FirstData class:
// Pre Auth Transaction Type
define("API_LOGIN", "B123456-01");
define("API_KEY", "xxxxxxxxxxyyyyyyyyyyyyzzzzzzzzzz");
$data = array();
$data['type'] = "00";
$data['number'] = "4111111111111111";
$data['name'] = "Cyrus Vance";
$data['exp'] = "0618";
$data['amount'] = "100.00";
$data['zip'] = "33333";
$data['cvv'] = "123";
$data['address'] = "1111 OCEAN BLVD MIAMI FL";
$orderId = "0001";
require_once("FirstData.php");
$firstData = new FirstData(API_LOGIN, API_KEY, true);
// Charge
$firstData->setTransactionType(FirstData::TRAN_PREAUTH);
$firstData->setCreditCardType($data['type'])
->setCreditCardNumber($data['number'])
->setCreditCardName($data['name'])
->setCreditCardExpiration($data['exp'])
->setAmount($data['amount'])
->setReferenceNumber($orderId);
if($data['zip']) {
$firstData->setCreditCardZipCode($data['zip']);
}
if($data['cvv']) {
$firstData->setCreditCardVerification($data['cvv']);
}
if($data['address']) {
$firstData->setCreditCardAddress($data['address']);
}
$firstData->process();
// Check
if($firstData->isError()) {
echo "!!!";
// there was an error
} else {
echo "###";
// transaction passed
}
My number one problem was that I had not created (applied for, with instant approval) a
demo account on First Data. I didn't realize this was a separate thing on First Data. On Balanced Payments, for instance, you have one account, and you can run your script on a test url with test values.
From the Administration panel, click "Terminals", then your Gateway number on the ECOMM row (will look something like AH1234-03), then you have to click "Generate" on password save it to your personal notes), then click UPDATE.
Now replace your parameter values in your test scripts. I use a variable assignment block that looks something like this:
define("API_LOGIN", "AH1234-05"); //fake
define("API_KEY", "44p7797xxx790098z1z2n6f270ys1z0x"); //fake
$data = array();
$data['type'] = "03";
$data['number'] = "4111111111111111";
$data['name'] = "Cyrus Vancce";
$data['exp'] = "0618";
$data['amount'] = "100.00";
$data['zip'] = "33320";
$data['cvv'] = "123";
$data['address'] = "1234 N OCEAN BLVD MIAMI BEACH FL";
$orderId = "0001";
require_once("FirstData.php");
$firstData = new FirstData(API_LOGIN, API_KEY, true);
at the end of the VinceG test scripts, I output my gateway response with a print_r, like this:
$firstData->process();
// Check
if($firstData->isError()) {
echo "!!!";
// there was an error
} else {
echo "###";
// transaction passed
}
echo "<pre>";
print_r($firstData);

How to move large amounts of mail with PHP?

I'm trying to write a PHP program that uses the IMAP PHP extension to run through a very large inbox (greater than 70,000 emails), and move all emails that fall within a specified date range into a folder. I keep running into problems trying to get the mail that falls within the desired range.
First I tried using the SINCE and BEFORE criteria in imap_search() to place all of the desired ID numbers into an array, and then created a string listing these ID numbers to feed into imap_mail_move(). But the problem I keep running into is that imap_search() never actually returns all of the emails within the specified range. For instance, I ran the following code:
echo "Beginning search. \n";
$mail = imap_search($this->mbox,
'SINCE "$startDate" BEFORE "$endDate"');
echo "Search complete. \n";
if (!$mail){echo "The inbox is empty. \n"; die();}
$count = 0;
foreach($mail as $i)
{
$count = $count + 1;
}
echo "Found $count emails. \n";
while specifying a date range that I know to hold 600ish emails, and imap_search() only listed 259 of them. When I expanded the range to encompass the entire inbox of about 75,000 emails, imap_search() only returned 25,112 of them.
When this didn't work, I tried a different, slower way to get all emails within the desired date range. I used imap_search() to collect ALL emails in the inbox, then I iterated through each email, compared the date contained in the emails header to the dates definining my interval, and added the ID to a string if it was in range. I ran the following code:
// Get all mail in the INBOX
$mail = imap_search($this->mbox, "ALL");
if (!$mail){echo "The inbox is empty. \n"; die();}
// Create a string list of all message IDs
//that fall in the specified range
$processed = 0;
$IDsequence = '';
foreach($mail as $messageID)
{
$date = imap_headerinfo($this->mbox, $messageID)->date;
try {$dateObject = new DateTime($date);}
catch (Exception $e) {echo $e->getMessage(); echo "\n";}
$dateObject->setTimezone($TimeZone);
if ($dateObject <= $IntervalEndDate && $dateObject >=
$IntervalStartDate)
{
$IDsequence = $IDsequence . "," . strval($messageID);
}
$processed = $processed + 1;
if ($processed % 100 == 0)
{ echo "Processed $processed emails. \n"; }
}
// If we got at least one message, cut off the first comma.
if (strlen($IDsequence) > 1){
$IDsequence = substr($IDsequence, 1, strlen($IDsequence)-1);
}
else
{
echo "No e-mail to move. \n";
die();
}
echo "Beginning copy. \n";
imap_mail_copy($this->mbox, $IDsequence, $TargetFolder);
echo "Copy complete. \n";
//imap_expunge($this->mbox);
imap_close($this->mbox);
After iterating through just over 25,000 emails, it began to print the error message 'object does not exist' referencing the line of code where I collect the date from the email header. I notice here that the breakdown still occurs somewhere around 25,000 emails, so perhaps both methods break for the same reason. I suspect that I am doing something wrong with the message IDs (for instance, I am assuming that the message IDs for the 75,000 emails are '1' through '75,000').
What is going wrong? Is there a way to collect a large number of emails that fall within a date range and move them?
Perhaps there are only 25,112 messages in the mailbox, and the other ~50,000 are in another mailbox. I know GMail, for example, may report a rough total for the Inbox, but a good percentage of those messages are actually archived.
You might want to do a sanity check at this point. :)

Categories