How to improve the following code in PHP - php

Here is a simple form I am using to send XML data in admin_xml.php
<form name="review" action="admin_xml.php" method="post">
<textarea name="xml" cols="40" rows="10"></textarea>
<input class="submit" type="submit" value="Submit Request">
</form>
Here is the XML which I enter in order to retrieve the data from MySQL Database
<?xml version="1.0" encoding="UTF-8"?>
<GetOrdersIds>
<Credentials>
<Username>my_username</Username>
<Password>my_password</Password>
</Credentials>
<Criterions>
<OrderNumber></OrderNumber>
<StartDate>2009-01-01</StartDate>
<EndDate>2009-07-01</EndDate>
</Criterions>
</GetOrdersIds>
Here is the php code which extracts the tags from the xml:
<?php
$text_all = "<?xml version=\"1.0\"?>\r\n<GetOrdersIds version=\"1.0\">\r\n<Credentials>\r\n<Username>my_username</Username>\r\n<Password>my_password</Password>\r\n</Credentials>\r\n<Criterions>\r\n<OrderNumber></OrderNumber>\r\n<StartDate>2009-01-01</StartDate>\r\n<EndDate>2009-07-01</EndDate>\r\n</Criterions>\r\n</GetOrdersIds>";
$field = "Criterions";
$result = substr($text_all, strpos($text_all, "<".$field.">")+strlen("<".$field.">"), strpos($text_all, "</".$field.">")-strlen("<".$field.">")-strpos($text_all, "<".$field.">"));
?>
The result from the above php code is:
<OrderNumber></OrderNumber>
<StartDate>2009-01-01</StartDate>
<EndDate>2009-07-01</EndDate>
When the script is run, the php code goes through my mysql data, and extracts all orders between the Start Date and the End Date given above.
Is there a better way of improving the following php code, so that it performs the same function:
$result = substr($text_all, strpos($text_all, "<".$field.">")+strlen("<".$field.">"), strpos($text_all, "</".$field.">")-strlen("<".$field.">")-strpos($text_all, "<".$field.">"));
This is the code which searches through the xml data and retrieves all the tags.
UPDATE :
Can anyone list the $result code in SimpleXML?

Some temp vars will help and also make it easier to read.
$result = substr($text_all, strpos($text_all, "<".$field.">")+strlen("<".$field.">"), strpos($text_all, "</".$field.">")-strlen("<".$field.">")-strpos($text_all, "<".$field.">"));
Can be rewritten to.
$tagLen = strlen('<'.$field.'>');
$openTag = strpos($text_all, '<'.$field.'>');
$closeTag = strpos($text_all, '</'.$field.'>', $openTag);
$result = substr($text_all, $openTag + $tagLen, $closeTag - $tagLen - $openTag);
or use SimpleXML
$doc = simplexml_load_string($text_all);
echo $doc->Criterions->asXML();
If you want the individual values use this.
$doc = simplexml_load_string($text_all);
echo $doc->Criterions->OrderNumber;
echo $doc->Criterions->StartDate;
echo $doc->Criterions->EndDate;
if you want the element in XML then use asXML():
$doc = simplexml_load_string($text_all);
echo $doc->Criterions->OrderNumber->asXML();
echo $doc->Criterions->StartDate->asXML();
echo $doc->Criterions->EndDate->asXML();

With SimpleXML:
<?php
$xmlSTR = '<?xml version="1.0" encoding="UTF-8"?>
<GetOrdersIds>
<Credentials>
<Username>my_username</Username>
<Password>my_password</Password>
</Credentials>
<Criterions>
<OrderNumber></OrderNumber>
<StartDate>2009-01-01</StartDate>
<EndDate>2009-07-01</EndDate>
</Criterions>
</GetOrdersIds>';
$xml = new SimpleXMLElement($xmlSTR);
echo $xml->Credentials->Username;
//To see the entire structure print_r($xml); as php can access objects as arrays

Have a look at the simplexml module.

Use an XML parser like SimpleXML to extract that data:
$doc = simplexml_load_string($_POST['xml']);
$OrderNumber = $doc->Criterions->OrderNumber;
$StartDate = $doc->Criterions->StartDate;
$EndDate = $doc->Criterions->EndDate;

Assuming your XML string is stored in the variable called $text_all (as you show in your example), this will get you what you want man... :-)
$mysql_stuff = '';
$xml = new SimpleXMLElement($text_all);
foreach($xml->Criterions->children() as $criterion) {
$mysql_stuff .= $criterion->asXML()."\n";
}
echo $mysql_stuff;
$mysql_stuff will now contain:
<OrderNumber/>
<StartDate>2009-01-01</StartDate>
<EndDate>2009-07-01</EndDate>
I tested this and it works. I hope this answers your question!

Related

php- How to send $_POST data to xml?

I have a php file that contains:
<?php
$no = $_POST['no'];
$url = "http://domain.tld/answer.xml";
?>
The $url stores a URL that links to an xml file and that xml files is like:
<?xml version="1.0" encoding="UTF-8"?>
<vxml version = "2.1" >
<Call> </Call>
</vxml>
I want to pass the $_POST['no'] to my xml file. Suppose if $_POST['no'] is 9999988888, then the tag in xml should be like:
<Call>9999988888</Call>
Can anyone tell how to do this? :)
that xml file is on my own server.
you could use simplexml, as:
$no = $_POST['no'];
$xml = simplexml_load_file('your_xml_file.xml');
$xml->Call = $no;
//save/update your xml
$xml->asXML('your_xml_file.xml');
You need to generate the xml using PHP.
First of all, rename your .xml to .php.
Then, start it using
<?php
header('Content-type: text/xml');
?>
When you reach your call tag, change it to :
<Call><?php echo intval($_GET['no']); ?></Call>
Note: I've assumed your no is a number. If it's not, remove intval. It's nice to have it as it will protect you from injections.
At last, call your XML file using :
$url = "http://domain.tld/answer.php?no=8877454";
Your XML should have some keywords, i.e.
<?xml version="1.0" encoding="UTF-8"?>
<vxml version = "2.1" >
<Call>{{CALL}}</Call>
</vxml>
In your PHP File, just fetch this XML & use str_replace to replace those keywords,
<?php
$no = $_POST['no'];
$url = "http://domain.tld/answer.xml";
$xml = file_get_contents($url);
$newXML = str_replace("{{CALL}}", $no, $xml);
header('Content-type: text/xml');
echo $newXML;
?>

Get a special type of child in an xml document with PHP

I'm looking for a way to get a special type of child out of a xml file with php.
the xml:
<notify type="post" name="Max" />
I want to grab the name out of there.
My code: `$sender =
$sender = $node->getChild('notify');
$sender = $sender->getChild('name');
$sender = $sender->getData();
but as i expected it isn't working that way.
Thanks in advance for any help
You can use an xpath expression to get the job done. It is like an SQL query for XML.
$results = $xml->xpath("//notify[#type='post']/#name");
Assuming the XML in $xml, the expression reads like
select all notify nodes,
where their type-attribute is post,
give back the name-attribute.
$resultswill be an array, and my code example is made for simplexml. You can use the same xpath-expression with DOM though.
Here's the complete code:
$x = <<<XML
<root>
<notify type="post" name="Max" />
<notify type="get" name="Lisa" />
<notify type="post" name="William" />
</root>
XML;
$xml = simplexml_load_string($x);
$results = $xml->xpath("//notify[#type='post']/#name");
foreach ($results as $result) echo $result . "<br />";
Output:
Max
William
see it working: http://codepad.viper-7.com/eO29FK

How to have proper XML layout using PHP input

I know thins is not secure at all, but it is still before the beta stage and I'm just looking for functionality. So, I have a user input area where they put in their information. From there, the information is sent to a PHP file which makes it an XML file from there. The only problem is, there are no tags so I will show you the code used to create the XML file and the XML file too.
HTML
<form action="insertdata.php" method="post">
Data1<input name="data" value="" type="text" placeholder="Data">
Data2 <input name="data2" value="" type="text" placeholder="Data">
<input type="submit" value="Submit">
</form>
PHP
$xml = new DOMDocument("1.0");
$data = $xml ->createElement ("Data");
$datat = $xml -> createTextNode($_POST['data']);
$data = $xml ->appendChild ($datat);
$data1 = $xml -> createElement ("Data1");
$data1t = $xml -> createTextNode ($_POST['data1']);
$data1 = $xml -> appendChild ($data1t);
//echo "<xmp>".$xml -> saveXML (). "</xmp>";
$xml ->save("'".$_POST[data]."'.xml") or die ("error creating file");
So, my problem is not the creation of the XML file, it's that the XML file looks like this:
<?xml version="1.0"?>
Datainput
datainput1
Why isn't the data within the file contained by tags?
Also, how would you be able to do this?
You create the elements, but never used them. The $data and $data1 are NEVER used once created, so all you're doing is appending two textnodes to the root element. You want something more like
$xml = new DOMDocument("1.0");
$data = $xml->createElement('Data'); // Create <Data>
$text = $xml->createTextNode($_POST['data']); // fill in text node
$data->appendChild($text); // put textnode inside <Data>...</Data>
$xml->appendChild($data); // insert <Data> into the XML document.

when using XML parse, is the xml resource the object you access?

I dont seem to quite understand how xml_parse works. What i was doing was getting the contents of the xml file, create a parser, and pass it into xml_parse(). I dont know what to do after that. I was thinking that in my case, $xml was the array i can now iterate through. I was trying to see how i would parse my data.
$fp = file_get_contents("memberdata.xml");
echo "pre-create";
$xml = xml_parser_create();
echo "pre-parse";
$status = xml_parse($xml,$fp);
if(!$status){
die("Error parsing data from $fp into $xml");
}
echo "pre XML posting";
echo "<br />".$xml."<br />";
print_r($xml);
xml_parser_free($xml);
I cant seem to figure out how to access this.
Sample xml data is as follows:
<currentTime>2012-09-05 03:43:25</currentTime>
<result>
<rowset name="members" key="characterID" columns="characterID,name,startDateTime,baseID,base,title,logonDateTime,logoffDateTime,locationID,location,shipTypeID,shipType,roles,grantableRoles">
<row ..>
</rowset>
</result>
<cachedUntil></cashedUntil>
Instead of using the base tools, using one of the toolkits, SimpleXML will alleviate a lot of the frustrations. The answer to this question is redone using SimpleXML.
$fp = file_get_contents("memberdata.xml");
$eve = new SimpleXMLElement($fp);
$cols = $eve->{'result'}->rowset['columns'];
//I put result in {} because result is a special character in php.
$cols = explode(",",$cols);
foreach ($cols as $c){
echo "".$c."<br />";
}
//output is printed to screen

xml and php getting tag elements with certain element and outputting

I am have two xml files.. I first get one and loop through it then I need to take an id from the first xml file and find it in the second one and echo out the results associated with that id. If I were to do this with SQL I would simply do this:
$query = (SELECT * FROM HotelSummary WHERE roomTypeCode = '$id') or die();
while($row=mysql_fetch_array($query)){
$name = $row['Name'];
}
echo $name;
How can I do this is in xml and php??
I recommend you to read the DOMDocument documentation.
It's quite heavy but also powerful (not always clear what happens, but the Internet shold always give you a solution)
You can simply walk through your first document, finding your Id and then find your DOMElement via an XPath.
<?php
$dom = new DOMDocument();
$dom->load('1.xml');
foreach ($dom->getElementsByTagName('article') as $node) {
// your conditions to find out the id
$id = $node->getAttribute('id');
}
$dom = new DOMDocument();
$dom->load('2.xml');
$xpath = new DOMXPath($dom);
$element = $xpath->query("//*[#id='".$id."']")->item(0);
// would echo "top_2" based on my example files
echo $element->getAttribute('name');
Based on following test files:
1.xml
<?xml version="1.0" encoding="UTF-8"?>
<articles>
<article id="foo_1">
<title>abc</title>
</article>
<article id="foo_2">
<title>def</title>
</article>
</articles>
2.xml
<?xml version="1.0" encoding="UTF-8"?>
<tests>
<test id="foo_1" name="top_1">
</test>
<test id="foo_2" name="top_2">
</test>
</tests>
Use SimpleXML to create an object representation of the file. You can then loop through the elements of the Simple XML object.
Depending on the format of the XML file:
Assuming it is:
<xml>
<roomTypeCode>
<stuff>stuff</stuff>
<name>Skunkman</name>
</roomTypeCode>
<roomTypeCode>
<stuff>other stuff</stuff>
<name>Someone Else</name>
</roomTypeCode>
</xml>
It would be something like this:
$xml = simplexml_load_file('xmlfile.xml');
for($i = 0; $i < count($xml->roomTypeCode); $i++)
{
if($xml->roomTypeCode[$i]->stuff == "stuff")
{
$name = $xml->roomTypeCode[$i]->name;
}
}
That connects to the XML file, finds how many roomTypeCode entries there are, searches for the value of "stuff" within and when it matches it correctly, you can access anything having to do with that XML entry.

Categories