Help, prepare a package of data and posting it to a PHP form

Hi,

I came across this thread prepare a package of data and posting it to a PHP form, http://forum.unity3d.com/threads/109918-prepare-a-package-of-data-and-posting-it-to-a-PHP-form

The problem is that the FileInfo keep append the local path in front of the URL I provided which result an error of DirectoryNotFoundException.

using UnityEngine;
using System.Collections;
using System.Xml;
using System.Xml.Serialization;
using System.IO;
using System.Text;

public class _GameSaveLoad : MonoBehaviour {
	
	//local private members
	Rect _Save, _Load, _SaveMSG, _LoadMSG;
	bool _ShouldSave, _ShouldLoad, _SwitchSave, _SwitchLoad;
	string _FileLocation, _FileName;
	public GameObject _Player;
	UserData myData;
	string _PlayerName;
	string _data;
	
	Vector3 VPosition;
	
	public string getFileName;
	
	string url;

	//When the EGO is instansiated the Atart will trigger
	//so we setup our initial values for our local members
	void Start () {
		
		//we setup our rectangles for our messages
		_Save = new Rect( 10, 80, 100, 20 );
		_Load = new Rect( 10, 100, 100, 20 );
		_SaveMSG = new Rect( 10, 120, 100, 20 );
		_LoadMSG = new Rect( 10, 140, 400, 40 );
		
		//Where we want to save and load to and from
		//_FileLocation = Application.dataPath + @"/Data";
		string url="http://localhost/demoProject/upload.php";
		_FileLocation = url;
		
		//for now, lets just set the name to Joe Schmoe
		_PlayerName = "Joe Schmoe";
		
		//we need something to store the information into
		myData = new UserData();
	}
	
	// Update is called once per frame
	void Update () {
	
	}
	
	void OnGUI () {
		//Create File Name
		getFileName = GUI.TextField( new Rect( 20, 150, 150, 30 ), getFileName, 45 );
		print( getFileName );
		
		_FileName = getFileName + ".xml";
		
		//Loading the player
		if( GUI.Button( _Load, "Load" ) ) {
			GUI.Label( _LoadMSG, "Loading from: " + _FileLocation );
			//Load out userData into myData
			LoadXML();
			if( _data.ToString() != "" ) {
				//notice how I use a referenvce to type (UserData) here, you need this
				//so that the returned objects is converted into the correct type
				myData = (UserData)DeserializeObject(_data);
				//set the players position to the data we loaded
				VPosition = new Vector3( myData._iUser.x, myData._iUser.y, myData._iUser.z );
				_Player.transform.position = VPosition;
				//just a way to show that we loaded in ok
				Debug.Log( myData._iUser.name );
			}
		}
		
		//Saving the player
		if( GUI.Button( _Save, "Save" ) ) {
			
			GUI.Label( _SaveMSG, "Saving to: " + _FileLocation );
			myData._iUser.x = _Player.transform.position.x;
			myData._iUser.y = _Player.transform.position.y;
			myData._iUser.z = _Player.transform.position.z;
			myData._iUser.name = _PlayerName;
			
			//Time to create our XML
			_data = SerializeObject( myData );
			//This is the final resulting XML from the serialization process
			CreateXML();
			Debug.Log( _data );
		}
	}
	
	//The following methods came from the referenced URL
	string UTF8ByteArrayToString( byte[] characters ) {
		UTF8Encoding encoding = new UTF8Encoding();
		string constructedString = encoding.GetString( characters );
		return( constructedString );
	}
	
	byte[] StringToUTF8ByteArray( string pXmlString ) {
		UTF8Encoding encoding = new UTF8Encoding();
		byte[] byteArray = encoding.GetBytes( pXmlString );
		return byteArray;
	}
	
	//Here we serialize our UserData object of myData
	string SerializeObject( object pObject ) {
		string XmlizedString = null;
		MemoryStream memorystream = new MemoryStream();
		XmlSerializer xs = new XmlSerializer( typeof( UserData ) );
		XmlTextWriter xmlTextWriteer = new XmlTextWriter( memorystream, Encoding.UTF8 );
		xs.Serialize( xmlTextWriteer, pObject );
		memorystream = ( MemoryStream )xmlTextWriteer.BaseStream;
		XmlizedString = UTF8ByteArrayToString( memorystream.ToArray() );
		return XmlizedString;
	}
	
	//Here we deserialize it back into its original form
	object DeserializeObject( string pXmlizedString ) {
		XmlSerializer xs = new XmlSerializer( typeof( UserData ) );
		MemoryStream memoryStream = new MemoryStream( StringToUTF8ByteArray( pXmlizedString ) );
		XmlTextWriter xmlTextWriter = new XmlTextWriter( memoryStream, Encoding.UTF8 );
		return xs.Deserialize( memoryStream );
	}
	
	//Save and load methods for the file itself
	void CreateXML () {
		
		StreamWriter writer;
		
		string encodedThumbnail = "";
			
		//FileInfo t = new FileInfo( _FileLocation + "/" + _FileName );
		FileInfo t = new FileInfo( _FileLocation );
		print ( _FileLocation );
		if( !t.Exists ) {
			writer = t.CreateText();
		}
		else {
			t.Delete();
			writer = t.CreateText();
		}
		
		writer.Write( _data );
		writer.Close();
		
		Debug.Log( "File written" );
		
		XmlDocument newXml = new XmlDocument();
		newXml.LoadXml("<_iUser></_iUser>");
		XmlNode rootNode = newXml.DocumentElement;
		//this would be how you insert the base64 string into a XML element
		rootNode.InnerText = encodedThumbnail;
		MemoryStream ms = new MemoryStream();
		newXml.Save(ms);
		byte[] bytes = ms.ToArray();
		print ( "xml converted to bytes" );
		
		//Create a Web form
		WWWForm form = new WWWForm();
		form.AddField( "action", "Upload XML" );
		form.AddBinaryData( "fileUpload", bytes, _FileName + ".xml", "text/xml" );
		WWW www = new WWW( url, form );
	}
	
	void LoadXML () {
		StreamReader r = File.OpenText( _FileLocation + "\\" + _FileName );
		string _info = r.ReadToEnd();
		r.Close();
		_data = _info;
		Debug.Log( "File Read" );
	}
}

//UserData is our custom class that holds our defined objects we want to store in XML format
public class UserData {
	//we have to define a default instance of the structure
	public DemoData _iUser;
	//Default constructor doesn't really do anything at the moment
	public UserData(){}
	
	//Anything we want to store in the XML file, we define it here
	public struct DemoData {
		public float x;
		public float y;
		public float z;
		public string name;
	}
}

You can not use an URL as a path. FileInfo and the pass you pass to it are for filesystems, an URL is not a direction to a file system, but to a resource (in this case a script or file on a webserver). You must create the XML (or json if you like, though you need a different library for that, but json has less data overhead) in memory (instead of a file, using MemoryStream class)

Then save your Xml file there. Once done, read it into a string and either use the WWW/WWWForm classes (Unity Api) or Http classes from .NET framework (don’t forget to do this in an extra thread in order not to block your game thread when sending/receiving data) to communicate with the webserver.

I manage to create the XML in memory.
When I tried to post it to my php file and it return success, but I cannot find the xml file in server.
Not sure whether the problem lies at the _GameSaveLoad.cs or upload.php

_GameSaveLoad.cs

using UnityEngine;
using System.Collections;
using System.Xml;
using System.Xml.XPath;
using System.Xml.Serialization;
using System.IO;
using System.Text;

public class _GameSaveLoad : MonoBehaviour {
	
	//local private members
	Rect _Save, _Load, _SaveMSG, _LoadMSG;
	bool _ShouldSave, _ShouldLoad, _SwitchSave, _SwitchLoad;
	string _FileLocation, _FileName;
	public GameObject _Player;
	UserData myData;
	string _PlayerName;
	string _data;
	
	Vector3 VPosition;
	
	public string getFileName;
	
	string url;

	//When the EGO is instansiated the Atart will trigger
	//so we setup our initial values for our local members
	void Start () {
		
		//we setup our rectangles for our messages
		_Save = new Rect( 10, 80, 100, 20 );
		_Load = new Rect( 10, 100, 100, 20 );
		_SaveMSG = new Rect( 10, 120, 100, 20 );
		_LoadMSG = new Rect( 10, 140, 400, 40 );
		
		//Where we want to save and load to and from
		_FileLocation = Application.dataPath + @"/Data";
		string url="http://localhost/demoProject/upload.php";
		//_FileLocation = url;
		
		//for now, lets just set the name to Joe Schmoe
		_PlayerName = "Joe Schmoe";
		
		//we need something to store the information into
		myData = new UserData();
	}
	
	// Update is called once per frame
	void Update () {
	
	}
	
	void OnGUI () {
		//Create File Name
		getFileName = GUI.TextField( new Rect( 20, 150, 150, 30 ), getFileName, 45 );
		print( getFileName );
		
		_FileName = getFileName + ".xml";
		
		//Loading the player
		if( GUI.Button( _Load, "Load" ) ) {
			GUI.Label( _LoadMSG, "Loading from: " + _FileLocation );
			//Load out userData into myData
			LoadXML();
			if( _data.ToString() != "" ) {
				//notice how I use a referenvce to type (UserData) here, you need this
				//so that the returned objects is converted into the correct type
				myData = (UserData)DeserializeObject(_data);
				//set the players position to the data we loaded
				VPosition = new Vector3( myData._iUser.x, myData._iUser.y, myData._iUser.z );
				_Player.transform.position = VPosition;
				//just a way to show that we loaded in ok
				Debug.Log( myData._iUser.name );
			}
		}
		
		//Saving the player
		if( GUI.Button( _Save, "Save" ) ) {
			
			GUI.Label( _SaveMSG, "Saving to: " + _FileLocation );
			myData._iUser.x = _Player.transform.position.x;
			myData._iUser.y = _Player.transform.position.y;
			myData._iUser.z = _Player.transform.position.z;
			myData._iUser.name = _PlayerName;
			
			//Time to create our XML
			_data = SerializeObject( myData );
			//This is the final resulting XML from the serialization process
			CreateXML();
			Debug.Log( _data );
		}
	}
	
	//The following methods came from the referenced URL
	string UTF8ByteArrayToString( byte[] characters ) {
		UTF8Encoding encoding = new UTF8Encoding();
		string constructedString = encoding.GetString( characters );
		return( constructedString );
	}
	
	byte[] StringToUTF8ByteArray( string pXmlString ) {
		UTF8Encoding encoding = new UTF8Encoding();
		byte[] byteArray = encoding.GetBytes( pXmlString );
		return byteArray;
	}
	
	//Here we serialize our UserData object of myData
	string SerializeObject( object pObject ) {
		string XmlizedString = null;
		MemoryStream memorystream = new MemoryStream();
		XmlSerializer xs = new XmlSerializer( typeof( UserData ) );
		XmlTextWriter xmlTextWriteer = new XmlTextWriter( memorystream, Encoding.UTF8 );
		xs.Serialize( xmlTextWriteer, pObject );
		memorystream = ( MemoryStream )xmlTextWriteer.BaseStream;
		XmlizedString = UTF8ByteArrayToString( memorystream.ToArray() );
		return XmlizedString;
	}
	
	//Here we deserialize it back into its original form
	object DeserializeObject( string pXmlizedString ) {
		XmlSerializer xs = new XmlSerializer( typeof( UserData ) );
		MemoryStream memoryStream = new MemoryStream( StringToUTF8ByteArray( pXmlizedString ) );
		XmlTextWriter xmlTextWriter = new XmlTextWriter( memoryStream, Encoding.UTF8 );
		return xs.Deserialize( memoryStream );
	}
	
	/*public void ParseXml( TextAsset xmlFile, string xmlPathString ) {
		//Convert XML File TextAsset to string
		string strXmlFileData = xmlFile.ToString();
		
		//Create byte array from xml string
		byte[] byteArray = new byte[strXmlFileData.Length];
		System.Text.ASCIIEncoding encoding = new System.Text.ASCIIEncoding();
		byteArray = encoding.GetBytes( strXmlFileData );
		
		//Create memory stream from byte array
		MemoryStream memoryStream = new MemoryStream( byteArray );
		memoryStream.Seek( 0, SeekOrigin.Begin );
		
		//Create XMLDocument from memory stream
		XmlDocument xmlDoc = new XmlDocument();
		xmlDoc.Load( memoryStream );
		
		//Set up XPathDocument
		XPathDocument myXPathDocument = new XPathDocument( new XmlNodeReader( xmlDoc ) );
		
		//Create XPathNavigator object to navigate current XPathDocument
		XPathNavigator myXPathNavigator = myXPathDocument.CreateNavigator();
		
		//Create XPathNodeIterator object to iterate through XPath Query
		XPathNodeIterator Sections = myXPathNavigator.Select( xmlPathString );
		
		while( Sections.MoveNext() ){
			string strSubSectionTitle = Sections.Current.GetAttribute( "name", "" );
			string strSubSectionBody = Sections.Current.InnerXml.ToString();
			GUILayout.Label( strSubSectionTitle, "subsection_title" );
			GUILayout.Label( strSubSectionBody );
		}
		
		print ( "done convert" );
		
		WWWForm form = new WWWForm();
		form.AddField( "action", "Upload XML" );
		form.AddBinaryData( "fileUpload", byteArray, _FileName + ".xml", "text/xml" );
		WWW www = new WWW( url, form );
		print ( "saved in server" );
	}*/
	
	//Save and load methods for the file itself
	void CreateXML () {
		
		StreamWriter writer;
		
		string encodedThumbnail = "";
			
		FileInfo t = new FileInfo( _FileLocation + "/" + _FileName );
		//FileInfo t = new FileInfo( _FileLocation );
		//print ( _FileLocation );
		if( !t.Exists ) {
			writer = t.CreateText();
		}
		else {
			t.Delete();
			writer = t.CreateText();
		}
		
		writer.Write( _data );
		writer.Close();
		
		Debug.Log( "File written" );
		
		//Convert XML File TextAsset to string
		string xmlFile = t.CreateText().ToString();
		string strXmlFileData = xmlFile;
		
		//Create byte array from xml string
		byte[] byteArray = new byte[strXmlFileData.Length];
		System.Text.ASCIIEncoding encoding = new System.Text.ASCIIEncoding();
		byteArray = encoding.GetBytes( strXmlFileData );
		
		//Create memory stream from byte array
		MemoryStream memoryStream = new MemoryStream( byteArray );
		memoryStream.Seek( 0, SeekOrigin.Begin );
		
		//Create XMLDocument from memory stream
		XmlDocument xmlDoc = new XmlDocument();
		xmlDoc.Save( memoryStream );
		
		WWWForm form = new WWWForm();
		form.AddField( "action", "Upload XML" );
		form.AddBinaryData( "fileUpload", byteArray, _FileName + ".xml", "text/xml" );
		WWW www = new WWW( url, form );
		
		/*XmlDocument newXml = new XmlDocument();
		newXml.LoadXml( x );
		XmlNode rootNode = newXml.DocumentElement;
		//this would be how you insert the base64 string into a XML element
		rootNode.InnerText = encodedThumbnail;
		MemoryStream ms = new MemoryStream();
		newXml.Save(ms);
		byte[] bytes = ms.ToArray();
		print ( "xml converted to bytes" );
		
		//Create a Web form
		WWWForm form = new WWWForm();
		form.AddField( "action", "Upload XML" );
		form.AddBinaryData( "fileUpload", bytes, _FileName + ".xml", "text/xml" );
		WWW www = new WWW( url, form );*/
		
		print ( "xml in server" );
	}
	
	void LoadXML () {
		StreamReader r = File.OpenText( _FileLocation + "\\" + _FileName );
		string _info = r.ReadToEnd();
		r.Close();
		_data = _info;
		Debug.Log( "File Read" );
	}
}

//UserData is our custom class that holds our defined objects we want to store in XML format
public class UserData {
	//we have to define a default instance of the structure
	public DemoData _iUser;
	//Default constructor doesn't really do anything at the moment
	public UserData(){}
	
	//Anything we want to store in the XML file, we define it here
	public struct DemoData {
		public float x;
		public float y;
		public float z;
		public string name;
	}
}

upload.php

<?php
if ( isset ($_POST['action']) ) {
if($_POST['action'] == "Upload XML") {
unset($imagename);

if(!isset($_FILES)  isset($HTTP_POST_FILES)) $_FILES = $HTTP_POST_FILES;

if(!isset($_FILES['fileUpload'])) $error["image_file"] = "An image was not found.";

$imagename = basename($_FILES['fileUpload']['name']);

if(empty($imagename)) $error["imagename"] = "The name of the image was not found.";

if(empty($error)) {
$newimage = "images/" . $imagename;
//echo $newimage;
$result = @move_uploaded_file($_FILES['fileUpload']['tmp_name'], $newimage);
if ( empty($result) ) $error["result"] = "There was an error moving the uploaded file.";
}
}
} else {
echo "no form data found";
}
?>

How big is the file?

You are missing an error check in your PHP script: Upload Errors.

    if($_FILES['fileUpload']['error'] > 0) {
        // some other error occured
    }

If an upload error happens, PHP will silently fail, but “fileUpload” will still be populated, just the error field will be > 0. Also I’m not sure why you are using “image/” as path, usually that’s the place where you put the full path to your upload folder (on most non-webhosted-webservers, something like /var/www/htdocs/uploads (where the htdocs is the folder where the website is on the file system) and you must make sure that the folder you are writing in has sufficient permissions (on most webservers rwx-linux permissions for user/group www-data))

move_uploaded_file also returns false when it wasn’t able to create the file (no such directory, permission, file already exists)

The XML file will be huge.
I will look into the PHP part, still new to PHP…

Well for that you need to check the PHP configuration of your webserver. The default of many hosting services (and PHP default configuration on most Ubuntu boxes) is 2M per file

You may want to to check the php.ini file (depending on system, it can be found in /etc/php5/apache/php.ini on ubuntu/debian boxes) for the following entries

http://php.net/manual/en/ini.core.php

upload_max_filesize => max size per single uploaded file
post_max_size => max post size. Should be max number of uploaded files at one * upload_max_filesize or less.

Everything beyond (server configuration etc) that is somewhat out of scope, of the forum ^^

I made a mistake at memoryStream, instead of load, i wrote save

Mistake:

xmlDoc.Save( memoryStream );

Edited:

xmlDoc.Load( memoryStream );

But after editing it, a new error appears in Unity3d,
XmlException: Text node cannot appear in this state. Line 1, position 1.
Mono.Xml2.XmlTextReader.ReadText(Boolean notWhitespace)

Maybe this will help.

Well your code starts to confuse me a bit now.

In your first post you attempted to create a xml file “from your game to a webserver” which doesn’t work. So I said you should use a memory stream to save your xml to, before sending it this way you don’t have to save a file into the file system (HDD, SD Card, internal flash memory of a smartphone). Once the XML file is saved you could simply read the bytes and pass it.

What you are doing now is (in CreateXML()):

  1. You write to a file on the file system
  2. write the XML
  3. get another stream reader and use “ToString()” (which doesn’t return the content of it! A StringWriter, it can’t read contents of a file. ToString() returns something like “System.IO.StreamWriter”
  4. you put this into another string
  5. you pass this to memory reader
  6. then you create a new XmlDocument
  7. and safe the (empty) xml document to the memory stream (overriding the thing you put in before) XD

My suggestion: throw all FileInfo and StreamWriter from your CreateXML method and replace StreamWriter with MemoryStream. Though what confuses me is: Why do you need the XmlDocument at all? SerializeObject already returns a string which should be your XML string

Tobias J., thanks for the link, I will look into it.

Tseng, I working on the changes now, hope it will works…

Tseng,
for the XmlDocument, I am just following whatever tutorials I can find and piecing them together.
Which at the end of the days confuse me more…

You usually use XML document if you want
a) read an XML file manually (i.e. read certain nodes or parts of it)
b) edit an XML file via code (changing nodes, values and attributes)
c) create an XML file in code (w/o serialization), i.e see docs for XmlDocument.Append

However, when you use a Serializer, the Serializer will convert a certain object/class into xml and back, so it usually doesn’t involve XmlDocument at all (as you can see in your Serialize/Deserialize methods)

which means that if I want to post the data to server I have to use a Serializer?

I had serialize the data at string SerializeObject.
When i try to post it to my php file, it returns Error during upload: malformed

_GameSaveLoad.cs

using UnityEngine;
using System.Collections;
using System.Xml;
using System.Xml.XPath;
using System.Xml.Serialization;
using System.IO;
using System.Text;

public class _GameSaveLoad : MonoBehaviour {
	
	//local private members
	Rect _Save, _Load, _SaveMSG, _LoadMSG;
	bool _ShouldSave, _ShouldLoad, _SwitchSave, _SwitchLoad;
	string _FileLocation, _FileName;
	public GameObject _Player;
	UserData myData;
	string _PlayerName;
	string _data;
	
	Vector3 VPosition;
	
	public string getFileName;
	
	string url;
	byte[] bytes;

	//When the EGO is instansiated the Atart will trigger
	//so we setup our initial values for our local members
	void Start () {
		
		//we setup our rectangles for our messages
		_Save = new Rect( 10, 80, 100, 20 );
		_Load = new Rect( 10, 100, 100, 20 );
		_SaveMSG = new Rect( 10, 120, 100, 20 );
		_LoadMSG = new Rect( 10, 140, 400, 40 );
		
		//Where we want to save and load to and from
		_FileLocation = Application.dataPath + @"/Data";
		string url="http://localhost/demoProject/upload.php";
		//_FileLocation = url;
		
		//for now, lets just set the name to Joe Schmoe
		_PlayerName = "Joe Schmoe";
		
		//we need something to store the information into
		myData = new UserData();
	}
	
	// Update is called once per frame
	void Update () {
	
	}
	
	void OnGUI () {
		//Create File Name
		getFileName = GUI.TextField( new Rect( 20, 150, 150, 30 ), getFileName, 45 );
		print( getFileName );
		
		_FileName = getFileName + ".xml";
		
		//Loading the player
		if( GUI.Button( _Load, "Load" ) ) {
			GUI.Label( _LoadMSG, "Loading from: " + _FileLocation );
			//Load out userData into myData
			LoadXML();
			if( _data.ToString() != "" ) {
				//notice how I use a referenvce to type (UserData) here, you need this
				//so that the returned objects is converted into the correct type
				myData = (UserData)DeserializeObject(_data);
				//set the players position to the data we loaded
				VPosition = new Vector3( myData._iUser.x, myData._iUser.y, myData._iUser.z );
				_Player.transform.position = VPosition;
				//just a way to show that we loaded in ok
				Debug.Log( myData._iUser.name );
			}
		}
		
		//Saving the player
		if( GUI.Button( _Save, "Save" ) ) {
			
			GUI.Label( _SaveMSG, "Saving to: " + _FileLocation );
			myData._iUser.x = _Player.transform.position.x;
			myData._iUser.y = _Player.transform.position.y;
			myData._iUser.z = _Player.transform.position.z;
			myData._iUser.name = _PlayerName;
			
			//Time to create our XML
			_data = SerializeObject( myData );
			//This is the final resulting XML from the serialization process
			//CreateXML();
			//Debug.Log( _data );
		}
	}
	
	//The following methods came from the referenced URL
	string UTF8ByteArrayToString( byte[] characters ) {
		UTF8Encoding encoding = new UTF8Encoding();
		string constructedString = encoding.GetString( characters );
		return( constructedString );
	}
	
	byte[] StringToUTF8ByteArray( string pXmlString ) {
		UTF8Encoding encoding = new UTF8Encoding();
		byte[] byteArray = encoding.GetBytes( pXmlString );
		return byteArray;
	}
	
	//Here we serialize our UserData object of myData
	string SerializeObject( object pObject ) {
		UTF8Encoding encoding = new UTF8Encoding();
		string XmlizedString = null;
		MemoryStream memorystream = new MemoryStream();
		XmlSerializer xs = new XmlSerializer( typeof( UserData ) );
		XmlTextWriter xmlTextWriteer = new XmlTextWriter( memorystream, Encoding.UTF8 );
		xs.Serialize( xmlTextWriteer, pObject );
		memorystream = ( MemoryStream )xmlTextWriteer.BaseStream;
		XmlizedString = UTF8ByteArrayToString( memorystream.ToArray() );
		
		bytes = StringToUTF8ByteArray( XmlizedString );
		UploadFile( url );
		
		return XmlizedString;
	}
	
	//Here we deserialize it back into its original form
	object DeserializeObject( string pXmlizedString ) {
		XmlSerializer xs = new XmlSerializer( typeof( UserData ) );
		MemoryStream memoryStream = new MemoryStream( StringToUTF8ByteArray( pXmlizedString ) );
		XmlTextWriter xmlTextWriter = new XmlTextWriter( memoryStream, Encoding.UTF8 );
		return xs.Deserialize( memoryStream );
	}
	
	IEnumerator UploadData (string uploadURL) {
		WWWForm postForm = new WWWForm();
		postForm.AddField( "action", "Upload Data" );
		postForm.AddBinaryData( "fileUpload", bytes, _FileName, "text/xml" );
		WWW upload = new WWW(uploadURL, postForm);
		yield return upload;
		
		if( upload.error == null ) {
			Debug.Log(upload.text);
		}
		else {
			Debug.Log( "Error during upload: " + upload.error );
		}
	}
	
	void UploadFile( string uploadURL ) {
		StartCoroutine( UploadData( uploadURL ) );
	}
	
	//Save and load methods for the file itself
	void CreateXML () {
		
		StreamWriter writer;
		
		//string encodedThumbnail = "";
			
		FileInfo t = new FileInfo( _FileLocation + "/" + _FileName );
		if( !t.Exists ) {
			writer = t.CreateText();
		}
		else {
			t.Delete();
			writer = t.CreateText();
		}
		
		writer.Write( _data );
		writer.Close();
		
		Debug.Log( "File written" );
	}
	
	void LoadXML () {
		StreamReader r = File.OpenText( _FileLocation + "\\" + _FileName );
		string _info = r.ReadToEnd();
		r.Close();
		_data = _info;
		Debug.Log( "File Read" );
	}
}

//UserData is our custom class that holds our defined objects we want to store in XML format
public class UserData {
	//we have to define a default instance of the structure
	public DemoData _iUser;
	//Default constructor doesn't really do anything at the moment
	public UserData(){}
	
	//Anything we want to store in the XML file, we define it here
	public struct DemoData {
		public float x;
		public float y;
		public float z;
		public string name;
	}
}

upload.php

<?php
	if ( isset ($_POST['action']) ) {
		if($_POST['action'] == "Upload Data") {
			unset($dataname);

			if(!isset($_FILES)  isset($HTTP_POST_FILES))
				$_FILES = $HTTP_POST_FILES;

			if(!isset($_FILES['fileUpload']))
				$error["data_file"] = "An data was not found.";

			$dataname = basename($_FILES['fileUpload']['name']);

			if(empty($dataname))
				$error["dataname"] = "The name of the data was not found.";

			if(empty($error)) {
				$newdata = "data/" . $dataname;
				//echo $newimage;
				$result = @move_uploaded_file($_FILES['fileUpload']['tmp_name'], $newdata);

					if ( empty($result) )
						$error["result"] = "There was an error moving the uploaded file.";
				}
			}
		}
		else {
			echo "no form data found";
	}
?>