2

I need to loop over a set of image paths to grab, resize and store images from external destinations to S3.

I'm used to calling cfcs to do this like so:

<cfinvoke component="form_img_handler" method="upload" returnvariable="imgSuccess">
    <cfinvokeargument name="command" value="upload_search"/>
    <cfinvokeargument name="imgPath" value="#results.bildpfad #"/>
    <cfinvokeargument name="imgFile" value="#results.bilddateiname#"/>
    <cfinvokeargument name="sellerILN" value="#results.iln#"/>
    <cfinvokeargument name="cookie" value="#variables.screenWidth#"/>
</cfinvoke>

Question:
If I have to do this 25x, in a loop, would it be better to use cfobject instead of cfinvoke? From what I understand cfinvoke gets instantiated, runs its job and perishes. While cfobjects are there to stay. If so, would it better in the above case to use cfobject? If so, how would I call my upload function (passing parameters) and how do I remove the object once I'm done?

(never used cfobject before...)

Thanks for help!

Leigh
  • 28,765
  • 10
  • 55
  • 103
frequent
  • 27,643
  • 59
  • 181
  • 333
  • 1
    You *can* reuse objects with `cfinvoke`. You just do not see many examples of it. That said, the cfinvoke syntax is too bulky for my tastes :) I prefer Cody and Peter's approach. – Leigh Aug 24 '12 at 19:04

2 Answers2

10

Neither, use something like...

Outside loop (possibly in global scope, e.g. Application):

<cfset form_img_hander = createObject('component','dotted.path.to.form_img_hander') />
or
<cfset form_img_hander = new dotted.path.to.form_img_hander() />

Inside loop:

<cfset imgSuccess = form_img_handler.upload
    ( command   = "upload_search"
    , imgPath   = results.bildpfad
    , imgFile   = results.bilddateiname
    , sellerILN = results.iln
    , cookie    = variables.screenWidth
    )/>

Because it's far more readable.


You don't have a performance problem, unless you have a repeatable test-case which proves that you have a performance problem.


Regarding removing objects...
If you're not placing objects in a persistent scope, you don't need to worry about removing them - they are only tied to the request and once the request has ended they will be garbage collected as required.

If you are placing objects in a persistent scope, you probably still don't need to worry about removing them, but if you determine that you do, you can use StructDelete to remove it (just like any other variable). Of course, you should be careful not to do that whilst it's needed.

Peter Boughton
  • 110,170
  • 32
  • 120
  • 176
  • So, if I do this in application scope, I'd set application.form_img_hander = ... What happens if more than one user initiates the `upload`? Will these run sequentially or simultaneously? Would it be different if I set the object in Session scope? – frequent Aug 24 '12 at 19:39
  • 2
    That depends on the logic inside the component. Make sure variables are scoped correctly, you avoid conflicting filenames, and so on, and it'll work fine with simultaneous users. – Peter Boughton Aug 24 '12 at 19:42
  • ok. so inside my cffunction, I'm declaring var LOCAL = {} and in it I'm storing everyting I need (LOCAL.xyz = "value" ) including the arguments passed. Should be ok, shouldn't it? – frequent Aug 24 '12 at 19:45
4

Instantiate your object using CreateObject and assign it to a variable:

<cfset handler = CreateObject("component", "form_img_handler")>
<cfset handler.upload(URL.command, URL.imgPath ... )>

You can call the 2nd line in a loop after you've instantiated the object once.

Cody Caughlan
  • 32,456
  • 5
  • 63
  • 68