I found this article: http://gertonscorner.wordpress.com/2009/03/15/fileupload-using-amfphp-remoteobject-and-flash-10/. Based on it I've made my own version, because my service is defined via service-config.xml in the way described in the documentation of amfphp, section Your first Project using Amfphp.
SERVER SIDE:
If you already know how to configure the gateway in order to reach both the service class and the value object class, here are the two classes:
ValueObject Class:
<?php
class FileVO {
public $filename;
public $filedata;
// explicit actionscript class
var $_explicitType = "remoting.vo.FileVO";
}
?>
Service class:
<?php
class RemoteFile {
/**
* Upload files!
*
* @param FileVO $file
* @return string
**/
public function upload(FileVO $file) {
$data = $file->filedata->data;
file_put_contents(UPLOAD_PATH . $file->filename, $data);
return 'File: ' . $file->filename .' Uploaded ';
}
}
?>
As you notice, we have the constant UPLOAD_PATH, which is the directory where we put the files in. The name of the file in this directory will be the one it came from the client. Of course you will need to change this, but for now is outside the scope of this example.
CLIENT SIDE:
On the client side, in the src folder of the Flex Project I build a package with the value object class, saved as ActionScrip file:
package remoting.vo
{
import flash.utils.ByteArray;
[RemoteClass(alias="FileVO")]
public class FileVO{
public var filename:String;
public var filedata:ByteArray;
public function FileVO(){
}
}
}
The component with the File Uploading:
<?xml version="1.0" encoding="utf-8"?>
<s:Group xmlns:fx="http://ns.adobe.com/mxml/2009"
xmlns:s="library://ns.adobe.com/flex/spark"
xmlns:mx="library://ns.adobe.com/flex/mx"
xmlns:net="flash.net.*">
<fx:Declarations>
<!-- Place non-visual elements (e.g., services, value objects) here -->
<net:FileReference id="fileReference"
select="select_handler(event)"
complete="complete_handler(event);"
/>
<s:RemoteObject id="ro"
destination="amfphp"
source="RemoteFile"
result="handleResult(event)"
fault="Alert.show('Error ! ')"/>
</fx:Declarations>
<fx:Script>
<![CDATA[
import mx.controls.Alert;
import mx.rpc.events.ResultEvent;
import remoting.vo.FileVO;
public function handleResult(event:ResultEvent):void{
Alert.show('the server said : ' + event.result);
}
private function btn_click(evt:MouseEvent):void {
fileReference.browse();
}
private function select_handler(evt:Event):void{
fileReference.load();
}
private function complete_handler(evt:Event):void{
var data:ByteArray = new ByteArray();
var file:FileVO;
//Read the bytes into bytearray var
fileReference.data.readBytes(data, 0, fileReference.data.length);
// Create a new FileVO instance
file = new FileVO();
file.filename = fileReference.name;
file.filedata = data;
ro.upload(file);
}
private function onEvent(evt:Event):void {
Alert.show(evt.toString(), evt.type);
}
]]>
</fx:Script>
<s:Button id="btn" label="Browse to Upload" click="btn_click(event);" />
</s:Group>
For me it works! At least on my development server. Be aware of the security hole here. You need to provide some form of protection in order to prevent any abuse.