Relax Breath of Solution.Community tech blog of Sameera Thilakasiri - Consultant UI, UX, RWD Specialist/ Interactive Designer

Just I wanted.. Do you?…

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 tag which containted a boolean value, followed by data or, in the case of false in the success tag, nodes with specific errors to report.

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>


Author
Sameera Thilakasiri By Sameera Thilakasiri
,is a front-end developer based in Colombo, is a blogger and a lifestyle photographer.
Follow him Twitter and Google+. Check out him.

Comments

One Response to “File Uploads with PHP and Flex”

  1. Sameera Sandaruwan
    March 10th, 2010 @ 10:21 pm

    If it is run time error? or attachment error?

Leave a Reply

You must be logged in to post a comment.