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

I am writing an application in ColdFusion, and although it is mostly stable, it is so often mistaken. Since it has already replaced the old application, sometimes users get errors instead of me.

I created a good page that people get when they receive an error message that sends me information, such as error, referrer, which page error, line number, etc.

The only thing I can not get to work is to get the form data, if any. I donโ€™t know which page he made a mistake in advance, so I canโ€™t just output '# form.field #'.

For example, if:

form.abc = 1 form.def = 2 

How can I get variable names and values โ€‹โ€‹from a "form" without knowing them in advance?

Is this document cycling through a structure somewhere along the right path?

In addition, I am looking for a good way to store this data in a database, because other error information is stored there, and I really do not want it to be placed in an e-mail.

+4
source share
5 answers

The form area has a FieldNames variable that tells you which fields were submitted.

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

Any of them can be used inside <cfloop index="CurField" list="#StructKeyList(Form)#"> , but there are simpler ways ...


If you are on CF8, you can easily and easily convert a region to a string using the serializeJson() and deserializeJson() functions, which can then be stored in the corresponding database field.

If you are on CF6..7, you can download a CFC called cfjson from riaforge , which mimics these features.


Finally, if you use earlier versions of CF or have a strange aversion to using JSON for storage, you can flip your own with an even simpler loop into one of the above - the collection loop allows you to directly scroll through the Structure or Region - note that which an annoying person chose an "element" rather than an "index" as an attribute for them.

Since we know that form variables are all simple objects (i.e. strings) that I have chosen for the basic format key=value[newline]key=value[newline]... which is also easy to undo.

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#"/> 


Last important note. Like all user-defined variables (Form, Url, Cookie scopes), you need to make sure that they are handled correctly to prevent security holes - especially make sure that you use cfqueryparam for all database queries - do not want to loop too much, but Feel free to ask another question if you need help with cfqueryparam.


Hope this helps. :)

+7
source

If you want to manually iterate over all form fields, the easiest way is cfloop:

 <cfloop collection="#form#" item="variables.name"> #variables.name#=(#form[variables.name]#)<br/> </cfloop> 

But this says that for error email purposes, it will probably be easier for you to simply โ€œresetโ€ the form area (which is just a special structure), for example:

 <cfmail from=" errors@ #cgi.server_name#" to=" you@yourdomain.com " subject="Error Occurred in such and such a place" type="html"> <cfdump var="#form#"/> </cfmail> 

When sending error messages, I like to include a second cfdump for the CGI area (again, only a special structure), as this may provide some other useful information about the request.

If you have CF 8, you might also want to dump in text format, for example, the following, because it will reduce the size of the message (and, in my opinion, will make the message more readable)

 <cfdump var="#form#" format="text"> 

Note. The format attribute of the CFDump tag was added for CF 8, so you cannot use it in previous versions of ColdFusion.

You mentioned that you were looking for a way to store these errors in a database, and that is a good idea. Instead of rolling your own solution for this, I suggest you check out BugLogHQ . It has been a while and works well for others, including me, and best of all it is FREE and Open Source. This age and widespread use means that it will be less likely to have errors in its own code and probably has more and better features than what you write.

Using BugLogHQ, you donโ€™t have to worry about displaying the error, you just send data to the error log and take care of everything else.

+4
source

Form is just a hash / structure, so you can just iterate over your keys:

 <cfoutput> <cfloop collection=#form# item="field"> #htmleditformat(field)=#htmleditformat(form[field])#<br/> </cfloop> </cfoutput> 

Entering data into a database? How you do it depends on what you want to do with it later. The most flexible solution may simply be to convert the entire Form (and url ) to a WDDX object and save it in the blob field:

 <cfwddx action="cfml2wddx" input=#url# output="encodedURL"/> <cfwddx action="cfml2wddx" input=#form# output="encodedForm"/> <cfquery datasource="yourDSN"> INSERT INTO errorlog (datestamp, event, script_name, path_info, url, form) VALUES (<cfqueryparam value=#now()# cfsqltype="CF_SQL_TIMESTANP"/>, <cfqueryparam value="your error string or cfcatch data" cfsqltype="CF_SQL_VARCHAR"/>, <cfqueryparam value=#cgi.script_name# cfsqltype="CF_SQL_VARCHAR"/>, <cfqueryparam value=#cgi.path_info# cfsqltype="CF_SQL_VARCHAR"/>, <cfqueryparam value=#encodedURL# cfsqltype="CF_SQL_BLOB"/>, <cfqueryparam value=#encodedForm# cfsqltype="CF_SQL_BLOB"/>) </cfquery> 

Thus, you will have access to all raw data for analysis at your leisure. Of course, there are many other ways to do this.

+3
source

if you use Application.cfc in your application, just replace the onError method with the one below. Note. Application.settings.mode can be one of the following values โ€‹โ€‹(dev, test, prod). application.settings.webmasteremail must be set to the email address to which you want to send error information. Both of these variables must be set in the onApplicationStart method.

What does this function do? If the application is set to "dev" mode (by setting application.settings.mode = "dev"), it will display the error information on the screen. If the application is configured for any other mode (for example, test or prod), it will send an e-mail and save the information in the database.

 <cffunction name="onError" returnType="void" output="true"> <cfargument name="exception" required="true"> <cfargument name="eventname" type="string" required="true"> <!--- corrects bug where <cfabort> throw an error ---> <cfif arguments.exception.rootCause eq "coldfusion.runtime.AbortException"> <cfreturn> </cfif> <cfsavecontent variable="errordata"> <p>#eventname#</p> <cfdump var="#exception#" label="Exception Information" format="text"> <cfdump var="#url#" label="URL Information" format="text"> <cfdump var="#form#" label="FORM Information" format="text"> <cfdump var="#application#" label="Application Scope" format="text"> <cfif isdefined("session")> <cfdump var="#session#" label="Session Scope" format="text"> </cfif> <cfif isdefined("client")> <cfdump var="#client#" label="Client Scope" format="text"> </cfif> <cfdump var="#cgi#" label="URL Information" format="text"> </cfsavecontent> <!--- will email the error inforation and display the error page ---> <cfif application.settings.mode eq "dev"> <p>#eventname#</p> #errordata# <cfelse> <cfmail to="#application.settings.webmasteremail#" from=" error@ #cgi.http_host#" subject="Error has occured on #cgi.http_host#" type="HTML" charset="windows-1252"> <p>#eventname#</p> #errordata# </cfmail> <cfquery datasource="yourDSN"> insert into errorlog ( creationdate ,event ,info ) values ( <cfqueryparam value="#now()#" cfsqltype="CF_SQL_TIMESTAMP"/> ,<cfqueryparam value="#eventname#" cfsqltype="CF_SQL_VARCHAR"/> ,<cfqueryparam value="#errordata#" cfsqltype="CF_SQL_LONGVARCHAR"/> ) </cfquery> <h2>A functional error has occurred.</h2> <p>A notification of this error has been automatically e-mailed to the development team; no action on your part is required.</p> <p>Please click the "back" button on your browser to return to the web site. We apologize for this inconvenience.</p> </cfif> </cffunction> 
+3
source

If you email your form variables, simply reset them like this:

 <cfmail type="html" ...> <cfdump var="#form#" label="form"> <cfdump var="#cgi#" label="cgi"> <cfdump var="#session#" label="session"> </cfmail> 

You can reset all the areas you need. You may or may not need those I have provided.

You said that your original problem was that the application replaces the old application? Are you developing on the same server you are deploying to? If so, you can simply change the application name for your development copy - make sure the names are unique to avoid this problem (if that is your problem).

0
source

All Articles