OK, here we go =)
But, anyway, you'll have to read the manual, to understand what's going on here =)
PHP first, that's simple =)
This is the page we will use to communicate with Flash app. Notice, sending XMLs not encoded in UTF-8 may be a headache, so, make sure you save php files in UTF-8 encoding, mbstring library is installed with your PHP, and if you need SQL to communicate with these pages, the SQL is also properly set to read names and strings in UTF-8.
This page, once requested will create an instance of PostXML class, which will parse the data sent from Flash.
<?php
mb_internal_encoding("UTF-8");
mb_regex_encoding("UTF-8");
mb_http_output("UTF-8");
ob_start("mb_output_handler");
require_once("includes/postxml.inc");
$rec = new PostXML();
$bom = "\xEF\xBB\xBF";
$xml = fopen("log.xml", "w+");
fwrite($xml, $bom . $rec->toString());
print $bom . $rec->toString();
?>
This is includes/postxml.inc (PostXML class) it parses the data from $GLOBALS["HTTP_RAW_POST_DATA"] into DOM structure, so that later you'll be able to deal with wellstructured data rather than strings/arrays.
<?php
class PostXML extends DOMDocument {
private $src;
function __construct() {
parent::__construct("1.0", "utf-8");
if(isset($GLOBALS["HTTP_RAW_POST_DATA"])){
$this->src = trim($GLOBALS["HTTP_RAW_POST_DATA"]);
$sxml = simplexml_load_string($this->src);
$dxml = $this->importNode(dom_import_simplexml($sxml), true);
$this->appendChild($dxml);
} else {
$nodata = $this->appendChild($this->createElement("noData"));
$nodata->appendChild($this->createTextNode("No data posted!"));
}
}
/**
* @return string
*/
function toString() {
$this->formatOutput = true;
return $this->saveXML();
}
}
?>
This is the Document class for our Flash sending app.
It instantiates SimpleSender class and uses it's sendXML() method to communicate to our PHP page.
/**
* ...
* @author wvxvw
*/
package
{
import flash.display.Sprite;
import org.wvxvw.phputils.SimpleSender;
import org.wvxvw.phputils.SimpleSenderEvent;
public class TestSender extends Sprite
{
public var sender:SimpleSender;
public var serverPage:String = 'http://localhost/flashtest/receiver.php';
public var xmlToSend:XML =
<data>
<testNode testAttribute="foo"/>
<testTextNode>
Test text
</testTextNode>
<![CDATA[
test CDATA section
]]>
</data>;
public function TestSender()
{
sender = new SimpleSender();
sender.addEventListener(SimpleSenderEvent.LOAD_SUCCESS, handleLoadSuccess);
sender.addEventListener(SimpleSenderEvent.LOAD_ERROR, handleLoadError);
sender.loadXML(xmlToSend, serverPage);
}
public function handleLoadSuccess(evt:SimpleSenderEvent):void
{
trace(evt.xml.toXMLString());
}
public function handleLoadError(evt:SimpleSenderEvent):void
{
trace(evt.xml.toXMLString());
}
}
}
The SimpleSender class: converts string representation of the given XML to binary sends it where we tell it and dispatches events when something happens to our request:
/**
* ...
* @author wvxvw
*/
package org.wvxvw.phputils
{
import flash.events.EventDispatcher;
import flash.events.Event;
import flash.events.IOErrorEvent;
import flash.events.SecurityErrorEvent;
import flash.net.URLLoader;
import flash.net.URLRequest;
import flash.net.URLLoaderDataFormat;
import flash.net.URLRequestMethod;
import flash.net.URLRequestHeader;
import flash.utils.ByteArray;
import flash.utils.Endian;
import org.wvxvw.phputils.SimpleSenderEvent;
public class SimpleSender extends URLLoader
{
private static const IO_ERROR:XML = <ioError url=""/>;
private static const SECURITY_ERROR:XML = <securityError message=""/>;
private static const PARSING_ERROR:XML = <parsingError/>;
private var _source:String;
private var _sourceBytes:ByteArray;
private var _request:URLRequest;
private var _header:URLRequestHeader = new URLRequestHeader('Content-Type', 'application/octet-stream');
public function SimpleSender()
{
super();
super.dataFormat = URLLoaderDataFormat.BINARY;
this.addEventListener(Event.COMPLETE, dipatchCompete);
this.addEventListener(IOErrorEvent.IO_ERROR, dispatchIOError);
this.addEventListener(SecurityErrorEvent.SECURITY_ERROR, dispatchSecurityError);
}
override public function load(request:URLRequest):void
{
return;
}
/**
* @param xml : XML to be sent to the server page
* @param receiver : server page URL
*/
public function loadXML(xml:XML, receiver:String):void
{
var i:Boolean = XML.prettyPrinting;
_request = new URLRequest(receiver);
_request.requestHeaders.push(_header);
_request.method = URLRequestMethod.POST;
XML.ignoreWhitespace = true;
XML.prettyPrinting = false;
_source = xml.toXMLString();
XML.prettyPrinting = i;
_sourceBytes = new ByteArray();
_sourceBytes.writeUTFBytes(_source);
_sourceBytes.position = 0;
_request.data = _sourceBytes;
super.load(_request);
}
private function dipatchCompete(evt:Event):void
{
var xl:XML;
var str:String = this.data;
try {
xl = XML(this.data);
dispatchEvent(new SimpleSenderEvent(SimpleSenderEvent.LOAD_SUCCESS, xl));
} catch (e:Error) {
this.data = PARSING_ERROR.copy();
this.data.replace(0, '<![CDATA[' + str + ']]>');
dispatchEvent(new SimpleSenderEvent(SimpleSenderEvent.LOAD_SUCCESS, XML(this.data)));
}
}
private function dispatchIOError(evt:IOErrorEvent):void
{
this.data = IO_ERROR.copy();
this.data.@url = evt.toString().match(/[^\s]+:\/\/[^\"]+/g)[0];
dispatchEvent(new SimpleSenderEvent(SimpleSenderEvent.LOAD_ERROR, XML(this.data)));
}
private function dispatchSecurityError(evt:SecurityErrorEvent):void
{
this.data = SECURITY_ERROR.copy();
this.data.@message = evt.errorID;
dispatchEvent(new SimpleSenderEvent(SimpleSenderEvent.LOAD_ERROR, XML(this.data)));
}
}
}
This is the event SimpleLoader may dispatch, it may tell you that error happened during request-responce process or just deliver XML the Sender received back from PHP.
/**
* ...
* @author wvxvw
*/
package org.wvxvw.phputils
{
import flash.events.Event;
public class SimpleSenderEvent extends Event
{
public static const LOAD_SUCCESS:String = 'loadSuccess';
public static const LOAD_ERROR:String = 'loadError';
public var xml:XML;
public function SimpleSenderEvent(type:String, xl:XML)
{
super(type);
xml = xl;
}
public override function clone():Event
{
return new SimpleSenderEvent(type, xml);
}
public override function toString():String
{
return formatToString('SimpleSenderEvent', 'type', 'xml');
}
}
}