File upload with Adobe Flex is a common asked feature for lots of applications. There are several posts on the internet to be found which explain, in detail, how to do this.
Most of these examples however uses the http protocol to transport the binary data. With the arrival of the Adobe Flash 10 player and the new FileReference features that comes with it, it is now also possible to upload a file via a RemoteObject service call.
For the coming example it is assumed that amfphp 1.9 and Flash player 10 (Flex 3.2 SDK) is installed and running. Furthermore i am using a setup as described in one of my earlier posts about RemoteObject and AMFPHP. Download PHPUpload.zip for full example code.
Copy the services contents found in the zip to your amfphp services location (and check the amfphp/globals.php if your “vo” location is configurated to “services/vo/”).
Within your services directory a RemoteFile.php can be found with a public function upload, which require a parameter of type FileVO:
require_once ('./vo/FileVO.php');
class RemoteFile {
/**
* Upload files!
*
* @param FileVO $file
* @return string
**/
public function upload(FileVO $file) {
$data = $file->filedata->data;
file_put_contents( 'uploads/' . $file->filename, $data);
return 'File: ' . $file->filename .' Uploaded ';
}
}
The FileVO php class has a Flex counterpart also called FileVO which is used as a so called RemoteClass. This RemoteClass has an attribute for the filename and filedata (ByteArray).
No we are ready to create the service class for the upload example, this class will be named RemoteFileService and extends the RemoteService super class.public class RemoteFileService extends RemoteService {
private static var phpServiceClass:String = "RemoteFile";
//constructor
public function RemoteFileService(amfChannelId:String, amfChannelEndpoint:String) {
super("remotefileService","amfphp", amfChannelId, amfChannelEndpoint);
}
// Upload function
public function upload(file:FileVO):void {
remoteObject.source = phpServiceClass;
remoteObject.upload.addEventListener(
ResultEvent.RESULT,handleRemoteMethod);
remoteObject.upload(file);
}
// Remote result handler
protected function handleRemoteMethod(event:ResultEvent):void {
var uploadStatus:String;
uploadStatus = event.result.toString();
Application.application.dispatchEvent(
new RemoteResultEvent(RemoteResultEvent.UPLOAD_STATUS, uploadStatus));
}
}
The Flex application file contains a text component (which will be filled with the selected filename), a button for selecting a file and a button to start the upload. Download PHPUpload.zip for full example code.
After a succesfull upload the selected file will be placed in the amfphp/services/uploads directory (needs write privileges!) and an Alert shows a message from the server.
[...] Fileupload using AMFPHP, RemoteObject and Flash 10 « Gerton’s Corner (tags: amf php flash flex) [...]
Thanks, just what I need!
Even though I would prefer WebORB over the no longer maintained AMFPHP.
When working with remoting to AMFPHP it’s also quite important to watch which Objectencoding you use.
.
In my experience AMFPHP can have problems registering data-types in complex objects using AMF3 (which AMF0 doesn’t), but if you want to handle ByteArrays however AMF3 seems neccessary.
I lost a good few hours figuring out why the heck my ba’s weren’t being read because of that
Just on a side note:
I no longer prefer WebORB. It seems to have a memory leak in handling byteArrays. I now prefer Zend_AMF. Actively maintained by Wade Arnold, former AMFPHP developer.
Thanks for sharing. I’m working on single file upload with Flex3 and AMFPHP
I downloaded your sample and tried, however I got 2 errors
1061: Call to a possibly undefined method load through a reference with static type flash.net:FileReference. PHPUpload.mxml line 57
1119: Access of possibly undefined property data through a reference with static type flash.net:FileReference. PHPUpload.mxml line 65
which are
refUploadFile.load(); //line57
refUploadFile.data.readBytes(data, 0, refUploadFile.data.length); //line65
respectively.
with thousands of thanks.
@Chilli
It seems you are using the wrong Flex SDK. For this to work you need a minimal SDK version of 3.2 (with Flash 10 support)
I had this exact same issue. It is that Flash 10 must be referenced. I found a guide to setting this here:
http://opensource.adobe.com/wiki/display/flexsdk/Targeting+Flash+Player+10
Hi!
I was considering this approach in my application since everything in it is handled by Zend_Amf_Server on php side and it would be a bit awkward to write special scripts to handle file uploads. But I became really concerned about memory and performance issues.
See, with this approach all the uploaded data is being accumulated in a string variable which means, as I guess, that it’s being stored in RAM. Now, I’m working on a project where video files are to be uploaded. So I guess just a few simultaneous requests can become a disaster.
I’m not really informed on this issue. In fact, looking for answers was the reason I found this page. So I might be pretty wrong. Reading a few thoughts on a subject would be very nice.
@mojojojo
I agree that this method of uploading files will increase your clients memory consumption considerably when using lots of files or very large files.
I think it will be better when you use the FileReference.upload method with some special upload scripts.
Okay ) It feels good to avoid pitfalls. I guess looking from a performance point sending byte arrays makes sense only when the recipient has to work with them as byte arrays, and even then it’s questionable.
So yes, it’s a pretty solution, but useless from a performance point.
Hi,
I used this example and I have one problem. When I upload a picture, I can see the picture and the name, but the file is empty (0kb).
Problem with byteArray?
grtz
Matthias
whats the point, if the users dont have flash 10