Is it not possible to use PHP and grab an XML file? - php

Why can't I use PHP in an .xml file at the same time grab it with SimpleXMLElement? When one works, the other doesn't.
Example: If I use PHP in the .xml file like
file.xml.php
<?php
require('db.php');
header('Content-Type: application/xml; charset=utf-8');
$updated_date = date('l', filemtime('file.xml.php'));
?>
<?xml version="1.0" encoding="UTF-8" ?>
<content>
<value name="Content 1" val="Value 1"></value>
<value name="Content 2" val="Value 2"></value>
<value name="Content 3" val="Value 3"></value>
<value name="Last Updated" val="<?php echo $updated_date; ?>"></value>
</content>
It works fine. But if I use SimpleXMLElement to get the file:
$xmlstring = file_get_contents('file.xml');
$xmlObject = new SimpleXMLElement($xmlstring);
foreach($xmlObject->children() as $node) {
$arr = $node->attributes();
echo $arr['name'] . ':' . $arr['val'];
}
it gives me this error:
PHP Fatal error: Uncaught exception 'Exception' with message 'String could not be parsed as XML' in /var/www/html/get_xml.php:336\nStack trace:\n#0 /var/www/html/get_xml.php(336): SimpleXMLElement->__construct('<?php??require(...')\n#1 {main}\n
I know it's telling me that the xml file cannot be read. However, when I read the xml file through its own URL, it works fine as if it was just another xml file.
Is it not possible to use PHP in .xml files and grab them at the same time? Without PHP, the file is kind of useless to me. Unless if I can just use the plain name so that it doesn't show that error. I know it has to do something with the require.

When you're getting the file, you need to ensure it's actually being parsed by PHP first. If you're just getting the PHP/XML source file from disk, it will still contain the PHP code: The code won't have been executed, meaning you'll simply have an invalid XML file.
As you've already found out, grabbing the file in a browser, it's fine: You can simulate this via PHP by using file_get_contents($urlToTheXmlPhpFile). Note, this has to be a URL to the file via a webserver: If you're just using a path to a file on your local disk, this won't work and you'll have the same problem - PHP won't have executed the file, so it will be a malformed combination of XML and PHP still.
To clarify:
file_get_contents('myfile.xml.php'); // Malformed - Attempting to parse source code.
file_get_contents('http://mydomain/myfile.xml.php'); // This should work.
If you're simply trying to require the PHP XML file via your local filesystem, rather than via a webserver, you could use eval to execute the PHP code. Do so with caution though, as this has the potential to enable arbitrary code execution for anyone who is able to change the XML file.
$validXmlString = eval(file_get_contents('myfile.xml.php')); // Be careful with this.

Related

Saving XML File from URL on my Server

I am able to put the following url in any browser and the xml appears after a few seconds...
ftp://USER:PASSWORD#aphrodite.WEBSITE.net/exports/xml/products.xml
I tried the following code in a php file so I can run a cron daily at midnight and for it to save the xml file on my server. There is a xml file being saved in my data directory but it is blank. Any ideas?
<?php
$content = file_get_contents('ftp://USER:PASSWORD#aphrodite.WEBSITE.net/exports/xml/products.xml');
file_put_contents('./data/products.xml', $xml);
?>
Try this:
<?php
$xml = file_get_contents('ftp://USER:PASSWORD#aphrodite.WEBSITE.net/exports/xml/products.xml');
file_put_contents('./data/products.xml', $xml);
?>
Your $content is not used in the file_put_contents method call so you are not writing anything to the file. I changed the code so that the data gets written to the file.
Nothing wrong with your code since file_get_contents almost supports all the protocols, But you may need to change $xml to $content because as I see $xml variable does not exists in your code.

php's simplexml_load_file is not working

So I've been working on this SIMPLE AS HELL php code and cannot figure out why it will not work. All I'm trying to do is parse some data inside an html file and display it all nice and neat. Here is my xml file
<?xml version="1.0" encoding="UTF-8"?>
<posts>
<post>
<title>Overview</title>
<item>Why are great</item>
<item>Who WonderWidgets</item>
</post>
</posts>
and here is my php inside the html file...
<?php
$posts = simplexml_load_file('/Users/Sam/Desktop/untitled\ html/posts.xml')
echo $posts->post->title;
?>
I have tried everything I can think of...
The echo echoes only
->post->title; ?>
Why is it echoing '?>' ?
Is anyone else having this problem or am I just too stupid to figure out what is wrong here...
Other Information:
It seems as though the variable $posts is empty when I tried this in the command line php.
I cannot occupy it and I have tried to do so with multiple xml files...HELP!
Edit:
I just tried this in my php shell and I get this error:
php > $posts = simplexml_load_file('posts.xml')
php > echo $posts
php > echo $posts->post->title;
Parse error: syntax error, unexpected T_ECHO in php shell code on line 2
My working directory is / and I have the posts.xml stored there.
I tried putting your XML in test.xml and tried your example. It worked fine. I got the output as overview.
Check your path to the file. Check the slashes in the path.
$posts = simplexml_load_file('test.xml');
echo $posts->post->title;

Incorrect elements appended in xml file

I have an xml file running in my server. While everything is working fine in my localserver, but when I upload it on my server, and when many people are using it, I get an error in my xml file.
I am using simplexml in php to read and update data.
For example,
I have the following structure of my xml file
<?xml version="1.0"?>
<db>
<uid></uid>
<score></score>
</db>
While it works perfectly for some time, but after some time, some elements get appended in my xml file. For example,
<db>
<uid></uid>
<score></score>
</db>/score</db>
or
<db>
<uid></uid>
<score><//score>
</db>
or
<db>
<uid></uid>
<core></score>
</db>
and then I get parsing error. Is it because many people are writing to my xml file at the same time? I am using LOCK_EX so that shouldn't be a problem
This is how I am opening it-
$data= new SimpleXMLElement($file, null, true);
And this is how I am closing it-
file_put_contents($file, $data->asXML(), LOCK_EX);
And it works perfectly all right in my localserver. And it works fine for some time when I upload it online but then suddenly weird things happen to my xml file. What's wrong?
Edit:
My update code-
<?php
include('functions.php');
$winid= $_GET['wid'];
$loseid=$_GET['lid'];
$winid=intval($winid);
$loseid=intval($loseid);
$file="data.xml";
$data= new SimpleXMLElement($file, null, true);
$winner=intval($data->score[$winid]);
$loser=intval($data->score[$loseid]);
$exp_winner=expected($loser,$winner);
$new_win=win($winner,$exp_winner);
$exp_loser=expected($winner,$loser);
$new_lose=loss($loser,$exp_loser);
$data->score[$winid]=$new_win;
$data->score[$loseid]==$new_lose;
file_put_contents($file, $data->asXML(), LOCK_EX);
header("Location: index.php");
?>
Try changing all occurrences of $data->score['string'] to $data->score->string. See if it helps!
Example: change $winner=intval($data->score[$winid]); to $winner=intval($data->score->$winid);
Also, you have accidentally wrote two equal signs on this line $data->score[$loseid]==$new_lose;!

Parse a PHP file as an XML file?

I have been working on a project that displays data in an XML file. (It's kind of like an API). I know how to parse XML with PHP, and how to make an XML file in PHP, but they don't work together. :)
Basically, I have two files: parse.php and xml.php.
xml.php grabs info from a MySQL database, and outputs it as XML.
parse.php loads and parses xml.php and outputs it as HTML.
If I run parse.php, it does not load xml.php. However, if I copy the outputted XML (from xml.php) and save it as a xml.xml file (and change the filename in parse.php to 'xml.xml') it works. I'd really appreciate any help.
Content of parse.php:
<?php
$doc = "xml.php";
$doc = #simplexml_load_file($doc) or die("Server Error: Recipe not found!");
$title = $doc->title;
echo $title
?>
Content of xml.php:
<?php
header("Content-type: text/xml");
$dbc = mysql... //gets data from database
echo "<!DOCTYPE..."; //xml stuff here
echo "<title>" . $dataFromMySQL . "</title>";
?>
The database connection works, and the DOCTYPE in the XML is ok, so that's not the problem.
Again, I only get the problem when I generate XML dynamically using PHP. If it's a .XML file, it works fine.
Can anyone help me?
Thanks.
simplexml_load_file will try to actually load the php contents of the xml.php file. It will not run that file first. You need to do some rewriting or use this ugly solution:
ob_start();
include 'xml.php';
$xml = ob_get_clean();
$doc = simplexml_load_string($xml);
//...
NOTE: I like #lonesomeday's proposed solution better, it will just require more rewriting.
#simplexml_load_file($doc);
That is where your problem is. This does not execute xml.php, but attempts to parse that file -- the PHP code that you've written -- as XML. Obviously (since it isn't XML) this won't work.
You have to find a way of getting the output from executing xml.php into parse.php.
The easy way to do this would be to change all your echo calls into $xml .= calls, and simply include xml.php into parse.php.
// xml.php
$xml = '';
$xml .= "<!DOCTYPE..."; //xml stuff here
$output .= "<title>" . $dataFromMySQL . "</title>";
// parse.php
include('xml.php');
simplexml_load_string($xml);
Note that your problem here shows the foolishness of using the error suppression operator #. If you hadn't used it, PHP would have shown you various errors which would have helped you to realise what the problem was.
Addendum: it occurs to me that the best way actually is to forget about the pointless XML step along the way and just convert the database output into HTML.
If you want to do this without rewriting xml.php, you can get PHP to process the file by accessing via url:
$doc = file_get_contents("http://localhost/xml.php");
You're literally loading the local file. Unless you evaluate it, the code doesn't run, so you'll just get the code itself.
You could use CURL to download xml.php over HTTP, or you could make the XML-generation component of the xml.php a callable function which you simply include and execute.
parse.php:
<?php
include('xml.inc');
$doc = #simplexml_load_string(xml_function()) or die("Error");
echo $doc->title;
xml.php:
<?php
include('xml.inc');
header("Content-type: text/xml");
echo xml_function();
xml.inc:
<?php
function xml_function() {
$dbc = mysql... //gets data from database
$xml = "<!DOCTYPE..."; //xml stuff here
$xml .= "<title>" . $dataFromMySQL . "</title>";
return $xml;
}
But... even that seems silly, honestly, when you could have both output methods connect to the same data and skip a generation/parse step. Simply output HTML/XML conditionally.

How do I parse an external XML file (returned from a POST) with php?

I have a simple code written (based on some tutorials found around the internet) to parse and display an XML file. However, I only know how to reference an XML file stored on my server and I would like to be able to use an XML file that is being returned to me from a POST.
Right now my code looks like this:
if( ! $xml = simplexml_load_file('test.xml') )
{
echo 'unable to load XML file';
}
else
{
foreach( $xml as $event)
{
echo 'Title: ';
echo "$event->title<br />";
echo 'Description: '.$event->info.'<br />';
echo '<br />';
}
}
Is there some way I can replace the simpleXML_load_file function with one that will allow me to point to the POST URL that returns the XML file?
Use simplexml_load_string instead of loadfile:
simplexml_load_string($_POST['a']);
If you get the url to the file in the POST you can propably use the simplexml_load_file function with the url, but if that doesn't work you can use the file_get_contents in combination with the simplexml_load_string:
//say $_POST['a'] == 'http://example.com/test.xml';
simplexml_load_file($_POST['a']); // <-- propably works
simplexml_load_string(file_get_contents($_POST['a'])); //<-- defenitly works (propaly what happens internally)
also getting contents of external files could be prohibited by running PHP in safe mode.
If you are receiving a file that's been uploaded by the user, you can find it (the file) looking at the content of the $_FILES superglobal variable -- and you can read more about files uploads here (for instance, don't forget to call move_uploaded_file if you don't want the file to be deleted at the end of the request).
Then, you can work with this file the same way you already do with not-uploaded files.
If you are receiving an XML string, you can use simplexml_load_string on it.
And if you are only receiving the URL to a remote XML content, you have to :
download the file to your server
and, then, parse its content.
This can be done using simplexml_load_file, passing the URL as a parameter, if your server is properly configured (i.e. if allow_url_fopen is enabled).
Else, the download will have to be done using curl -- see curl_exec for a very basic example, and curl_setopt for the options you can use (you'll especially want to use CURLOPT_RETURNTRANSFER, to get the XML data as a string you can pass to simplexml_load_string).
From http://www.developershome.com/wap/wapUpload/wap_upload.asp?page=php4:
If you do not want to save the
uploaded file directly but to process
it, the PHP functions
file_get_contents() and fread() can
help you. The file_get_contents()
function returns a string that
contains all data of the uploaded
file:
if (is_uploaded_file($_FILES['myFile']['tmp_name']))
$fileData = file_get_contents($_FILES['myFile']['tmp_name']);
That will give you a handle on the raw text within that file. From there you will need to parse through the XML. Hope that helps!
Check out simplexml_load_string. You can then use cURL to do the post and fetch the result. An example:
<?php
$xml = simplexml_load_string($string_fetched_with_curl);
?>

Categories