PDA

View Full Version : Problems with PHP/XML



taishar77
12-05-2012, 08:20 AM
I am attempting to make an addressbook using a php form/validation which then generates an xml file. I have every part of it working, validation/confirmation/xml generation but I am running into some problems with data not saving (it is erasing the previous xml instead of appending it). I am really new at this so I will apologize if my code is messy. Once I get this solved I am also hoping to use xsl to transform the xml into a nice table but I have problems with that not reading as well... Here is my code around the forms:


<?php
// define configuration file name and path
$configFile = 'abook.xml';

// if form not yet submitted
// display form
if (!isset($_POST['submit'])) {

// set up array with default parameters
$data = array();
$data['name'] = null;
$data['email'] = null;
$data['caddress'] = null;
$data['city'] = null;
$data['state'] = null;
$data['zipcode'] = null;
$data['phone'] = null;
$data['pug'] = null;
$data['comment'] = null;
$data['subscribe'] = null;

// read current configuration values
// use them to pre-fill the form
if (file_exists($configFile)) {
$doc = new DOMDocument();
$doc->preserveWhiteSpace = false;
$doc->load($configFile);
$address = $doc->getElementsByTagName('address');
foreach ($address->item(0)->childNodes as $node) {
$data[$node->nodeName] = $node->nodeValue;
}
}
?>

and then at the end after the form has been submitted:

/snips out the validation code/

// generate new XML document
$doc = new DOMDocument();

// create and attach root element <configuration>
$root = $doc->createElement('addressbook');
$configuration = $doc->appendChild($root);

// create and attach <oven> element under <configuration>
$address = $doc->createElement('address');
$configuration->appendChild($address);

// write each configuration value to the file
foreach ($config as $key => $value) {
if (trim($value) != '') {
$elem = $doc->createElement($key);
$text = $doc->createTextNode($value);
$address->appendChild($elem);
$elem->appendChild($text);
}
}

// format XML output

// save XML file
$doc->formatOutput = true;
$doc->save($configFile) or die('ERROR: Cannot write configuration file');
echo 'Thank you for filling out an application.';
}

?>

Is there a way to get this to not create new xmls and just add to the existing one? Once I get some input on that I'll go into my xsl problem but I think part of it has to do with a new xml being created likely wipes out my link to the style sheet....

taishar77
12-06-2012, 06:10 AM
I take it this is something that cannot be done?

traq
12-06-2012, 06:31 AM
it is erasing the previous xml instead of appending it...

Well, your code is doing that explicitly. You're not loading and adding to the existing xml; you're creating a new document and overwriting the existing one.


<?php

$doc = new DOMDocument();
$doc->load( "/path/to/your/existing.xml" );

// continue (but don't recreate the root element)
// you can use DOMXpath [http://php.net/domxpath] to find the element(s) you want to append your new elements to

If you don't absolutely need to use xml for this, I'd recommend taking a different direction...

for example, if the addresses you're collecting ever need to be searched (e.g., to find a particular person's address, or addresses in a given city), you'd be much better off using a database.

If you're going to send it to another application (e.g., to a webpage for use by javascript), you might consider using JSON - it's much simpler, lighter weight, equally portable, less error-prone, and it's trivial for most languages to convert it to native data types.

XML is complex, slow to process, and memory-intensive (you have to load the entire document before you can do anything).

taishar77
12-06-2012, 06:43 AM
Thank you traq, I figured it was because I am writing a new one with DOM, I'm just really new so trying to find the variables I need to swap out is where it becomes sort of a head banging against the wall experience :)

I have the database elements created with MySQL but I am even less experienced doing that then I am generating the xml file, which I've managed to do but it obviously has been a huge headache for someone who is very new and learning on the fly. I will research how to write it to a MySQL database and generate a table for it - is there a resource you can point me to for that specifically? I've gotten sort of rummy working on this four straight days into hours in the morning I'd care to forget.

I managed to get a table setup on my server for MySQL but that is something totally foreign to me on how to access/write to it.

traq
12-06-2012, 03:07 PM
MySQL's dev website is a great resource, but it's the most confusing thing in the world to try to read.

For this project, you probably wouldn't need more than SELECT, INSERT, and maybe UPDATE for your queries. The big part is designing your tables and indexes. Can you describe each piece of data that you're collecting, and how they relate to each other? e.g., which pieces are optional, which are sub-parts of the same info, which info might have more than one entry for the same person, which info must be unique? Which pieces of data will you be querying (searching) by?

taishar77
12-07-2012, 09:31 AM
I wound up using a


$sql="INSERT INTO Persons (FirstName, LastName, Email, Address, City, State, Zipcode, Comment, Color, Color2, Subscribe)
VALUES
('$_POST[firstname]','$_POST[lastname]','$_POST[email]','$_POST[address]','$_POST[city]','$_POST[state]','$_POST[zipcode]','$_POST[comment]','$_POST[color]','$_POST[color2]','$_POST[subscribe]')";

sequence and it worked wonderfully. You were exactly right in that creating a database and connecting to it to create the output was much simpler than messing around with creating xml via DOMDocument functions. I later on managed to find an example of the DOM function I needed but I was already done (usually works that way doesn't it?). Thanks for your advice!


MySQL's dev website is a great resource, but it's the most confusing thing in the world to try to read.

For this project, you probably wouldn't need more than SELECT, INSERT, and maybe UPDATE for your queries. The big part is designing your tables and indexes. Can you describe each piece of data that you're collecting, and how they relate to each other? e.g., which pieces are optional, which are sub-parts of the same info, which info might have more than one entry for the same person, which info must be unique? Which pieces of data will you be querying (searching) by?

traq
12-07-2012, 08:53 PM
I wound up using a

$sql="INSERT INTO Persons (FirstName, LastName, Email, Address, City, State, Zipcode, Comment, Color, Color2, Subscribe)
VALUES
('$_POST[firstname]','$_POST[lastname]','$_POST[email]','$_POST[address]','$_POST[city]','$_POST[state]','$_POST[zipcode]','$_POST[comment]','$_POST[color]','$_POST[color2]','$_POST[subscribe]')";

A little more advice: do not use that query. You're using user-supplied data directly in your query, which will lead to either an SQL injection attack or a multitude of SQL errors.

You need to sanitize any data you get from the user, before you use it. For example:
<?php

$DB = new mysqli( 'host','username','password','table_name' );

// much safer:
$firstname = empty( $_POST['firstname'] )? // check if value was submitted
"Some Guy": // if not, assign a default value -maybe even "" [empty string]
$DB->real_escape_string( $_POST['firstname'] ) // if so, sanitize the input for use in your query
;

// if you need to validate the user input (e.g., make a field required),
// you might do it like this:
if( empty( $_POST['lastname'] ) ){
$errors[] = "Lastname is required!"; // set error message
}else{
$lastname = $DB->real_escape_string( $_POST['lastname'] ); // sanitize input
}

// check for errors
if( empty( $errors ) ){
$SQL = "INSERT INTO `Persons` ( `firstname`,`lastname` ) VALUES( '$firstname','$lastname' )";
if( $DB->query( $SQL ) ){ /* success! */ }
else{ /* problem :( */ }
}else{
/* errors in submission! */
}