Skip to main content
November 23, 2010
Question

Form File Upload Function

  • November 23, 2010
  • 2 replies
  • 1534 views

This seems like a dumb question, but I am on a tight deadline and don't have a ton of time to muck around trying to figure it out.

Building a form which takes up to 4 images to upload. The form gets passed to a function that is supposed to handle the image uploading.Problem is, when a form filed gets passed to a function, it doesn't seem to be valid any longer. Like all the examles you see online just have the cffile line and the form all on the same page, no functions involved. So now when I try to have a function handle the uploading, I get errors like

The form field arguments.image did not contain a file.

C:\ColdFusion9\runtime\servers\coldfusion\SERVER-INF\temp\wwwroot-tmp\neotmp3794510969991376318.tmp

The calls to the image uploader function look like

               <!--- Handle File Uploads ---->
               <cfif structKeyExists(form, "image1")>
                    <cfset returnStruct.image1 = uploadImage(form.image1)>
               </cfif>

               <cfif structKeyExists(form, "image2")>
                    <cfset returnStruct.image2 = uploadImage(form.image2)>
               </cfif>

               <cfif structKeyExists(form, "image3")>
                    <cfset returnStruct.image3 = uploadImage(form.image3)>
               </cfif>

               <cfif structKeyExists(form, "image4")>
                    <cfset returnStruct.image4 = uploadImage(form.image4)>
               </cfif>

The upload image function looks like

     <cffunction name="uploadImage" access="private" returntype="struct" description="Upload a given image">
          <cfargument name="image" type="any" required="yes">

          <cfset var returnstruct = structnew()>
          <cfset returnStruct.message = "function ran successfully">
          <cfset returnstruct.success = true>          
          <cfset returnStruct.file = arguments.image>
          
          <cftry>
                    
               <cfset destination = expandPath("./files")>
               
               <cfif not directoryExists(destination)>
                    <cfdirectory action="create" directory="#destination#">
               </cfif>
     
               <cffile action="upload" filefield="arguments.image" destination="#destination#" nameConflict="makeUnique" result="upload">
               <cfset returnStruct.uploadResult = upload>
               
               <cfset returnStruct.newName = createUUID()&serverFileExt>
               <cffile action="rename" destination="#destination##returnStruct.newName#" source="#destination##serverFileName##serverFileExt#" >
             
               <cfcatch type="any">
                    <cfset returnStruct.message = cfcatch.message>
                    <cfset returnstruct.success = false>                
            </cfcatch>   
        </cftry>
          
          <cfreturn returnStruct>          
     </cffunction>

Any thoughts on what I'm doing wrong?

    This topic has been closed for replies.

    2 replies

    pete_freitag
    Participating Frequently
    November 23, 2010

    Try passing the name of the form field, instead of the actual variable, eg uploadImage("image1")

    Also from a security perspective you need to make sure users can't upload cfm files, or other dangerious file types, so there are a few things I would do to improve that:

    1) Don't upload under the webroot (use getTempDirectory() first, then validate the file type)

    2) Always check the uploaded file extension and match it against a list of allowed types.

    Here's a blog entry I wrote with some more upload tips:

    http://www.petefreitag.com/item/701.cfm

    November 23, 2010

    Thanks guys, I'll give it a whack and let you know how it goes.

    I know I shouldn't be storing files in the web root, but this site is going in a shared hosting environment, so I am unsure where outside my site folder I'll be able to store the files. I've never done a site for a shared hosting setup before so i'm kinda at a loss for exactly how I'll do that. I will add some file type proection though. My form fields to have accept filters on them, and I'll make sure the files that get uploaded are infact of the image type.

    pete_freitag
    Participating Frequently
    November 23, 2010

    You're Welcome... Yes it is tricky to do on a shared host, they may not allow you to write to the getTempDirect

    ory() your best bet in that case is, if they let you, create a folder above the web root to use that.

    cfjedimaster
    Inspiring
    November 23, 2010

    When you use cffile to upload a file, the value of fielfield is the

    name of the form field. You passed it the value and then ignored it

    and used arguments.image instead. What you want to do is

    a) pass the form field name as a string

    b) use that in your cffile tag literally:

    <cffile action="upload" filefield="#arguments.image#"

    destination="#destination#" nameConflict="makeUnique" result="upload"

    cfjedimaster
    Inspiring
    November 23, 2010

    The damn forum 'ate' my first code sample. It was:

    <cfset returnStruct.image4 = uploadImage("image4")>