Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

In ColdFusion, how can I extract and store the contents of the submitted form?

I'm writing an application in ColdFusion, and even though it is mostly stable, it errors every so often. Because it has replaced the old application already, sometimes it is the users who get errors instead of me.

I've created a nice page that people get when they get an error that sends information to me, such as error, referrer, error on which page, line number, etc.

The only thing I can't get to seem to work is getting the form data submitted if there is any. I don't know what page it errored on beforehand, so I can't just output '#form.field#'.

For example if:

form.abc = 1
form.def = 2

How can i get the variable names and value from 'form' without knowing them beforehand?

Is this document on looping over a structure somewhere along the right path?

Also, I'm looking for a good way to store that data in a database, because that is where the other information about the error is stored, and I don't really want to have to put it in an email to me.

like image 298
Davis Avatar asked Dec 04 '22 16:12

Davis


1 Answers

The Form scope has a FieldNames variable which will tell you what fields were submitted.

You can also do StructKeyList(Form) to get a list of the current variables in the scope. This one will also include FieldNames and any other variables that have since been added to the Form scope.

Either of these could be used inside a <cfloop index="CurField" list="#StructKeyList(Form)#"> - but there are easier ways...


If you are on CF8 you can convert the scope to a string nice and easily with serializeJson() and deserializeJson() functions, which could then be stored in a suitable database field.

If you're on CF6..7 then you can download a CFC called cfjson from riaforge which mimics these functions.


Finally, if you're on earlier versions of CF, or have an odd aversion to using JSON for storage, you can roll your own with an even simpler loop to the one hinted above - a collection loop lets you loop directly through a Structure or Scope - note that some annoying person picked 'item' rather than 'index' as the attribute for these.

Since we know Form variables are all simple objects (i.e. strings) I've elected for a basic key=value[newline]key=value[newline]... format, which is easy to reverse also.

Encoding:

<cfset Output = '' />
<cfloop item="CurField" collection="#Form#">
    <cfset Output = Output & CurField & '=' & Form[CurField] & Chr(10) />
</cfloop>

<cfoutput>#Output#</cfoutput>

Decoding:

<cfset FormData = StructNew()/>
<cfloop index="CurLine" list="#Output#" delimiters="#Chr(10)#">
    <cfset FormData[ListFirst(CurLine,'=')] = ListRest(CurLine,'=') />
</cfloop>

<cfdump var="#FormData#"/>


One last important note: As with all user-supplied variables (Form,Url,Cookie scopes) you must make sure you handle them correctly to prevent security holes - specifically make sure you are using cfqueryparam for all your database queries - don't want to sidetrack too far, but feel free to ask another question if you need any help with cfqueryparam.


Hope this helps. :)

like image 79
Peter Boughton Avatar answered Dec 26 '22 01:12

Peter Boughton