Output folder content in XML file
Thursday, July 3rd, 2008 in PHP
Usually in a Flash gallery the images are shown using an XML file generated by the server (in our case using PHP). So, how do you create that XML file used to output the contents of your images folder?
Starting with PHP 5, we have some new tools added that ease out work. One in particular is of interest and that’s SimpleXML. In plain english, it offers the possibility to convert XML to an object and that may be used later in the code with simple array iterators. More than that, it can also output XML valid code to generate XML files.
For this example, besides SimpleXML, we’ll need one more thing: a way to read the folder containing the images. And for that we have readdir. So the process will go like this: first we need to read the entire directory with readdir() and after that we need to generate the XML output using SimpleXML. Remember, SimpleXML is available in PHP starting with version 5, so make sure you have it installed on your server.
To check your PHP server version, simply create a file called phpinfo.php and inside it put only this: <?php phpinfo(); ?> – after that, upload the file on your web hosting service. Open your favourite web browser and point it at this file ( www.mywebaddress.com/phpinfo.php ). The first this you’ll see will be the server version ( something like PHP Version 5.x.x ). Remember to delete the file after you’re done.
Ok, so by now, PHP 5 is available and we can start working. The process is pretty simple and straight forward. In this example of ours, the point is to output in XML every image within a directory and for every image to store the file path along with the width and height of the image.
If we look at the PHP documentation for SimpleXML, we can see that the constructor takes as argument an XML declaration and that’s what we have stored in $xml_string variable. After that , we can start populating the XML with our own image files.
1 2 3 4 5 6 | $xml_string = <<<xml <?xml version="1.0" encoding="UTF-8"?> <images> </images> XML; $xml_generator = new SimpleXMLElement($xml_string); |
Now that we started SimpleXML, it’s time to read the image folder. As I said before, we use readdir for that. This function will return every element within the folder provided, but it will not read any other folders included in that. Let’s see:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 | $path_to_image_dir = 'images'; // relative path to your image directory if ( $handle = opendir( $path_to_image_dir ) ) { while (false !== ($file = readdir($handle))) { if ( is_file($path_to_image_dir.'/'.$file) ) { list( $width, $height ) = getimagesize($path_to_image_dir.'/'.$file); $image = $xml_generator->addChild('image'); $image->addChild('path', $path_to_image_dir.'/'.$file); $image->addChild('height', $height); $image->addChild('width', $width); } } closedir($handle); } |
As you can see in the code above, the image width and height are gathered by getimagesize(). After that, a new child is create in our XML ( $image ) and to that child we’re adding the image file details (path, width and height). Always remember when reading a folder with readdir to close the opendir() handle using closedir().
Ok now. We have our XML object stored in $xml_generator. We’ll only need to output it so that the XML file can be read. We can do that in two ways. One is to use this file as XML, the other one is to actually create an XML file. If we’ll use this file as XML, there are a couple of things needed to be done. First of all, this file must say ‘I’m an XML file’. To do that, we set an XML header to it, so that it will be identified by whatever script is calling it as an XML file:
1 2 | header("Content-Type: text/xml"); echo $xml_generator->asXML(); |
As you can see, first we say that this file is XML and after that the XML output is added using echo. Now, from what I know, if you call in Flash a PHP file that has XML header and valid XML output, things might not work as expected. So we’ll actually need to set it an XML extension. To do that, we use .htaccess. I’m not going to get into .htacess explaining here, I’ll just tell you what to do.
First thing is to create a file called .htaccess. We’ll assume that the php file holding all the code above is called my_xml_file.php. Inside the newly created .htaccess file, put the following lines:
1 2 | RewriteEngine On RewriteRule ^my_xml_file.xml$ my_xml_file.php [L,nc] |
Save the file and upload it on your web server /httpdocs directory. Make sure that the file has no name, just the .htaccess extension.
This will make all calls made for my_xml_file.xml to actually go to the PHP file. Now we have the XML header, XML content and XML extension all in order. When calling the XML file from your application, you’ll address the my_xml_file.xml not my_xml_file.php. To test the installation, after uploading to your web server the PHP and .htaccess file, open a browser and point it to the XML file name added to .htaccess ( ie: http://mydomain.com/my_xml_file.xml ). You should see the XML output from the PHP file, which means everything is ok.
Now, if what you need is to actually create an XML file from the PHP file, you’ll need to replace these lines:
1 2 | header("Content-Type: text/xml"); echo $xml_generator->asXML(); |
with these ones:
1 2 3 | $file = fopen('path_to_xml/myfile.xml','w'); fwrite($file, $xml_generator->asXML()); fclose($file); |
For this to work, you’ll need to put the XML file into a writable folder ( chmod 777 ). Once the file is created, if you add new files to the images folder, don’t expect them to appear in the XML file because they won’t. You’ll need to run the php file again in order to generate the XML file one more time with the complete images list.
That will be all. Here’s the complete code and the download files.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 | <?php $path_to_image_dir = 'images'; // relative path to your image directory $xml_string = <<<xml <?xml version="1.0" encoding="UTF-8"?> <images> </images> XML; $xml_generator = new SimpleXMLElement($xml_string); if ( $handle = opendir( $path_to_image_dir ) ) { while (false !== ($file = readdir($handle))) { if ( is_file($path_to_image_dir.'/'.$file) ) { list( $width, $height ) = getimagesize($path_to_image_dir.'/'.$file); $image = $xml_generator->addChild('image'); $image->addChild('path', $path_to_image_dir.'/'.$file); $image->addChild('height', $height); $image->addChild('width', $width); } } closedir($handle); } header("Content-Type: text/xml"); echo $xml_generator->asXML(); ?> |






59 comments
Great work just what i was looking for many thanks, : )
Is there a way to make it alphabetical? This does not seem to return an alphabetical list.
Hi Matt,
The script above uses readdir. From the php manual: The filenames are returned in the order in which they are stored by the filesystem. More info on readdir here.
Hi I need to do almost the samething but I don’t know how to include the CDATA-section tag out to the xml file.
Can you help me to find out how to do it?
Thanks,
Samy
Hello
Great tutorial. This is very usefull knowledge. Thanks!
But I have question about sorting with xml_generator.
For example how to sort records in output xml file.
When I upload new file to my directory i would like to have it on the begining of my xml list.
And how to sort records in xml by name.
If You woudl like to send me some anwsers or links where i could find some informations I would be greatfull.
Regards.
Ziemowit
Hi Ziemowit,
When reading a directory, files are returned in the order they are stored by the filesystem. After reading the folder contents, the file is added to XML. One idea to sort your files by name is to first read the whole directory, store all filenames into an array, sort that array and after that populate the XML. About showing the last uploaded file first, you could use fileatime() for sorting in the array above.
Hi Constantin
Thanks for Your reply.
I get the idea. Now I’ll try to make it work. I found on the internet that meny people are looking for sorting xml knowledge. Some of them use xsl transformations but it brings more complications. I think the best way to do it, is that witch You suggested. To sort array before outputing xml. Maby You could find some time and write tutorial on that ;)
Regards
Great !
I like it and it works fine.
But, how can I add a CDATA-section?
Can you add the code portion for that please?
Thank you so much.
Hi samy,
Sorry for the delay. I’ve been very busy. Looks like there’s a bigger problem regarding cdata. Here’s a possible solution: http://blog.evandavey.com/2008/04/how-to-fix-simplexml-cdata-problem-in-php.html
When I have the time I’ll dig into it myself and see how this can be solved. As a note, I haven’t tested the above solution.
I found the solution and it was so simple, the only thing I am looking now is to get them sort out. But almost there.
I hope some is looking for this and have the sorting solutin, Thanks.
SetItem(“Videos/Compartir_de_Jesus/$file”, “Thumbs/$file_jpg”, “”,”",”",”$file”,”$file”,”Presione y vea: $file”);
}
}
// Write the XML File to a file.
$fp = fopen(‘Alejandro_B_01.xml’, ‘w’);
fwrite($fp, $myfeed->output());
fclose($fp);
class RSSFeed {
// VARIABLES
// channel vars
var $channel_url;
var $AlbumData;
// image
var $image_url;
// Items
var $Items = array();
var $nrItems;
// FUNCTIONS
// constructor
function RSSFeed() {
$this->nrItems=0;
$this->channel_url=”;
$this->channel_AlbumData=”;
}
// set channel vars
function SetChannel($url, $AlbumData) {
$this->channel_url=$url;
$this->channel_AlbumData=$AlbumData;
}
// set image
function SetImage($url) {
$this->image_url=$url;
}
// set Item
function SetItem($url, $Thumb, $File, $FileInfo, $Link, $Name, $Description, $ToolTips) {
$this->Items[$this->nrItems]['url']=$url;
$this->Items[$this->nrItems]['Thumb']=$Thumb;
$this->Items[$this->nrItems]['File']=$File;
$this->Items[$this->nrItems]['FileInfo']=$FileInfo;
$this->Items[$this->nrItems]['Link']=$Link;
$this->Items[$this->nrItems]['Name']=$Name;
$this->Items[$this->nrItems]['Description']=$Description;
$this->Items[$this->nrItems]['ToolTips']=$ToolTips;
$this->nrItems++;
}
// output feed
function Output() {
$output = ”.”\n”;
$output .= ”;
//for($k=0; $knrItems; $k++) {
//};
for($k=0; $knrItems; $k++) {
$output .= ”;
$output .= ‘Items[$k]['Thumb'].’”>’.”\n”;
$output .= ‘Items[$k]['url'].’”>’.”\n”;
$output .= ”.$this->Items[$k]['File'].”.”\n”;
$output .= ‘Items[$k]['Link']. ‘”>’.”\n”;
$output .= ‘Items[$k]['Name'] . ‘]]>’.”\n”;
$output .= ‘Items[$k]['Description'] . ‘]]>’.”\n”;
$output .= ‘Items[$k]['ToolTips'] . ‘]]>’.”\n”;
$output .= ”.”\n”;
};
$output .= ”.”\n”;
return $output;
}
};
?>
In order to make an itunes-store-compliant podcast, you need:
<?xml version="1.0" encoding="UTF-8"?>
<rss xmlns:itunes="http://www.itunes.com/dtds/podcast-1.0.dtd" version="2.0">
then the rest of the xml output.
But as $xml_result = $xml_generator->asXML(); won’t let you do that, here’s the workaround:
et voila! feedvalidator and itunes are happy.
If anyone knows a better way, please let me know. Thanks!
super! thanks!
great tutorial!
thanks so mutch for that and very well explained, in my case i just need on more thing
is to read sub-folders with images, can you explain me how?
best regards
Hi Nuno,
To read folders, see this script I developed a while ago ( make sure you read comments too ) or if you want to do it yourself, see PHP Directory Functions.
Hey, great post. Do you think this could be adapted for video as well? If so could you suggest where and how I should start?
Cheers
It all depends. If you host videos yourself, it could. Please give me more details.
This works fine in IE but is NOT in Firefox because it does not sort. Sort by date or file name would be better on the output so that it could be used in the iTunes store. Firefox displays the XML file as written and this returns the XML in the order in which they are stored by the filesystem.
Hey, i need something kind of that but instead of this :
images/sunset.jpg
800
600
i will need something like this:
Hello Nicolaj,
Please contant me using the contact form to exchange code and try to find a solution to your problem.
Hey, great work it works good…………………………
I need the output to save in separate(individual) XML file…………..is it possible……………plz help me out ……..thanks in advance
Yes, get all the content and put it into a file. See PHP manual for file management. A good start is here: PHP fopen()
Thanks dude………………
I got the output ………i used XMLWriter() to store the output in an xml file dynamically………………its working……….
Hello!
Your script is working fine! I am trying to modificate him to make xml file looking like this:
But I am newbie at php, can anybody help me?
HTML is disabled for comments. Try placing the XML file you try to get somewhere online for analysis.
between the path tags, i need to add .
How can the “” be added?
between the path tags, i need to add content src =”this is the source name which I get.jpg” .
How can the content src =, and the quotes be added?
It looks like you have to use a relative path…can this be used to read images in a directory with an absolute path? Only reason I ask is because the website I am working on is on a windows server and won’t allow installation of php. So I have another computer with linux installed and php5. Hoping to point the script to the folder of images on the site using the actual direct url like: http://www.example.com/images
Leave a comment