Reading - Writing XML dynamicly in PHP - php

I've following problem:
I am reading from a existing xml-file like this:
<?php
error_reporting(E_ALL);
ini_set('display_errors', 1);
//Deks.
$xml = simplexml_load_file( "FILE" ) or die (" Couldnt load. ");
foreach ($xml->children() as $one){
foreach ($one->children() as $two ){
foreach($two->children() as $three ){
$array = array();
foreach ($three as $key => $value ){
$array[ ( string ) $key ] = ( string )$value;
echo $key . ' = ' . $value . '<br />';
}
}
}
}
?>
So I get my needed output.
My XML looks like this:
<overx>
<overy>
<katx>
<katy>
<rnd>true</rndm>
</katy>
<rely>
<lwm>true</lwm>
</rely>
</katx>
</overy>
</overy>
The xml-file is shortened heavily. Most of children have different names also their children has.
Now I want to create a html form which reads the xml form dynamically.
That's the way I am doing it:
<?php
error_reporting(E_ALL);
ini_set('display_errors', 1);
$form_fields = null;
$xml = simplexml_load_file( "FILE" ) or die (" Couldnt load. ");
foreach ( $xml->children() as $one){
foreach ( $one->children() as $two ){
foreach( $two->children() as $three ){
$array = array();
foreach ( $three as $field ){
$form_fields .= '<div>';
$form_fields .= '<label>' . ucfirst($field->getName()) . ' </label>';
if ($field->getName() == "active" ){
$form_fields .= '<input type="checkbox" value="true"'.$field->getName() . '" />';
}
else{
$form_fields .= '<input type="text" name="'.$field->getName() . '" />';
}
$form_fields .= '</div>';
}
}
}
}
?>
But now I have the following problem:
I want to save the form as .xml which have exactly the same structure as the XML it's loaded from. Actually, I am saving poorly via javascript and right now it's only saving key->value but not the structure or anything else and I really don't know how to do it.
Thanks in advance.

Related

php - Retrieve value from $_SESSION and output using another variable

My question might seem totally silly but I am really stuck here.
I know $_SESSION is a global variable but I can't seem to know how to retrieve the value it stores.
For example:
<?php
if(isset($_SESSION["cart_products"]))
{
foreach ($_SESSION["cart_products"] as $cart_itm)
{
//set variables to use in content below
$product_name = $cart_itm["product_name"];
$product_code = $cart_itm["product_code"];
echo '<p>'.$product_name.'</p>';
echo '<p><input type="checkbox" name="remove_code[]" value="'.$product_code.'" /></p>';
}
}
echo $_SESSION["cart_products"];
?>
Here you can see, the $_SESSION["cart_products"] holds some value (information like product name, product code etc). Now, the problem is that I just want to echo out all the product names that are stored in $_SESSION["cart_products"].
Since it's a cart list, it contains more than ONE product details. But, when I echo out $product_name, it only shows the name of the last product in the list. And echoing out $_SESSION["cart_products"] gives array to string error.
Please, tell me how can I list out all the product names separating by a ,.
Any help will be greatly appreciated.
Thanks in advanced.
PS: I have already tried using implode() function.
for displaying all the product name separated by , use this code.
$allProductName = '';
$prefix = '';
foreach ($_SESSION["cart_products"] as $cart_itm)
{
$allProductName .= $prefix . '"' . $product_name. '"';
$prefix = ', ';
}
echo $allProductName;
Here's a edited version of your code
<?php
//you need to start session first
session_start();
$item = ["product_name" => "BMW", "product_code" => "540M"];
$list = array( $item, $item );
// Assuming you session list
$_SESSION[ "cart_products" ] = $list;
if(isset( $_SESSION["cart_products"])) {
foreach ( $_SESSION["cart_products"] as $cart_itm ) {
//set variables to use in content below
$product_name = $cart_itm["product_name"];
$product_code = $cart_itm["product_code"];
echo '<p>'.$product_name.'</p>';
echo '<p><input type="checkbox" name="remove_code[]" value="'.$product_code.'" /></p>';
}
// to print names seperated by ','
$temp = "";
foreach ( $_SESSION["cart_products"] as $cart_itm ) {
$temp .= $cart_itm["product_name"] . ", ";
}
echo $temp;
}
// you cant print array using echo directly
print_r( $_SESSION["cart_products"] );
?>
Finally, I got the answer to my query with the help of #Christophe Ferreboeuf. However, some modification was still needed.
Here's the corrected code:
$allProductName = '';
$prefix = '';
foreach ($_SESSION["cart_products"] as $cart_itm)
{
$allProductName .= $prefix . '"' . $cart_itm["product_name"]. '"';
$prefix = ', ';
}
echo $allProductName;

Buffering or moving PHP data to display in a different part of a webpage

I am parsing a very large XML file with XMLReader.
$reader = new XMLReader;
$reader->open('products.xml');
$dom = new DOMDocument;
$xpath = new DOMXpath($dom);
while ($reader->read() && $reader->name !== 'product') {
continue;
}
A while loop is used to display relevant data based on user input as well as building arrays with XML values.
while ($reader->name === 'product') {
$node = $dom->importNode($reader->expand(), TRUE);
if ($xpath->evaluate('number(price)', $node) > $price_submitted) {
$category = $xpath->evaluate('string(#category)', $node);
$name = $xpath->evaluate('string(name)', $node);
$price = $xpath->evaluate('number(price)', $node);
// Relevant search results displayed here:
echo "Category: " . $category . ". ";
echo "Name: " . $name . ". ";
echo "Price: " . $price . ". ";
$nameArray[] = $name;
}
$reader->next('product');
}
The foreach loop below uses the array that is built in the while loop above. I need these values (displayed in this foreach loop below) to appear BEFORE the while loop above displays the relevant search results. With XMLReader, you can only execute one while loop for each time you parse the XML, and I don't want to parse it twice because of memory and overhead issues. What is the best way to do this?
foreach ($nameArray as $names) {
echo $names . " ";
}
Well… there are not many options. The most effectiv straight-forward approach is to store category/name/price in array instead of outputting them directly:
<?php
$data = array();
while ($reader->name === 'product') {
$node = $dom->importNode($reader->expand(), TRUE);
if ($xpath->evaluate('number(price)', $node) > $price_submitted) {
$category = $xpath->evaluate('string(#category)', $node);
$name = $xpath->evaluate('string(name)', $node);
$price = $xpath->evaluate('number(price)', $node);
$data[] = array($category, $name, $price);
$nameArray[] = $name;
}
$reader->next('product');
}
foreach ($nameArray as $names) {
echo $names . " ";
}
foreach ($data as $datum) {
// Relevant search results displayed here:
echo "Category: " . $datum[0] . ". ";
echo "Name: " . $datum[1] . ". ";
echo "Price: " . $datum[2] . ". ";
}
In case that doesn't work memory-wise (you mentioned that XML file is really large) you should use db- or file-backed temporary storage

Need to create li with list of different links using php explode method

here is my working php explode code for NON links:
<?php
$textarea = get_custom_field('my_custom_output');
$array = explode(',',$textarea);
$output = ''; // initialize the variable
foreach ($array as $item) {
$item = trim($item); // clear off white-space
$output .= '<li>' . $item . '</li>';
}
?>
<ul>
<?php print $output; ?>
</ul>
..and the code which defines "my_custom_output", which I input into my textarea field:
text1,text2,text3,etc
..and the finished product:
text1
text2
text3
etc
So that works.
Now what I want to do is make text1 be a link to mywebsite.com/text1-page-url/
I was able to get this far:
<?php
$textarea = get_custom_field('my_custom_output');
$array = explode(',',$textarea);
$output = ''; // initialize the variable
foreach ($array as $item) {
$item = trim($item); // clear off white-space
$output .= '<li class="link-class"><a title="' . $item . '" href="http://mywebsite.com/' . $item_links . '">' . $item . '</a></li>';
}
?>
<ul>
<?php print $output; ?>
</ul>
Now, I would like $item_links to define just the rest of the url. For example:
I want to put input this into my textarea:
text1:text1-page-url,text2:new-text2-page,text3:different-page-text3
and have the output be this:
text1
text2
..etc (stackoverflow forced me to only have two links in this post because I only have 0 reputation)
another thing I want to do is change commas to new lines. I know the code for a new line is \n but I do not know how to swap it out. That way I can put this:
text1:text1-page-url
text2:new-text2-page
text3:different-page-text3
I hope I made this easy for you to understand. I am almost there, I am just stuck. Please help. Thank you!
Just split the $item inside your loop with explode():
<?php
$separator1 = "\n";
$separator2 = ":";
$textarea = get_custom_field('my_custom_output');
$array = explode($separator1,$textarea);
$output = ''; // initialize the variable
foreach ($array as $item) {
list($item_text, $item_links) = explode($separator2, trim($item));
$output .= '<li class="link-class"><a title="' . $item_text . '" href="http://mywebsite.com/' . $item_links . '">' . $item_text . '</a></li>';
}
?>
<ul>
<?php print $output; ?>
</ul>
And choose your string separators so $item_text, $item_links wouldn't contain them.
After you explode the string you could loop through again and separate the text and link into key/values. Something like...
$array_final = new array();
$array_temp = explode(',', $textarea);
foreach($array_temp as $item) {
list($text, $link) = explode(':', $item);
$array_final[$text] = $link;
}
foreach($array_final as $key => $value) {
echo '<li>'.$key.'</li>';
}
to change comma into new line you can use str_replace like
str_replace(",", "\r\n", $output)

How to read json properties using PHP

How to get all pid and styles attribute from following json data with minimum loop in php
{"general":{"note":{"display":false}},"elements":{"the-1":{"index":1,"src":"shirt1.png","pid":"pid-3563130","angle":0,"styles":"background:transparent;top:51.80000305175781px;left:122px;width:80px;height:80px;","background":"transparent","pos":{"top":51.80000305175781,"left":122},"size":{"width":80,"height":80},"details":{"other":""}},"the-2":{"index":2,"src":"shirt2.png","pid":"pid-132002","angle":0,"styles":"background:transparent;top:44.80000305175781px;left:155px;width:80px;height:80px;","background":"transparent","pos":{"top":44.80000305175781,"left":155},"size":{"width":80,"height":80},"details":{"other":""}}}}
Thanks
$str = '{"general":{"note":{"display":false}},"elements":{"the-1":{"index":1,"src":"shirt1.png","pid":"pid-3563130","angle":0,"styles":"background:transparent;top:51.80000305175781px;left:122px;width:80px;height:80px;","background":"transparent","pos":{"top":51.80000305175781,"left":122},"size":{"width":80,"height":80},"details":{"other":""}},"the-2":{"index":2,"src":"shirt2.png","pid":"pid-132002","angle":0,"styles":"background:transparent;top:44.80000305175781px;left:155px;width:80px;height:80px;","background":"transparent","pos":{"top":44.80000305175781,"left":155},"size":{"width":80,"height":80},"details":{"other":""}}}}';
$arr = json_decode($str, true);
foreach ($arr['elements'] as $element) {
echo 'pid: ' . $element['pid'] . '<br />';
echo 'styles: ' . $element['styles'] . '<br />';
}
use json_decode function in PHP to get assosiative array.
<?php
$myJson = '{"general":{"note":{"display":false}},"elements":{"the-1":{"index":1,"src":"shirt1.png","pid":"pid-3563130","angle":0,"styles":"background:transparent;top:51.80000305175781px;left:122px;width:80px;height:80px;","background":"transparent","pos":{"top":51.80000305175781,"left":122},"size":{"width":80,"height":80},"details":{"other":""}},"the-2":{"index":2,"src":"shirt2.png","pid":"pid-132002","angle":0,"styles":"background:transparent;top:44.80000305175781px;left:155px;width:80px;height:80px;","background":"transparent","pos":{"top":44.80000305175781,"left":155},"size":{"width":80,"height":80},"details":{"other":""}}}}';
$myArray = json_decode($myJson,true);
$myInnerArray = $myArray['elements'];
$styles = array();
foreach($myInnerArray as $element)
$styles[] = $element['styles'];
print_r($styles);
?>
PHP has great abilities to handle json.
Let's assume the JSON string you've posted above is stored in a PHP variable $myJSON.
So we can easily store an associative array of these values into $myJSONArray like so:
$myJSONArray = json_decode( $myJSON, true );
So, now we just loop through:
foreach( $myJSONArray['elements'] as $arr => $key )
echo( "A PID: " . $key['pid'] . "\n" );
See it in action on Codepad.
$json = json_decode('{"general":{"note":{"display":false}},"elements":{"the-1":{"index":1,"src":"shirt1.png","pid":"pid-3563130","angle":0,"styles":"background:transparent;top:51.80000305175781px;left:122px;width:80px;height:80px;","background":"transparent","pos":{"top":51.80000305175781,"left":122},"size":{"width":80,"height":80},"details":{"other":""}},"the-2":{"index":2,"src":"shirt2.png","pid":"pid-132002","angle":0,"styles":"background:transparent;top:44.80000305175781px;left:155px;width:80px;height:80px;","background":"transparent","pos":{"top":44.80000305175781,"left":155},"size":{"width":80,"height":80},"details":{"other":""}}}}', true);
$elements = $json['elements'];
foreach($elements as $element){
$pid = $element['pid'];
$styles = $element['styles'];
echo $pid.': '.$styles.'<br />';
}
Example here

loop in simplexml load file

I am using the following code to parse the XML data to MySQL table and it is working as expected.
<?php
$sxe = simplexml_load_file("$myfile");
foreach($sxe->AUTHAD as $sales) {
$authad="insert into test.authad values ('".mysql_real_escape_string($sales->LOCALDATE)."','".mysql_real_escape_string($sales->LOCALTIME)."','".mysql_real_escape_string($sales->TLOGID)."','" ...
?>
The problem is that when I get a new xml file with different format, I can not use the above insert into statement and have to change the parameters manually. For e.g.
$authadv_new="insert into test.authad values ('".mysql_real_escape_string($sales->NEW1)."','".mysql_real_escape_string($sales->NEW2)."','".mysql_real_escape_string($sales->NEW3)."','" ...
Is there any way to automate this? I mean the PHP code should be able to anticipate the parameters and generate the mysql_real_escape_string($sales->NEW1) to NEW10 values using a loop.
While satrun77's example works fine, you can use slightly less code and stick to the advantages of the simplexml object by using its "children()" method:
$sxe = simplexml_load_string($xml);
foreach($sxe->AUTHAD as $sales) {
foreach ($sales->children() as $child) {
$children[]="'".mysql_real_escape_string($child)."'";
}
$authad="insert into test.authad values (".implode($children,",").");";
}
Maybe something like this using a dynamic variable $var?
<?php
$values = array();
for($i = 1; $i < 11; $i++) {
$var = "NEW".$i;
$values[] = "'".mysql_real_escape_string($sales->$var)."'";
}
$string = join(",", $values);
I hope this is what you are looking for?
$string = '<?xml version="1.0" encoding="UTF-8" ?>
<root>
<AUTHAD>
<NEW1>New 1</NEW1>
<NEW2>New 2</NEW2>
<NEW3>New 3</NEW3>
<NEW4>New 4</NEW4>
<NEW5>New 5</NEW5>
<NEW6>New 6</NEW6>
</AUTHAD>
<AUTHAD>
<NEW1>New 11</NEW1>
<NEW2>New 22</NEW2>
<NEW3>New 33</NEW3>
</AUTHAD>
</root>
';
$sxe = simplexml_load_string($string);
foreach($sxe->AUTHAD as $sales) {
if (count($sales) > 0) {
$values = array();
foreach($sales as $key => $sale) {
$values[] = "'" . mysql_real_escape_string($sale) . "'";
}
$authadv_new="insert into test.authad values (" . join(', ', $values) . ")";
echo $authadv_new.'<br >';
}
}
You're looking for get_object_vars() to iterate over the object members:
<?php
mysql_connect( 'localhost', 'root', 'moin' );
$sxe = simplexml_load_file( $argv[1] );
var_dump( $sxe );
$sql = "insert into test.authad values (";
foreach($sxe->AUTHAD as $sales) {
$members = get_object_vars( $sales );
$values = array();
foreach ( $members as $name => $value ) {
echo "$name : $value\n";
$values[] = "'" . mysql_real_escape_string( $value ) . "'";
}
$sql .= join( $values, ', ' );
}
$sql .= ")\n";
echo $sql;
The input is this file:
<sxe>
<AUTHAD>
<eins>one</eins>
<zwei>two':-)</zwei>
<drei>three;"'</drei>
</AUTHAD>
</sxe>
I'm getting the following result here:
insert into test.authad values ('one', 'two\':-)', 'three;\"\'')
If you're not concerned about the order of data between each XML you can just implode the object rather than pick out the specific values each time. Doing an implode also allows you to avoid the loop.
INSERT INTO test.authad VALUES('".implode("','", mysql_real_escape_string($sxe->AUTHAD))."')

Categories