Parse XML data with PHP - php

I have a XML feed with the following URL with IDs of trips to be retrieved.
http://www.expeditiontrips.com/xml/triplist.xml
Based on the each trip information can be retrieved from following URL where the ID becomes the XML name
http://www.expeditiontrips.com/xml/trips/2945.xml
I need to show this feed on my website using PHP. I retrieved trip IDs using the following code but then I have no clue how to use that information to get the individual trip details and show them in my site.
<?php
$ch = curl_init('http://www.expeditiontrips.com/xml/triplist.xml');
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
$xml_raw = curl_exec($ch);
curl_close($ch);
$trips = simplexml_load_string($xml_raw);
foreach ($trips as $trip):
echo '<li><div class="title">'.$trip.'</div></li>';
endforeach;
?>

I still wasn't sure how you would like your layout, but this will get you started. I just showed you how to get a single value and how to get a values from an array.
<?php
$ch = curl_init('http://www.expeditiontrips.com/xml/triplist.xml');
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
$xml_raw = curl_exec($ch);
curl_close($ch);
$trips = simplexml_load_string($xml_raw);
//uncomment next 2 lines, to view the array $trips
// echo "<pre>";
// print_r($trips);
//pick one id, for example the first one.
$ch = curl_init('http://www.expeditiontrips.com/xml/trips/' . $trips->trip[0] . '.xml');
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
$xml_raw = curl_exec($ch);
curl_close($ch);
$info = simplexml_load_string($xml_raw);
//uncomment next 2 lines, to view the array $info
// echo "<pre>";
// print_r($info);
//single value
echo '' . $info->url . '<br />';
//multiple valeus in an array
foreach($info->images->image as $images){
echo '<img src="' . $images->url . '">';
}
?>

Finally Ended up with the following code. :) Hope it helps someone
<?php
$ch = curl_init('http://www.expeditiontrips.com/xml/triplist.xml');
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
$xml_raw = curl_exec($ch);
curl_close($ch);
$trips = simplexml_load_string($xml_raw);
$totalTrips = count($trips);
$perPage = 10;
$page = isset($_GET['trip']) && ($page = intval($_GET['trip'])) > 0 ? $page : 1;
$start = ($page - 1) * $perPage;
$end = $start + $perPage;
for ($a=$start; $a<$end; ++$a) {
if (isset($trips->trip[$a])) {
$ch = curl_init('http://www.expeditiontrips.com/xml/trips/' . $trips->trip[$a] . '.xml');
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
$xml_raw = curl_exec($ch);
curl_close($ch);
$info = simplexml_load_string($xml_raw);
$ran = array(1,2,3,4,5,6);
$randomElement = $ran[array_rand($ran, 1)];
echo '<div id="trip-item">';
echo '<div class="trip-title">'.$info->name.'</div>';
echo '<div class="trip-body">';
echo '<div class="col span_3">';
echo '<img src="'.$info->images->image[$randomElement]->url.'" />';
echo '</div>';
echo '<div class="col span_9 col_last">';
echo '<span class="mini-des">'.$info->description.'</span>';
echo '<table>';
echo '<tr>';
echo '<td>Prices: '.$info->prices->price->value.'</td>';
echo '<td>Days:</td>';
echo '</tr>';
echo '<tr>';
echo '<td>Ship: '.$info->additions->addition[0]->body.'</td>';
echo '<td>Click here for Departure Dates</td>';
echo '</tr></table></div></div></div>';
}
}
$pages = ceil($totalTrips / $perPage);
$low = $page - 3;
$high = $page + 3;
echo '<div class="paginator">';
if ($page > 3) {
echo '«';
}
for ($a=$low; $a<=$high; ++$a) {
if($a > $pages) {
break;
}
if($a > 0 && $a != $page) {
echo '' . $a . '';
} else if($a > 0) {
echo '<span>' . $a . '</span>';
}
}
if ($page != $pages) {
echo '»';
}
echo '</div>';
?>

Related

Curl for loop writes previous loops value if there is no data in the current loop

I am using PHP CURL to collect some data but if one of the fields in my query is empty it writes the value from the previous loop, how can I correct this so that it enters no data if the value is not set?
<?php
$domains = array( 'http://www.domain.com/' => '1',
'http://www.domain2.com/' => '2'
);
function file_get_contents_curl($url){
$ch = curl_init();
curl_setopt($ch, CURLOPT_HEADER, 0);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 1);
$data = curl_exec($ch);
curl_close($ch);
return $data;
}
foreach ($domains as $url => $urlKey) {
$html = file_get_contents_curl($url);
$doc = new DOMDocument();
#$doc->loadHTML($html);
$nodes = $doc->getElementsByTagName('title');
$title = $nodes->item(0)->nodeValue;
$metas = $doc->getElementsByTagName('meta');
for ($i = 0; $i < $metas->length; $i++)
{
$meta = $metas->item($i);
if($meta->getAttribute('name') == 'description') {
$description = $meta->getAttribute('content');
}
if($meta->getAttribute('name') == 'keywords') {
$keywords = $meta->getAttribute('content');
}
}
echo "Title: " . $title . "<br>";
echo "Description: " . $description . "<br>";
echo "Keywords: " . $keywords . "<br>";
You need to clear the data each time through the loop, as they're retaining their information from the last run through.
foreach ($domains as $url => $urlKey) {
$title = '';
$description = '';
$keywords = '';
...
}
Alternatively you could put the information into an array so you only need to clear one item, something like
foreach ($domains as $url => $urlKey) {
$site_data = array();
...
$site_data['title'] = $nodes->item(0)->nodeValue;
...
echo "Title: " . $site_data['title'] . "<br>";
echo "Description: " . $site_data['description'] . "<br>";
echo "Keywords: " . $site_data['keywords'] . "<br>";
}

Using PHP cURL to get Behance API feed stopped working

up until today the below code was working fine, however, now it has stopped working. Yet if I put the URL in it returns a feed. Any idea what is going on here? I tried to debug Curl with error handling.
<?php
if (!isset($_GET['page']))
{
$page = '&page=1';
}
else
{
$page = '&page=' . $_GET['page'];
}
$curl_handle = curl_init();
//return the transfer as a string
curl_setopt($curl_handle, CURLOPT_URL, 'http://www.behance.net/v2/users/andrewwelch/projects?api_key=XXX' . $page);
curl_setopt($curl_handle, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($curl_handle, CURLOPT_CONNECTTIMEOUT, 5);
curl_setopt($curl_handle, CURLOPT_USERAGENT, 'Your application name');
curl_setopt($curl_handle, CURLOPT_TIMEOUT, 5);
if(!curl_exec($curl_handle)){
die('Error: "' . curl_error($curl_handle) . '" - Code: ' . curl_errno($curl_handle));
}
$query = curl_exec($curl_handle);
curl_close($curl_handle);
$projects = (json_decode($query));
;
$i = 0;
$projcount = array();
if (isset($projects))
{
foreach (reset($projects) as $value)
{
if ($i % 4 == 0)
{
if ($i != 0)
{
print "</div>";
}
print '<div class="row">';
}
print '<div class="col-sm-3" style="height:200px;">';
$covers = (Array) $value->covers;
print '<a href="' . $value->url . '" target="_blank">';
$thiscover = array_slice($covers, '1');
print '<img src="' . reset($thiscover) . '"/>';
print '<span class="thumb_title">' . $value->name . '</span>';
print '</a>';
print '</div>';
$i++;
}
print "</div>";
$pagenumber = $_GET['page'];
$prevpagenumber = ($_GET['page'] == 1) ? ($_GET['page']) : ($_GET['page'] - 1);
if (!($i < 12))
{
print '<a class="next-butt" style="float:right; display:inline" href="http://www.andrewwelch.info/web.php?page=' . ($_GET['page'] + 1) . '">Next page >></a>';
}
if (($_GET['page']) > 1)
{
print '<a class="prev-butt" href="http://www.andrewwelch.info/web.php?page=' . $prevpagenumber . '"><< Previous page</a>';
}
}
else
{
print 'No projects available.';
}
?>
I had the same problem and was getting a connection timed out...but discovered I wasn't setting the User-Agent.
Apparently you have it in your code.
What happens if you put this http://www.behance.net/v2/users/andrewwelch/projects?api_key=XXX
on your browser?

PHP Call Function from Inside Itself Until Condition Met

I have a function that I am creating that basically connects to the Google Plus API and Pulls information. Unfortunately in order to get more than a few results at a time you need to use the nextPageToken provided in the API callback. Here is what I have so far:
function get_data($url) {
$ch = curl_init();
$timeout = 5;
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, $timeout);
$data = curl_exec($ch);
curl_close($ch);
return $data;
}
function parseResults($nextPageToken = "") {
$count = 0;
$content = get_data('https://www.googleapis.com/plus/v1/activities?query=%23throughglass&maxResults=10&orderBy=recent&fields=items(actor(displayName%2Curl)%2Cid%2Cobject(actor%2Cattachments)%2Curl%2Cverb)%2CnextPageToken&pageToken=' . $nextPageToken . '&key=YOUR API KEY HERE');
$posts = json_decode($content);
$token = $posts->nextPageToken;
foreach ($posts->items as $value){
$id = $value->id;
$id_query = mysql_query("SELECT id FROM images WHERE id = '$id'");
if ($value->verb != "post") continue;
if (mysql_num_rows($id_query) > 0) continue;
echo $value->actor->displayName . "<br />";
$count++;
}
if ($count < 20){
parseResults($token);
}else{
break;
}
}
parseResults();
If you can kind of see what I am trying to do here hopefully someone can help me out. I basically want to keep re-calling the parseResults() function with the provided nextPageToken until there have been 20 records processed.
I was able to solve it with help from Lawrence above:
function get_data($url) {
$ch = curl_init();
$timeout = 5;
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, $timeout);
$data = curl_exec($ch);
curl_close($ch);
return $data;
}
function parseResults($nextPageToken = "", $count) {
$content = get_data('https://www.googleapis.com/plus/v1/activities?query=%23throughglass&maxResults=10&orderBy=recent&fields=items(actor(displayName%2Curl)%2Cid%2Cobject(actor%2Cattachments)%2Curl%2Cverb)%2CnextPageToken&pageToken=' . $nextPageToken . '&key={YOUR_API_KEY}');
$posts = json_decode($content);
$token = $posts->nextPageToken;
foreach ($posts->items as $value){
$id = $value->id;
$name = $value->actor->displayName;
$profile = $value->actor->url;
$post = $value->url;
$post_text = $value->object->attachments[0]->displayName;
$image_small = $value->object->attachments[0]->image->url;
$image_full = $value->object->attachments[0]->fullImage->url;
$id_query = mysql_query("SELECT id FROM images WHERE id = '$id'");
if (mysql_num_rows($id_query) > 0) continue;
if ($value->verb != "post") continue;
if ($value->object->attachments[0]->image->url == "" || $value->object->attachments[0]->fullImage->url == "") continue;
if ($post_text != "#throughglass") continue;
mysql_query("INSERT INTO images (id,
author_name,
author_url,
post_url,
post_text,
image_small,
image_full) VALUES (
'$id',
'$name',
'$profile',
'$post',
'$post_text',
'$image_small',
'$image_full')");
echo "<b>ID: </b>" . $id . "<br />";
echo "<b>Name: </b>" . $value->actor->displayName . "<br />";
echo "<b>Profile URL: </b>" . $value->actor->url . "<br />";
echo "<b>Post URL: </b>" . $value->url . "<br />";
echo "<b>Post Text: </b>" . $value->object->attachments[0]->displayName . "<br />";
echo "<b>Image Small: </b>" . $value->object->attachments[0]->image->url . "<br />";
echo "<b>Image Full: </b>" . $value->object->attachments[0]->fullImage->url . "<br /><br />";
$count++;
}
if ($count < 100){
parseResults($token, $count);
}else{
echo "<br /><br /><br />" . $token;
break;
}
}
parseResults("", 0);
I think you want to count the number of recursive calls.
You can achive this by wrapping the function into a class an use a class property, but an easiest wayt would be to add a parameter to your function parseResult and increment it before the next call.

How to make script recursive

I was wondering if anyone could help me fine tune my script.
I have what I need but I'm just trying to figure out how to make it recursive.
e.g. I currently have:
$key = 'XXXXXXXXXXXX';
$sensor = 'false';
$query = 'Place 1';
$url = 'https://maps.googleapis.com/maps/api/place/textsearch/json?key='.$key.'&query='.urlencode($query).'&sensor='.$sensor;
$ch = curl_init($url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
$places = curl_exec($ch);
curl_close($ch);
// echo $url;
$output = json_decode($places);
$i = 0;
while ($output->results[$i]->geometry->location->lat != '') {
echo '<strong>' . $query . '</strong><br />';
echo $output->results[$i]->geometry->location->lat . ', '. $output->results[$i]->geometry->location->lng;
echo '<br />' . $output->results[$i]->formatted_address;
echo '<hr />';
$i++;
}
// there is a delay between when the next page token is given and when it is ready to be accessed
sleep(5);
if ($output->next_page_token != '') {
$url = 'https://maps.googleapis.com/maps/api/place/textsearch/json?pagetoken='.$output->next_page_token.'&key='.$key.'&sensor='.$sensor;
// repeating myself now!
$ch = curl_init($url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
$places = curl_exec($ch);
curl_close($ch);
$output = json_decode($places);
$i = 0;
while ($output->results[$i]->geometry->location->lat != '') {
echo '<strong>' . $query . '</strong><br />';
echo $output->results[$i]->geometry->location->lat . ', '. $output->results[$i]->geometry->location->lng;
echo '<br />' . $output->results[$i]->formatted_address;
echo '<hr />';
$i++;
}
}
So, ideally, I am looking at how to restructure so that the above will run for as long as there is a next page token.
At the very least you could replace the if with a while. And maybe re-factor the body of the while into a function.
But you don't need to call it recursively, just iteratively until you're done (i.e. no more next page token)
function doQuery($url)
{
$ch = curl_init($url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
$places = curl_exec($ch);
curl_close($ch);
$output = json_decode($places);
$i = 0;
while ($output->results[$i]->geometry->location->lat != '') {
echo '<strong>' . $query . '</strong><br />';
echo $output->results[$i]->geometry->location->lat . ', '. $output->results[$i]->geometry->location->lng;
echo '<br />' . $output->results[$i]->formatted_address;
echo '<hr />';
$i++;
}
sleep(5);
return $output->next_page_token;
}
$next_page_token = doQuery($url);
while ($next_page_token != '')
{
$url = 'https://maps.googleapis.com/maps/api/place/textsearch/json?pagetoken='.$next_page_token.'&key='.$key.'&sensor='.$sensor;
$next_page_token = doQuery($url);
}
Encapsulate your logic within a function, then loop while you have a next page token:
function doWorkAndPrint( $url, $query) {
$ch = curl_init($url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
$places = curl_exec($ch);
curl_close($ch);
$output = json_decode($places);
$i = 0;
while ($output->results[$i]->geometry->location->lat != '') {
echo '<strong>' . $query . '</strong><br />';
echo $output->results[$i]->geometry->location->lat . ', '. $output->results[$i]->geometry->location->lng;
echo '<br />' . $output->results[$i]->formatted_address;
echo '<hr />';
$i++;
}
return $output->next_page_token;
}
Now, you just need to loop while that function returns something useful. Since you want to do it at least once, I would use a do ... while loop:
$key = 'XXXXXXXXXXXX';
$sensor = 'false';
$query = 'Place 1';
do {
$url = 'https://maps.googleapis.com/maps/api/place/textsearch/json?pagetoken='.$query.'&key='.$key.'&sensor='.$sensor;
$query = doWorkAndPrint( $url, $query);
} while( $query != '');

JSON and PHP driven slideshow not working

I have inherited a project from a client that uses JSON and PHP to display real estate property listings from a online realty service. The data provided by the service loads, but the properties and agents associated with them get mixed up. Sometimes all of the properties are displayed, but have only one agent associated with them. Other times the data loads, but does not transition after a few properties have been displayed. The transitions are being controlled by the jQuery cycle plugin.
I have included all of the code below. Any assistance is greatly appreciated.
Thank you.
Mike
<?php
function decode_json_string($json){
$objects = array();
$start_pos = strpos($json, '[');
$end_pos = strpos($json, ']');
$dataString = substr($json, ++$start_pos, ($end_pos - $start_pos));
while(strpos($dataString, '{') !== FALSE){
$start_pos = strpos($dataString, '{');
$end_pos = strpos($dataString, '}');
$objectString = substr($dataString, ++$start_pos, ($end_pos - $start_pos));
$tempString = $objectString;
$formattedString = "";
while(strpos($tempString, ':') !== FALSE){
$valueStart = strpos($tempString, ':');
if($tempString[++$valueStart] != '"'){
$substring1 = substr($tempString, 0, $valueStart);
if(strpos($tempString, ',', $valueStart) !== FALSE){
$valueEnd = strpos($tempString, ',', $valueStart);
$substring2 = substr($tempString, $valueStart, ($valueEnd - $valueStart));
}
else{
$valueEnd = $valueStart + 1;
$substring2 = substr($tempString, $valueStart);
}
$formattedString .= $substring1 . '"' . $substring2 . '"';
$tempString = substr($tempString, $valueEnd);
}
else{
$valueEnd = strpos($tempString, '",') + 1;
$formattedString .= substr($tempString, 0, $valueEnd);
$tempString = substr($tempString, $valueEnd);
}
}
$tempArray = explode('",', $formattedString);
foreach($tempArray as $tempValue){
$tempValueArray = explode( ":", $tempValue);
$key = format_string($tempValueArray[0]);
$value = format_string($tempValueArray[1]);
$object[$key] = $value;
}
$objects[] = $object;
$dataString = substr($dataString, ++$end_pos);
}
return $objects;
}
function format_string($string){
$string = str_replace("'", "", $string);
$string = str_replace('"', "", $string);
return trim($string);
}
function get_agent_properties_json($agentID){
global $BASE_URL;
$date = time();
$dataType = '3'; // Data Type = Properties
$url = $BASE_URL . '/FeaturedDataHandler.c?r=' . $date . '&DataType=' . $dataType . '&CompanyID=' . $companyID . '&agentID=' . $agentID;
// create a new cURL resource
$ch = curl_init();
// set URL and other appropriate options
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_HEADER, 0);
// grab URL and pass it to the browser
$response = curl_exec($ch);
// close cURL resource, and free up system resources
curl_close($ch);
return $response;
}
function get_agent_properties($agentID){
$agent_properties_json = get_agent_properties_json($agentID);
$properties = decode_json_string($agent_properties_json);
return $properties;
}
function print_property_details(&$property, &$agent){
global $BASE_URL;
if($property['ListingStatusCode'] != 'SOLD'){
$address = $property['Address'];
$shortaddr = substr($address, 0, -12);
echo "<div class='propertySlide'>";
echo "<div class='title'>";
echo "<div class='box1'>";
echo "<span class='price'>". $property['Price'] ."</span>";
echo "<span class='address'>". $shortaddr ."</span>";
echo "</div>";
echo "<div class='box2'>";
echo "<span class='style'><strong>Style:</strong> ". $property['Style'] ."</span>";
echo "<span class='footage'><strong>Sq. Feet:</strong> ". $property['SqFootage'] ."</span>";
echo "<span class='beds'><strong>Beds:</strong> ". $property['Bedrooms'] ."</span>";
echo "<span class='baths'><strong>Baths:</strong> ". $property['Bathrooms'] ."</span>";
echo "<span class='year'><strong>Year Built:</strong> ". $property['YearBuilt'] ."</span>";
echo "</div>";
echo "</div>";
echo "<div class='imagebox'><img class='listingImage' src='". $BASE_URL . $property['Image'] ."' /></div>";
echo "<div class='agentbox'>";
echo "<img class='agentImage' src='" . $BASE_URL . "/Users/pic" . $agent['WTLUserID'] . ".jpg' />";
echo "<span class='agent'><strong>Agent:</strong> ". $agent['DisplayName'] ."</span>";
echo "</div>";
echo "</div>";
}
}
?>
$date = time();
$dataType = '4'; // Data Type = Agents
$companyID = '2119'; // Red Deer - Century 21 Advantage
$url = $BASE_URL . '/FeaturedDataHandler.c?r=' . $date . '&DataType=' . $dataType . '&CompanyID=' . $companyID;
// create a new cURL resource
$ch = curl_init();
// set URL and other appropriate options
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_HEADER, 0);
// grab URL and pass it to the browser
$response = curl_exec($ch);
// close cURL resource, and free up system resources
curl_close($ch);
$agents = decode_json_string($response);
foreach($agents as $agent){
$properties = get_agent_properties($agent['WTLUserID']);
foreach($properties as $property){
print_property_details($property, $agent);
}
}
<?php
$BASE_URL = 'http://www.century21.ca';
$date = time();
$dataType = '4'; // Data Type = Agents
$companyID = '2119'; // Red Deer - Century 21 Advantage
$url = $BASE_URL . '/FeaturedDataHandler.c?r=' . $date . '&DataType=' . $dataType . '&CompanyID=' . $companyID;
// create a new cURL resource
$ch = curl_init();
// set URL and other appropriate options
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_HEADER, 0);
// grab URL and pass it to the browser
$response = curl_exec($ch);
// close cURL resource, and free up system resources
curl_close($ch);
$agents = decode_json_string($response);
foreach($agents as $agent){
$properties = get_agent_properties($agent['WTLUserID']);
foreach($properties as $property){
print_property_details($property, $agent);
}
}
Before trying to debug the decode_json_string() function here you should try PHP's built-in json_decode() http://php.net/manual/en/function.json-decode.php
If you have an older version of PHP that lacks json_decode() you can find a compatible one in upgrade.php

Categories