File Uploads with PHP and Flex
Posted on February 11, 2010 | 1 Comment
Structure
The PHP scripts used in our Flex applications for file uploads are semi-modular. They are based on switch statements which evaluate the variable “request.” We found this to be a simple and effective way to manage communication between the Flex application and the server. For example, if we had a “user.php” page, and wanted to add a new user to our database, we would make a “case ‘add'” in our switch statement, and inserted the code for processing a database request.
Feedback
We also soon found that it was important to have good communication between Flex and the server so we could prevent and debug errors efficiently. We did this by creating a function that ran at the end of every page to construct an XML that contained the feedback for Flex. The XML structure was very generic, including a
Example
Here’s an example PHP that could be used in the Flex application to upload a file:
<?php $errors = array(); $data = ""; $success = "false"; function return_result($success,$errors,$data) { echo("<?xml version=\"1.0\" encoding=\"utf-8\"?>"); ?> <results> <success><?=$success;?></success> <?=$data;?> <?=echo_errors($errors);?> </results> <? } function echo_errors($errors) { for($i=0;$i<count($errors);$i++) { ?> <error><?=$errors[$i];?></error> <? } } switch($_REQUEST['action']) { case "upload": $file_temp = $_FILES['file']['tmp_name']; $file_name = $_FILES['file']['name']; $file_path = $_SERVER['DOCUMENT_ROOT']."/myFileDir"; //checks for duplicate files if(!file_exists($file_path."/".$file_name)) { //complete upload $filestatus = move_uploaded_file($file_temp,$file_path."/".$file_name); if(!$filestatus) { $success = "false"; array_push($errors,"Upload failed. Please try again."); } } else { $success = "false"; array_push($errors,"File already exists on server."); } break; default: $success = "false"; array_push($errors,"No action was requested."); } return_result($success,$errors,$data); ?>
<?xml version="1.0" encoding="utf-8"?> <mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute" creationComplete="initApp()"> <mx:Script> <![CDATA[ /* Examples_FileUpload Written by: Dustin Andrew dustin@flash-dev.com www.flash-dev.com */ import mx.states.*; import mx.controls.*; import mx.managers.*; import mx.events.*; import flash.events.*; import flash.net.*; private const _strUploadDomain:String = "http://codycodingcowboy.cahlan.com/"; private const _strUploadScript:String = _strUploadDomain + "files/upload.php"; private var _arrUploadFiles:Array; private var _numCurrentUpload:Number = 0; private var _refAddFiles:FileReferenceList; private var _refUploadFile:FileReference; private var _winProgress:winProgress; private function initApp():void { Security.allowDomain("*"); _arrUploadFiles = new Array(); } // Called to add file(s) for upload private function addFiles():void { _refAddFiles = new FileReferenceList(); _refAddFiles.addEventListener(Event.SELECT, onSelectFile); _refAddFiles.browse(); } // Called to remove selected file(s) for upload private function removeFiles():void { var arrSelected:Array = listFiles.selectedIndices; for (var i:Number = 0; i < arrSelected.length; i++) { _arrUploadFiles[Number(arrSelected[i])] = null; } for (var j:Number = 0; j < _arrUploadFiles.length; j++) { if (_arrUploadFiles[j] == null) { _arrUploadFiles.splice(j, 1); j--; } } listFiles.dataProvider = _arrUploadFiles; listFiles.selectedIndex = 0; if (_arrUploadFiles.length == 0) { btnUpload.enabled = false; } else { btnUpload.enabled = true; } } // Called when a file is selected private function onSelectFile(event:Event):void { var arrFoundList:Array = new Array(); // Get list of files from fileList, make list of files already on upload list for (var i:Number = 0; i < _arrUploadFiles.length; i++) { for (var j:Number = 0; j < _refAddFiles.fileList.length; j++) { if (_arrUploadFiles[i].label == _refAddFiles.fileList[j].name) { arrFoundList.push(_refAddFiles.fileList[j].name); _refAddFiles.fileList.splice(j, 1); j--; } } } if (_refAddFiles.fileList.length >= 1) { for (var k:Number = 0; k < _refAddFiles.fileList.length; k++) { _arrUploadFiles.push({label:_refAddFiles.fileList[k].name, data:_refAddFiles.fileList[k]}); } listFiles.dataProvider = _arrUploadFiles; listFiles.selectedIndex = _arrUploadFiles.length - 1; } if (arrFoundList.length >= 1) { Alert.show("The file(s): \n\n• " + arrFoundList.join("\n• ") + "\n\n...are already on the upload list. Please change the filename(s) or pick a different file.", "File(s) already on list"); } if (_arrUploadFiles.length == 0) { btnUpload.enabled = false; } else { btnUpload.enabled = true; } } // Cancel and clear eventlisteners on last upload private function clearUpload():void { _numCurrentUpload = 0; _refUploadFile.removeEventListener(ProgressEvent.PROGRESS, onUploadProgress); _refUploadFile.removeEventListener(Event.COMPLETE, onUploadComplete); _refUploadFile.removeEventListener(IOErrorEvent.IO_ERROR, onUploadIoError); _refUploadFile.removeEventListener(SecurityErrorEvent.SECURITY_ERROR, onUploadSecurityError); _refUploadFile.cancel(); } // Called to upload file based on current upload number private function startUpload(booIsFirst:Boolean):void { if (booIsFirst) { _numCurrentUpload = 0; } if (_arrUploadFiles.length > 0) { _winProgress = winProgress(PopUpManager.createPopUp(this, winProgress, true)); _winProgress.btnCancel.removeEventListener("click", onUploadCanceled); _winProgress.btnCancel.addEventListener("click", onUploadCanceled); _winProgress.title = "Uploading file to " + _strUploadDomain; _winProgress.txtFile.text = _arrUploadFiles[_numCurrentUpload].label; _winProgress.progBar.label = "0%"; PopUpManager.centerPopUp(_winProgress); // Variables to send along with upload var sendVars:URLVariables = new URLVariables(); sendVars.action = "upload"; var request:URLRequest = new URLRequest(); request.data = sendVars; request.url = _strUploadScript; request.method = URLRequestMethod.POST; _refUploadFile = new FileReference(); _refUploadFile = _arrUploadFiles[_numCurrentUpload].data; _refUploadFile.addEventListener(ProgressEvent.PROGRESS, onUploadProgress); _refUploadFile.addEventListener(Event.COMPLETE, onUploadComplete); _refUploadFile.addEventListener(IOErrorEvent.IO_ERROR, onUploadIoError); _refUploadFile.addEventListener(SecurityErrorEvent.SECURITY_ERROR, onUploadSecurityError); _refUploadFile.upload(request, "file", false); } } // Called on upload cancel private function onUploadCanceled(event:Event):void { PopUpManager.removePopUp(_winProgress); _winProgress == null; _refUploadFile.cancel(); clearUpload(); } // Get upload progress private function onUploadProgress(event:ProgressEvent):void { var numPerc:Number = Math.round((Number(event.bytesLoaded) / Number(event.bytesTotal)) * 100); _winProgress.progBar.setProgress(numPerc, 100); _winProgress.progBar.label = numPerc + "%"; _winProgress.progBar.validateNow(); if (numPerc > 90) { _winProgress.btnCancel.enabled = false; } else { _winProgress.btnCancel.enabled = true; } } // Called on upload complete private function onUploadComplete(event:Event):void { _numCurrentUpload++; PopUpManager.removePopUp(_winProgress); if (_numCurrentUpload < _arrUploadFiles.length) { startUpload(false); } else { Alert.show("File(s) have been uploaded.", "Upload successful"); } } // Called on upload io error private function onUploadIoError(event:IOErrorEvent):void { Alert.show("IO Error in uploading file.", "Error"); PopUpManager.removePopUp(_winProgress); _winProgress == null; _refUploadFile.cancel(); clearUpload(); } // Called on upload security error private function onUploadSecurityError(event:SecurityErrorEvent):void { Alert.show("Security Error in uploading file.", "Error"); PopUpManager.removePopUp(_winProgress); _winProgress == null; _refUploadFile.cancel(); clearUpload(); } ]]> </mx:Script> <mx:Canvas top="10" bottom="10" left="10" right="10"> <mx:Panel width="300" height="266" layout="absolute" horizontalCenter="0" verticalCenter="0" id="panUpload" title="Select file(s) for upload"> <mx:VBox left="10" bottom="10" top="10" right="10"> <mx:List width="100%" id="listFiles" height="100%" allowMultipleSelection="true"/> <mx:HBox width="100%" horizontalAlign="center"> <mx:Button label="Add file(s).." id="btnAdd" click="addFiles()"/> <mx:Button label="Remove file(s)" id="btnRemove" click="removeFiles()"/> </mx:HBox> </mx:VBox> <mx:ControlBar horizontalAlign="right"> <mx:Button label="Upload file(s)" id="btnUpload" click="startUpload(true)" enabled="false"/> </mx:ControlBar> </mx:Panel> </mx:Canvas> </mx:Application>
Comments
One Response to “File Uploads with PHP and Flex”
Leave a Reply
You must be logged in to post a comment.
March 10th, 2010 @ 10:21 pm
If it is run time error? or attachment error?