Cache PHP Output - php

I have a file called api.php which is loaded using parameters, for example:
api.php?name=NAME&format=xml
which would return a xml page with some data, or
api.php?name=NAME&format=JSON would return the same data in json format.
The xml page is generated using this:
function generate_valid_xml_from_array($array, $node_block='xboxapi', $node_name='game') {
$xml = '<?xml version="1.0" encoding="UTF-8" ?>' . "\n";
$xml .= '<' . $node_block . '>' . "\n";
$xml .= generate_xml_from_array($array, $node_name);
$xml .= '</' . $node_block . '>' . "\n";
return $xml;
}
$xml = generate_valid_xml_from_array($array);
header('Content-type: text/xml');
print $xml;
and the json is returned using this:
header('Content-type: application/json');
echo json_encode($data);
How would i set the returned data to be cached for 1 hour, and then updated hourly on request?
I have been scratching my head with this one for a while now

You can use a filesystem cache for your needs. Here is a link to an article describing the creation of a simple cache class:
http://devgrow.com/simple-cache-class/
Another possibility would be to use the Zend Cache classes from the Zend Framework, for more information look at the introduction chapter of the component in the Zend Framework manual:
http://framework.zend.com/manual/en/zend.cache.introduction.html
And if you Google for 'PHP cache class' you will get a lot of other possibilities you can check.

You could store it in a file or in your database together with information about the creation time. If someone queries it you check if the creation time is more than 60 minutes in the past. If not return your cached value, if it is too old rebuild your value, save it and return it afterwards.

Related

Laravel: Parsing XML with SimpleXML namespace issue [duplicate]

This question has two parts.
Part 1. Yesterday I had some code which would echo the entire content of the XML from an RSS feed. Then I deleted it from my php document, saved over it, and I am totally kicking myself.
I believe the syntax went something like this:
$xml = simplexml_load_file($url);
echo $xml;
I tried that again and it is not working, so apparently I forgot the correct syntax and could use your help, dear stackoverflow question answerers.
I keep trying to figure out what I was doing and I am unable to find an example on Google or the PHP site. I tried the print_r($url); command, and it gives me what appears to be an atomized version of the feed. I want the whole string, warts and all. I realize that I could just type the RSS link into the window and see it, but it was helpful to have it on my PHP page as I am coding and noding.
Part 2 The main reason I wanted to reconstruct this is because I am trying to parse nodes off a blog RSS in order to display it on a webpage hosted on a private domain. I posted a dummy blog and discovered an awkward formatting glitch when I failed to add a title to one of the dummy posts.
So what does one do in this situation? I tried a little:
if(entry->title == "")
{$entryTitle = "untitled";}
That did not work at all.
Here's my entire php script for the handling of the blog:
<?php
/*create variables*/
$subtitle ="";
$entryTitle="";
$html = "";
$pubDate ="";
/*Store RSS feed address in new variable*/
$url = "http://www.blogger.com/feeds/6552111825067891333/posts/default";
/*Retrieve BLOG XML and store it in PHP object*/
$xml = simplexml_load_file($url);
print_r($xml);
/*Parse blog subtitle into HTML and echo it on the page*/
$subtitle .= "<h2 class='blog'>" . $xml->subtitle . "</h2><br />";
echo $subtitle;
/*Go through all the entries and parse them into HTML*/
foreach($xml->entry as $entry){
/*retrieve publication date*/
$xmlDate = $entry->published;
/*Convert XML timestamp into PHP timestamp*/
$phpDate = new DateTime(substr($xmlDate,0,19));
/*Format PHP timestamp to something humans understand*/
$pubDate .= $phpDate->format('l\, F j\, Y h:i A');
if ($entry->title == "")
{
$entryTitle .= "Untitled";
}
echo $entry->title;
/*Pick through each entry and parse each XML tree node into an HTML ready blog post*/
$html .= "<h3 class='blog'>".$entry->title . "<span class='pubDate'> | " .$pubDate . "</span></h3><p class='blog'>" . $entry->content . "</p>";
/*Print the HTML to the web page*/
echo $html;
/*Set the variables back to empty strings so they do not repeat data upon reiteration*/
$html = "";
$pubDate = "";
}
?>
According to the php manual:
$xml = new SimpleXMLElement($string);
.
.
.
then if you want to echo the result:
echo $xml->asXML();
or save the xml to a file:
$xml->asXML('blog.xml');
References
http://php.net/manual/fr/simplexmlelement.asxml.php
http://spotlesswebdesign.com/blog.php?id=14
Part 1
This is still not exactly what I wanted, but rather a very tidy and organized way of echoing the xml data:
$url = "http://www.blogger.com/feeds/6552111825067891333/posts/default";
$xml = simplexml_load_file($url);
echo '<pre>';
print_r($xml);
Part 2
I had to get firephp running so I could see exactly what elements php was encountering when it reached an entry without a blog title. Ultimately it is an empty array. Therefore, the simple:
if(empty($entry->title))
works perfectly. For string comparison, I found that you can simply cast it as a string. For my purposes, that was unnecessary.
The simplexml_load_file returns an SimpleXMLElement, so:
print_r($xml);
will show its minor objects and arrays.
After your tweaks you can call $xml->asXML("filename.xml"); as #Tim Withers pointed out.
Part 1: echo $xml->asXML(); - http://www.php.net/manual/en/simplexmlelement.asxml.php
Part 2: php SimpleXML check if a child exists
$html .= "<h3 class='blog'>".($entry->title!=null?$entry->title:'No Title')
. "<span class='pubDate'> | " .$pubDate . "</span></h3><p class='blog'>"
. $entry->content . "</p>";
Note I would probably load the url like this:
$feedUrl = 'http://www.blogger.com/feeds/6552111825067891333/posts/default';
$rawFeed = file_get_contents($feedUrl);
$xml = new SimpleXmlElement($rawFeed);
Based on your comment in regards to part 1, I am not sure if the XML is being loaded completely. If you try loading it this way, it should display all the XML data.

What is the JSON Data?

I coded a script longago which is extremely popular however i am about to role out a update using the clever in-app-auto update feature i coded. Now the question is i have lost the JSON data i was displaying to the code which it then decodes and reads and gets the relevant content.
Here is a snippet:
function check_update(){
$v = isset($_GET['v']) ? $_GET['v']:11;
$reqUrl = "http://myserver.myhost.com/api/update/?" . "v=" . $v;
return json_decode(#file_get_contents($reqUrl));
}
function updatefunction(){
$updateResult = check_update();
print $updateResult->content . "\n\r";
}
echo updatefunction();
I have added the "echo updatefunction();" as a debug test for me to see if it is getting the correct data.
Now my question is what should the $reqUrl be showing for this script to echo some content ?
Thanks

Validating and possibly correcting an XML file that I have

I have an XML file (random resource ) that I need to use. I am using PHP DOM Document to process this document and DOMXPath to query the object. However, the XPath queries are not returning any kind of data (resultset->length = 0). The query is correct, and I am not worried about the syntax to it. I also experimented with DOMDOcument->getElementsByTagName("tag") and this returns a null result as well.
In the context above, how can I check if my DOMDocument was able to load when I did call the
DOMDocument->Load('file.xml')
[also tried
$xmlFile = file_get_contents('file.xml')
DOMDocument->loadXML($xmlFile)]
I am assuming if the XML file is fault then in all likelihood I cannot query the DOMDocument at all ?
Is there anyway for me to check if the
a) the document was loaded at all when I called DOMDocument->Load/loadXML methods
b) validate the XML file using external resources (w3 schools validator is the only one I know)
c) if the XML file is incorrect, anyway that I can rectify it ?
Thanks to all those who take the time out and read this.
Best,
Parijat Kalia
Try flipping this on before doing anything:
libxml_use_internal_errors(true);
Then after loading your XML, look for errors using:
$errors = libxml_get_errors();
You can iterate over $errors (it's an array of libXMLError objects).
For example:
libxml_use_internal_errors(true);
try
{
$doc = new DOMDocument();
$doc->load("somebadxmlfile.xml");
}
catch (Exception $e)
{
$errors = libxml_get_errors();
foreach ($errors as $error)
{
echo $error->message . " [ Line: " . $error->line . " | Column: " . $error->column . " | Level: " . $error->level . " | File: " . $error->file . " ]";
}
}

Creating/Writing an XML file in PHP?

I currently have a script written in PHP where I connect to a database in phpMyAdmin, and then parse all of the table values into an XML document.
Here is how the script works:
$xmlBody .= "<XML>";
$sql_news = mysql_query("SELECT * FROM news_table");
$xmlBody .= "<News_Table>";
//this while loop churns out the values of our "news_table" table
while($row_news = mysql_fetch_array($sql_news)){
// Set DB variables into local variables for easier use
$id_news = $row_news["news_id"];
$author_news = $row_news["news_author"];
$time_news = $row_news["news_time"];
$title_news = $row_news["news_title"];
$content_news = $row_news["news_content"];
$desc_news = $row_news["news_description"];
$image_news = $row_news["news_image"];
$xmlBody .= '
<News_Table_Entry>
<DataID>' . $id_news . '</DataID>
<DataAuthor>' . $author_news . '</DataAuthor>
<DataTime>' . $time_news . '</DataTime>
<DataTitle>' . $title_news . '</DataTitle>
<DataContent>' . $content_news . '</DataContent>
<DataDesc>' . $desc_news . '</DataDesc>
<DataImage>' . $image_news . '</DataImage>
</News_Table_Entry>';
} // End while loop
$xmlBody .= "</News_Table>";
mysql_close(); // close the mysql database connection
$xmlBody .= "</XML>";
echo $xmlBody;
?>
How do I create and output this as an external XML file? I've successfully got this script working, but using all of the methods for writing out to XML isn't working. Using the
echo 'Wrote: ' . $doc->save("/tmp/test.xml") . ' bytes'; // Wrote: 72 bytes
Function isn't working, along with the fwrite function as well. I've been working at trying to figure this out for a few days, but none of the solutions I've been told to try out have worked. Any help or insight would be greatly appreciated!
According to your code, you're already building the XML content yourself. XML files are just regular text files, so in this case you don't need any of the special XML functions that validate and render. Instead, you can simply save your text to the .xml file:
file_put_contents('/tmp/test.xml', $xmlBody);
file_put_contents allows you to forego all the fopen/fwrite functions, so it's the easiest way to write content to disk.
On the other hand, if you do want to learn to build a structured XML document with all the bells and whistles of consistency, look up SimpleXML or XMLWriter. A little more overhead that way, but doing all the markup by hand can be unwieldy, especially when one typo can invalidate your whole document.
This will help you
$xml_msg_in = fopen('/tmp/test.xml',"w");
fwrite($xml_msg_in,$xmlBody);
fclose($xml_msg_in);
Have you tried file_put_contents('/path/to/output.xml', $xmlBody);
Just to understand, does your echo $xmlBody; line at least work as expected?
And if you are trying to use the XML file somewhere without success, then note you're missing the XML header as the first line of the XML file.
<?xml version="1.0"?>
Note that depending on the data in your database, this header may need to specify a wider encoding such as UTF-16. But you should choose what character sets you want to allow in that database.
<?xml version="1.0" encoding="UTF-16"?>
And what is the trailing ?> at the end of your code sample?

Parsing XML with PHP (simplexml)

Firstly, may I point out that I am a newcomer to all things PHP so apologies if anything here is unclear and I'm afraid the more layman the response the better. I've been having real trouble parsing an xml file in to php to then populate an HTML table for my website. At the moment, I have been able to get the full xml feed in to a string which I can then echo and view and all seems well. I then thought I would be able to use simplexml to pick out specific elements and print their content but have been unable to do this.
The xml feed will be constantly changing (structure remaining the same) and is in compressed format. From various sources I've identified the following commands to get my feed in to the right format within a string although I am still unable to print specific elements. I've tried every combination without any luck and suspect I may be barking up the wrong tree. Could someone please point me in the right direction?!
$file = fopen("compress.zlib://$url", 'r');
$xmlstr = file_get_contents($url);
$xml = new SimpleXMLElement($url,null,true);
foreach($xml as $name) {
echo "{$name->awCat}\r\n";
}
Many, many thanks in advance,
Chris
PS The actual feed
Since no one followed my closevote, I think I can just as well put my own comments as an answer:
First of all, SimpleXml can load URIs directly and it can do so with stream wrappers, so your three calls in the beginning can be shortened to (note that you are not using $file at all)
$merchantProductFeed = new SimpleXMLElement("compress.zlib://$url", null, TRUE);
To get the values you can either use the implicit SimpleXml API and drill down to the wanted elements (like shown multiple times elsewhere on the site):
foreach ($merchantProductFeed->merchant->prod as $prod) {
echo $prod->cat->awCat , PHP_EOL;
}
or you can use an XPath query to get at the wanted elements directly
$xml = new SimpleXMLElement("compress.zlib://$url", null, TRUE);
foreach ($xml->xpath('/merchantProductFeed/merchant/prod/cat/awCat') as $awCat) {
echo $awCat, PHP_EOL;
}
Live Demo
Note that fetching all $awCat elements from the source XML is rather pointless though, because all of them have "Bodycare & Fitness" for value. Of course you can also mix XPath and the implict API and just fetch the prod elements and then drill down to the various children of them.
Using XPath should be somewhat faster than iterating over the SimpleXmlElement object graph. Though it should be noted that the difference is in an neglectable area (read 0.000x vs 0.000y) for your feed. Still, if you plan to do more XML work, it pays off to familiarize yourself with XPath, because it's quite powerful. Think of it as SQL for XML.
For additional examples see
A simple program to CRUD node and node values of xml file and
PHP Manual - SimpleXml Basic Examples
Try this...
$url = "http://datafeed.api.productserve.com/datafeed/download/apikey/58bc4442611e03a13eca07d83607f851/cid/97,98,142,144,146,129,595,539,147,149,613,626,135,163,168,159,169,161,167,170,137,171,548,174,183,178,179,175,172,623,139,614,189,194,141,205,198,206,203,208,199,204,201,61,62,72,73,71,74,75,76,77,78,79,63,80,82,64,83,84,85,65,86,87,88,90,89,91,67,92,94,33,54,53,57,58,52,603,60,56,66,128,130,133,212,207,209,210,211,68,69,213,216,217,218,219,220,221,223,70,224,225,226,227,228,229,4,5,10,11,537,13,19,15,14,18,6,551,20,21,22,23,24,25,26,7,30,29,32,619,34,8,35,618,40,38,42,43,9,45,46,651,47,49,50,634,230,231,538,235,550,240,239,241,556,245,244,242,521,576,575,577,579,281,283,554,285,555,303,304,286,282,287,288,173,193,637,639,640,642,643,644,641,650,177,379,648,181,645,384,387,646,598,611,391,393,647,395,631,602,570,600,405,187,411,412,413,414,415,416,649,418,419,420,99,100,101,107,110,111,113,114,115,116,118,121,122,127,581,624,123,594,125,421,604,599,422,530,434,532,428,474,475,476,477,423,608,437,438,440,441,442,444,446,447,607,424,451,448,453,449,452,450,425,455,457,459,460,456,458,426,616,463,464,465,466,467,427,625,597,473,469,617,470,429,430,615,483,484,485,487,488,529,596,431,432,489,490,361,633,362,366,367,368,371,369,363,372,373,374,377,375,536,535,364,378,380,381,365,383,385,386,390,392,394,396,397,399,402,404,406,407,540,542,544,546,547,246,558,247,252,559,255,248,256,265,259,632,260,261,262,557,249,266,267,268,269,612,251,277,250,272,270,271,273,561,560,347,348,354,350,352,349,355,356,357,358,359,360,586,590,592,588,591,589,328,629,330,338,493,635,495,507,563,564,567,569,568/mid/2891/columns/merchant_id,merchant_name,aw_product_id,merchant_product_id,product_name,description,category_id,category_name,merchant_category,aw_deep_link,aw_image_url,search_price,delivery_cost,merchant_deep_link,merchant_image_url/format/xml/compression/gzip/";
$zd = gzopen($url, "r");
$data = gzread($zd, 1000000);
gzclose($zd);
if ($data !== false) {
$xml = simplexml_load_string($data);
foreach ($xml->merchant->prod as $pr) {
echo $pr->cat->awCat . "<br>";
}
}
<?php
$xmlstr = file_get_contents("compress.zlib://$url");
$xml = simplexml_load_string($xmlstr);
// you can transverse the xml tree however you want
foreach ($xml->merchant->prod as $line) {
// $line->cat->awCat -> you can use this
}
more information here
Use print_r($xml) to see the structure of the parsed XML feed.
Then it becomes obvious how you would traverse it:
foreach ($xml->merchant->prod as $prod) {
print $prod->pId;
print $prod->text->name;
print $prod->cat->awCat; # <-- which is what you wanted
print $prod->price->buynow;
}
$url = 'you url here';
$f = gzopen ($url, 'r');
$xml = new SimpleXMLElement (fread ($f, 1000000));
foreach($xml->xpath ('//prod') as $name)
{
echo (string) $name->cat->awCatId, "\r\n";
}

Categories