So, I'm fairly new to working with APIs, and am just trying to play around with using the Etsy API to display a certain set of listings.
By default, the API returns a set of 25 results, and can do a max of 100 at a time. I'd like to show more than that, so I'm trying to add pagination to my call. Here's what I've got so far:
<?php
//setting API key
define("API_KEY", XXX);
//setting request url
$url = "https://openapi.etsy.com/v2/listings/active?keywords=unicorn,unicorns&includes=Images:1:0&api_key=" . API_KEY;
while (isset($url) && $url != '') {
$curl = curl_init($url);
curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);
$response_body=curl_exec($curl);
curl_close($curl);
$response = json_decode($response_body);
foreach ($response->results as $listing) {
echo "<li>" . $listing->title . " ~*~ " . $listing->price . " " . $listing->currency_code . " ~*~ " . 'View on Etsy!' . "</li>" . "<br>";
}
$url = $response->pagination->next_page;
}
?>
I thought this would loop through and return the next set of 25 results, but it didn't. Anyone have experience working with this? Is there somewhere I'm getting tripped up?
Thanks!
In your while block, you are assigning the value of the next_page property to $url.
But the actual value is an int, 2, not an url.
Instead append the next_page to the initial url, as a query string variable.
$url .= "&page=" . $response->pagination->next_page;
See below an example on how you can isolate each process to a function.
We move the curl operation into its own function where it returns an object from json_decode.
We move the whole processing of the listings into a separate function, where for now, it just prints out the listings.
This second function is recursive, meaning, that if the next page exists it will call the first function, get the response, then process it.
<?php
//setting API key
define("API_KEY", 'br4j52uzdtlcpp6qxb6we3ge');
function get_listings($page=1){
$url = "https://openapi.etsy.com/v2/listings/active?keywords=unicorn,unicorns&includes=Images:1:0&api_key=" . API_KEY;
$url .= "&page=$page";
$curl = curl_init($url);
curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);
$response_body=curl_exec($curl);
curl_close($curl);
$responseObject = json_decode($response_body);
return $responseObject;
}
function process_listings($responseObject){
foreach ($responseObject->results as $listing) {
echo "Title: " . $listing->title . PHP_EOL .
"Price " . $listing->price . PHP_EOL .
"Currency code " . $listing->currency_code . PHP_EOL .
'URL ' . $listing->url . PHP_EOL;
}
print PHP_EOL . "Pagination " . $responseObject->pagination->next_page . PHP_EOL;
$next_page = $responseObject->pagination->next_page;
if ($next_page) {
$nextPageResponse = get_listings($next_page);
process_listings($nextPageResponse);
}
}
$firstPage = get_listings(); // page 1 is default
process_listings($firstPage);
Related
First question! Woho!
I'm currently coding a Dashboard for a Discord bot in PHP.
Recently, when trying to select a server, it would only display 3 malfunctioning items. So I checked the complete array using print_r() and it turned out it rate-limited me.
Now, I got no idea why that happened, as I'm the only person on the server. So what am I doing wrong? Here is the code for listing the selection page:
$all = DiscordAPI("/users/#me/guilds");
foreach ($all as $guild) {
echo "<a href='/?server=" . $guild['id'] . "'><p>";
if ($guild['icon']) {
if (substr($guild['icon'], 0, 2) == "a_") {
echo "<img class='server-icon' src='https://cdn.discordapp.com/icons/" . $guild['id'] . "/" . $guild['icon'] . ".gif?size=64'>";
} else {
echo "<img class='server-icon' src='https://cdn.discordapp.com/icons/" . $guild['id'] . "/" . $guild['icon'] . ".webp?size=64'>";
}
} else {
$words = explode(" ", $guild['name']);
$acronym = "";
foreach ($words as $w) {
$acronym .= $w[0];
}
echo "<img class='server-icon' src='https://cdn.statically.io/avatar/s=64/" . $acronym . "'>";
}
echo $guild['name'];
echo "</p></a>";
}
And here is the code for the DiscordAPI() function:
function DiscordAPI($endpoint)
{
if (!$_SESSION['token']) {
die("No token provided");
}
$ch = curl_init("https://discord.com/api" . $endpoint);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_HEADER, 0);
curl_setopt($ch, CURLOPT_HTTPHEADER, array(
"Authorization: Bearer " . $_SESSION['token']
));
$data = curl_exec($ch);
curl_close($ch);
return json_decode($data, true);
}
There are 2 API calls before this code to verify that there is a valid token.
Quick sidenote: I got Autism, so I might understand stuff a bit differently. Don't be scared to ask if I worded something hard to understand. Thank you for trying to understand me.
I am trying to test segapay in test page but its throwing an error
X911911INVALID T_TERMINAL_NUMBER 00P 0000000000000
X911911INVALID T_TERMINAL_NUMBER 00P 0000000000000X911911INVALID T_TERMINAL_NUMBER 00P 0000000000000
Approval Indicator: X
Approval/Error Code: 911911
Approval/Error Message: INVALID T_TERMINAL_NUMBER
Front-End Indicator: 00
CVV Indicator: P
AVS Indicator:
Risk Indicator: 00
Reference: 0000000000
Order Number:
<?php
// Marchant ID
$mid = "713558155666";
$mkey = "J1M3S4C5N5E9";
$amount = "10.00";
$cardholder_name = "Brijesh";
$billing_address = "Test";
$billing_state = "AL";
$billing_city = "Test";
$cardnumber = "5555555555554444";
$exp_Date = "1109";
$billing_zip = "12345";
$email_addr = "brijesss#xxx.com";
$ordernum = "3333333";
//set the URL that will be posted to.
$eftsecure_url = "https://www.sagepayments.net/cgi-bin/eftbankcard.dll?transaction";
//make your query.
$data = "m_id=" . $mid; //your eftsecure merchant id.
$data .= "&m_key=" . $mkey; // your eftsecure merchant key;
$data .= "&T_amt=" . urlencode($amount); // The amount to be charged. Always encode
// any data given to you over the web. it is more
// secure and reliable.
$data .= "&C_name=" . urlencode($cardholder_name);
$data .= "&C_address=" . urlencode($billing_address);
$data .= "&C_state=" . urlencode($billing_state);
$data .= "&C_city=" . urlencode($billing_city);
$data .= "&C_cardnumber=" . urlencode($cardnumber);
$data .= "&C_exp=" . urlencode($exp_Date);
$data .= "&C_zip=" . urlencode($billing_zip);
$data .= "&C_email=" . urlencode($email_addr);
$data .= "&T_code=02"; // transaction type indicator
$data .= "&T_ordernum=" . urlencode($ordernum);
//HTTPS Bankcard Specifications 18
//now we will make the transaction. the first method is the preferred internal method
//using the built in CURL functions.
$ch = curl_init(); //initialize the CURL library.
curl_setopt($ch, CURLOPT_URL, $eftsecure_url); // set the URL to post to.
curl_setopt($ch, CURLOPT_POST, 1); // tell it to POST not GET (you can GET but POST is
//preferred)
curl_setopt($ch, CURLOPT_POSTFIELDS, $data); // set the data to be posted.
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); // this tells the library to return the
// data to you instead of writing it to
// a file
$res = curl_exec($ch); // make the post.
curl_close($ch); // shut down the curl library.
echo $res . "<br>\n"; // this is the response.
// or you can also use the curl executable directly.
$curl = "/usr/bin/curl"; // the location of the curl executable.
$fp=popen("$curl --data \"$data\" $eftsecure_url","r"); // this allows you to get the
// data directly from curl
while(!feof($fp)) $res .= fread($fp, 1024); // read all the output.
pclose($fp); // close the connection to curl.
//HTTPS Bankcard Specifications 19
echo "$res" . "<br>\n"; // this is the response.
// once you have the response then you need to parse its different components.
echo "<br><hr><br>\n";
echo "Approval Indicator: " . $res[1] . "<br>"; //A is approved E is
declined/error.
echo "Approval/Error Code: " . substr($res, 2, 6) . "<br>\n";
echo "Approval/Error Message: " . substr($res, 8, 32) . "<br>\n";
echo "Front-End Indicator: " . substr($res, 40, 2) . "<br>\n";
echo "CVV Indicator: " . $res[42] . "<br>\n";
echo "AVS Indicator: " . $res[43] . "<br>\n";
echo "Risk Indicator: " . substr($res, 44, 2) . "<br>\n";
echo "Reference: " . substr($res, 46, 10) . "<br>\n";
echo "Order Number: " . substr($res, strpos($res, chr(28)) + 1,strrpos($res, chr(28) - 1)) . "<br>\n";
?>
I want obtain some geolocation informations using a external service (website service), but this works fine only in my pc (localhost using WampServer http client); already when my php file is transfered for a remote host (pc), it fails for get these information. Already tried several services of hosts, but still without success.
PS: My reference of website was http://ip-api.com/.
Here is my code:
$ip = $_REQUEST['REMOTE_ADDR'];
$query = #unserialize(file_get_contents('http://ip-api.com/php/'.$ip));
if($query && $query['status'] == 'success') {
$regiao = $query['regionName'];
$cidade = $query['city'];
$isp = $query['isp'];
$sigla_regiao = $query['region'];
}
else {
echo '';
}
So, someone have some ideia why this api don't works in a remote host?
Thanks in advance.
According to the error you posted, the file_get_contents function is not able to create a connection to the remote host. It may be that the access to remote resources is disabled for certain functions.
You can try to access the remote URL with cURL:
$curl = curl_init();
curl_setopt($curl, CURLOPT_URL, "http://ip-api.com/php" . $ipAddr);
curl_setopt ($curl, CURLOPT_RETURNTRANSFER, 1);
$content = curl_exec ($curl);
curl_close ($curl);
if (curl_errno($curl))
throw new \Exception(sprintf("Connection error %s: %s", curl_errno($curl), curl_error($curl)));
print_r(unserialize($content));
If you're interested in another provider, you can use the services of https://geoip-db.com
A working JSON example:
<?php
$json = file_get_contents('https://geoip-db.com/json');
$data = json_decode($json);
print $data->country_code . '<br>';
print $data->country_name . '<br>';
print $data->state . '<br>';
print $data->city . '<br>';
print $data->postal . '<br>';
print $data->latitude . '<br>';
print $data->longitude . '<br>';
print $data->IPv4 . '<br>';
?>
Or a JSONP callback with php:
<?php
$jsonp = file_get_contents('https://geoip-db.com/jsonp');
$data = jsonp_decode($jsonp);
print $data->country_code . '<br>';
print $data->country_name . '<br>';
print $data->state . '<br>';
print $data->city . '<br>';
print $data->postal . '<br>';
print $data->latitude . '<br>';
print $data->longitude . '<br>';
print $data->IPv4 . '<br>';
// Strip callback function name and parenthesis
function jsonp_decode($jsonp) {
if($jsonp[0] !== '[' && $jsonp[0] !== '{') {
$jsonp = substr($jsonp, strpos($jsonp, '('));
}
return json_decode(trim($jsonp,'();'));
}
?>
I am integrating the API from our monitoring software (PRTG) into our website and attempting to use a function that generates a list of data in XML format. As it is generated as needed, the URL doesn't point to an existing file.
I tried using "simplexml_load_file" and "simplexml_load_string" and passing the URL with no luck. I've also tried use "file_put_contents" to first save the file, but it also fails since the URL doesn't actually point to a file.
How can this be made to work?
<?php
$prtg_url = "http://prtg.domain.net:8080/";
$prtg_user = "username";
$prtg_hash = "passwordhash";
function getSensorData($deviceid)
{
$sensor_xml_file = $GLOBALS['prtg_url'] . "api/table.xml?content=sensors&output=xml&columns=objid,type,device,sensor,status&id=" . $deviceid . "&username=" . $GLOBALS['prtg_user'] . "&passhash=" . $GLOBALS['prtg_hash'];
file_put_contents("sensor.xml", fopen($sensor_xml_file, 'r'));
$sensors = simplexml_load_file("sensor.xml");
foreach ($sensors->item as $sensor)
{
$sensor_ping = $sensor->ping;
$sensor_id = $sensor->objid;
$sensor_type = $sensor->type;
$sensor_typeraw = $sensor->type_raw;
echo $sensor_ping . "</br>";
echo $sensor_id . "</br>";
echo $sensor_type . "</br>";
echo $sensor_typeraw . "</br>";
}
}
getSensorData("3401");
?>
It may be something to do with the file handler. You could try using simplexml_load_file() with your URL. For example:
$url = $GLOBALS['prtg_url']
. "api/table.xml?content=sensors&output=xml&columns=objid,type,device,sensor,status&id="
. $deviceid . "&username=" . $GLOBALS['prtg_user']
. "&passhash=" . $GLOBALS['prtg_hash']);
$xml = simplexml_load_file($url);
try this:
$c = curl_init();
curl_setopt($c, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($c, CURLOPT_URL, $sensor_xml_file);
$xmlString = curl_exec($c);
curl_close($c);
$sensors = simplexml_load_string($xmlString);
$opts = array('http' =>
array(
'method' => 'GET',
'header' => "Content-Type: text/xml\r\n",
'timeout' => 60
)
);
$context = stream_context_create($opts);
$url = $GLOBALS['prtg_url']
. "api/table.xml?content=sensors&output=xml&columns=objid,type,device,sensor,status&id="
. $deviceid . "&username=" . $GLOBALS['prtg_user']
. "&passhash=" . $GLOBALS['prtg_hash']);
$result = file_get_contents($url, false, $context);
echo $results;
This forces a 60 second timeout on the operation, that way you can see if it actually fetches any results. If it does return incomplete results, switch to using XMLReader for your parser.
I'm building up a url to execute with curl. the url will call an api for the LMS that I'm using. Before being able to call anything else, you need to receive a token from the LMS to put in the url. I have gotten the token from the api, and I can echo it and it shows up just fine, when I echo the url after appending the token to it, it doesn't show up.
curl_setopt($c, 'CURLOPT_RETURNTRANSFER', true);
$res = curl_exec($c);
curl_close($c);
$start = strpos($res,"<token>");
$end = $start+37;
$token = substr($res,$start+7,$end-$start);
echo "{$token}<br />";
$url = "/www/api2.php?action=create_user";
$url .= "&login=" . urlencode($username);
$url .= "&password=" . urlencode($password);
$url .= "&name=" . urlencode($data['first_name']);
$url .= "&surname=" . urlencode($data['last_name']);
$url .= "&email=" . urlencode($email);
$url .= "&languages=english";
$url .= "&token=" . $token;
echo "{$url}<br />";
Output of the echo "{$url}<br />";
/www/api2.php?action=create_user&login=foobar3130&password=6116b3f29c&name=Foo&surname=Bar&email=foobar%40gmail.com&languages=english&token=
Output of echo "{$token}<br />";
pUCu2BUAE1heAyQ93fApfhvDE1bjKd
Edit
I added a check to see if $start was false, and it is false. I guess its not actually the token that gets echo'd because if I comment that line out, the string that I have for the token output still gets printed. I'm not sure what it would even be from.
Edit 2
I now have it returning xml but I am not sure how to parse it to get the token. It returns:
<xml><token>Fp1rYkds4fSuTAQxTvLvSiW5NE2FJz</token></xml>
Your edit seems to confirm that curl_exec() isn't returning the data to you - it is sending it directly to the browser. Use the option CURLOPT_RETURNTRANSFER to have it return the value to your variable.
try:
ob_start();
echo "/www/api2.php?action=create_user";
echo "&login=" . urlencode($username);
echo "&password=" . urlencode($password);
echo "&name=" . urlencode($data['first_name']);
echo "&surname=" . urlencode($data['last_name']);
echo "&email=" . urlencode($email);
echo "&languages=english";
echo "&token=" . $token;
$url=ob_get_contents();
ob_end_clean();
echo $url;
From what your script shows, you are trying to parse the Token out of an XML result, with a fixed width of 37 characters.
Judging from your latest comment, that's where the problem lies.
A much better approach would be to use actual XML DOM parsing to get the token from the file.