February 24, 2009

Application.cfm vs. Application.cfc

Application.cfm vs. Application.cfc

Many people who are using ColdFusion MX +, are unaware of the benefits of the Application.cfc pages, so have not used them. I will endeavor to explain how an Application.cfc page can be a tremendous boon to any Enterprise level website.

Imagine this. Everytime you open a page on your website, the Application page is run.

On the Application.cfm page, each line is run in sequence every time. If you load many APPLICATION variables or SESSION variables or other ‘environment’ variables, then you are recreating them, every time you open a page on the server. This is a lot of work for the CF server and can cause slowages on even the smallest websites.

On the Application.cfm page, only the code that is necessary is run.
Examples:
These 3 sections are common sections in an Application.cfc page.

  1. onApplicationStart
  2. onSesssionStart
  3. onRequestStart

The ‘application start’ is the first time an application (the website) is run on the server, or after it has timed out. Therefore the code in the onApplicationStart section will only run at the time the website runs for the first time on the server, or after a timeout. (or reboot of the server)

The ‘session start’ is the first time a unique web browser visits an application (the website), or after the session cookies have been erased. Therefore the code in the onSessionStart section will only run at the time a web browser starts its progress through your site.

The ‘request start’ is every time a page is called on the web server. Therefore the code in the onRequestStart will always run when a new page is requested (or a page is ‘refreshed’)

There are many possible sections on the ‘Application.cfc’ page, but the above are the most common. Hopefully you can see how a cfc can severly reduce the stress on a coldfusion server.

Let’s say that you have large language files that you load into the system in order to easily change from one language to another. In the past you might have called these variables lang.welcome = ‘Welcome’. Well, you could place these language files in the application.cfc – onApplicationStart section, and only load them when the application starts. This would reduce the overhead of lines of code that was needed to start each page.
You could make that into a structure:
Application.lang[‘en’].welcome = ‘Welcome’;
Then in the onRequestStart you can change the ‘session.lang’ variable based on the most recent choice of the user, and call each variable in this manner.
Application.lang[session.lang].welcome.

This would make it so that you would only load the multitude of line of code that describe the language variables into the application scope once, but be able to call the values on each page load.

With an Application.cfm page, you would have to load each language file every single time you loaded the page.

The benefits don’t stop there. There are a few additional ‘sections’ of an Application.cfc page that can benefit ColdFusion developers.

onError is used to capture page errors and deal with them in any fashion that the developer sees fit. This is a huge advance over the limitations of the <cferror> tag.

The onMissingTemplate section can be used to capture requests for ‘.cfm’ pages that don’t exist (or no longer exist) on your site. I have used this in the past to show a brief ‘page not found’ error to the user, then display a search result of possible matches to what the user ‘might’ have been looking for. Certainly a whole lot better than the static ‘dead end’ page that apache or IIS want to show the user.

I encourage you to have some fun testing and experimenting with the different sections of the Application.cfc page, only a few of the sections are listed here.

February 15, 2008

Knowledgebase - File Uploading

Knowledgebase - File Uploading

On the boards, I often get questions regarding file uploads. Usually these questions display a lack of knowledge about how a file is treated, and therefore sent, to the server. I have included here a brief tutorial that I hope will help the new programmer in understanding what is happening to the file as it travels from the user's computer to your server.

First off, the form page.
Try this simple form:
<form method="post" action="getfile.cfm" enctype="multipart/form-data">
<input type="file" name="uploadfile" size="40" />
<input type="submit" name="submit" value="Send the File Off" />
</form>
As you can see, this form is extremely simple. On a real upload page you would want at minimum some instructions to the user as well as a description of what this page will be doing.

When a user fills out the form in their local browser and clicks on the submit button, the file will be sent automatically from the user's computer to your server. In the 'form' tag above, the 'method=post' tells the form to send all information in as a 'post' form (not as part of the url string). The 'action' parameter tells the form which page to load after the form is submitted. The 'enctype=multipart/form-data' tells the form that there is a file attached to the form that needs to be sent to the server (without this, the file will not be received by the server at all).

So, here are the steps so far:
  1. The user opens your 'uploadfile.html' page in their browser. (You could have called this page anything 'upload.cfm', 'uf.html', etc)
  2. The user clicks on the 'browse button' in the form and chooses which file on their local computer to send to your server.
  3. The user clicks on the 'submit' button.
  4. The file is sent with the form to your server
  5. Your web server recognizes the 'multipart/form-data' enctype and accepts the file, saving it in a temporary (temp) directory on the web server.
  6. Your web server retrieves the 'action' page (getfile.cfm, could have been called anything as long as it is a CF page) and processes it.
Next, in order to actually use the file, you will need to save it into a 'permanent' directory on your webserver.
Try this simple CF page:
<cffile action = "upload" fileField = "UPLOADFILE" destination = "#GetDirectoryFromPath(expandpath('*.*'))#">
This one command is both 'misleading' as well as very powerful. First the powerful part. This command retrieves the location of the uploaded file from the current location in the temp directory. It moves the file from the temp directory to the destination directory. and then returnes to the coldfusion file a 'cffile structure' filled with information about the file that was just uploaded.
The misleading part? The action says 'upload'. Most people (myself included) read that to mean 'upload from the users computer'. Which can lead the programmer to believe that the file stays on the user's computer until this command is run. Which can also lead the programmer to believe that they have some minute control over the user's computer. What the 'upload' really means is 'copy from temp directory' or 'upload to a permanent directory'.

So we pick up our server activity steps from where we left off above. (web server retrieves the 'action' page)
  1. Since the action page is a .cfm page the web server sends the page to the ColdFusion engine.
  2. The ColdFusion engine sees the cffile upload command and;
    • Copies the file from the temp directory to the specified destination directory
    • If the copy was successful (no 'permission' errors), then the temp directory file is deleted
  3. ColdFusion creates a structure variable called 'cffile' to contain all of the information returned by the cffile action
  4. After ColdFusion engine is done with the file, it is sent back to the webserver to be sent as a 'static' html page to the user's browser.
This is how you upload a file from the user's browser to a directory on your web server. It is important to mention that this is an example of the most simple of cases. There are other actions that you should take when uploading a file. For instance, you should determine if you want the filename to be unique. You should limit the file types to those types you are allowing to be uploaded. You probably don't want anyone to upload a .cgi, .pl, .exe, etc that may 'compromise' your web server.

Something I would like to address, that has come up a few times, is this:
A certain browser (ie) made by the same company that makes a certain popular operating system (windows) sends the user's directory information for the file along with that file to the webserver. You can view it by displaying the 'cffile.CLIENTDIRECTORY' variable, after performing the cffile tag. It is important not to rely on this information. Unless you can guarantee that all browsers in your system will be IE (or at least IE7) then this information will not be available for all browsers. The reason is due to the 'sandbox' rules. These rules are there to protect the user from web sites that might want to do too much and possibly jeopardize the user's system. 'IE' has always broken those rules where it sees fit, but other browsers such as Netscape (now dying off), Firefox, Safari, etc respect the sandbox and don't send that information.

February 12, 2008

Tips & Tricks: Beginner Database Query Cfoutput

Tips & Tricks: Beginner Database Query Cfoutput Many times on the informational boards, I come across new developers who are working with the concepts of displaying database record sets. They are interested on how to display them in a functional way. I have compiled a short list of different methods here where I will show you some simple solutions to formatting your database query results. I will offer 2 solutions for each sample. The simple record set and the ‘grouped’ record set.
  1. Block tags or break tags. This is probably the most familiar method to anyone entering ColdFusion. I have shown both of these examples using the HTML paragraph tags, but you can substitute for any line-breaking code. (<br />, <div></div>. etc)
    Regular record set:
    <cfoutput query=”[yourqueryname]”>
    <p>#[columnname]#</p>
    </cfoutput>
    Grouped record set:
    <cfoutput query=”[yourqueryname]”>
    #[sectionname]#<br>
    <cfoutput>
    <p>#[columnname]#</p>
    </cfoutput>
    </cfoutput>
  2. Tables - Horizontal. After working with HTML for a while you will recognize this code as a simple list/report layout.
    Regular record set:
    <table>
    <cfoutput query=”[yourqueryname]”>
    <tr>
    <td>#[columnname]#</td>
    </tr>
    </cfoutput>
    </table>
    Grouped record set:
    <table>
    <cfoutput query=”[yourqueryname]”>
    <tr>
    <th>#[sectionname]#</th>
    </tr>
    <cfoutput>
    <tr>
    <td>#[columnname]#</td>
    </tr>
    </cfoutput>
    </cfoutput>
    </table>
  3. Tables - Vertical. This is similar to the system above with the addition of a ‘counter’. What you do is decide how many vertical results you want to display before ‘breaking’ to the next line of results. I have used 4 results, but choose what you need. I have moved the ‘<tr>’ to the outside of the cfoutputs and have added a to determine if the code should insert a table row termination and start tag. I had previously left out the code that I am adding using this editing color. I had left it out intentionally to keep the 'concept' of the process simple and clear for the new developer. It has been brought to my attention that it can end in badly formed HTML (this was the least of my concerns).
    Regular record set:
    <table>
    <tr>
    <cfoutput query=”[yourqueryname]”>
    <td>#[columnname]#</td>
    <cfif currentrow mod 4 eq 0 and currentrow neq recordcount></tr><tr></cfif>
    </cfoutput>
    </tr>
    </table>
    In the grouped example, I have added an additional cfif to check to see if the loop ‘did not’ end on a multiple of 4 AND it is not the very first record in the query. I have also added a variable that carries the row count of every breaking <tr> in the data displays so that it can be checked against the currentrow in the 'group' and not print two recurring breaking <tr> groups together.
    Grouped record set: <table>
    <tr>
    <cfoutput query=”[yourqueryname]”>
    <cfif currentrow mod 4 neq 0 and currentrow neq 1 and currentrow neq lastbreakrow ></tr><tr></cfif>
    <th colspan=”4”>#[sectionname]#</th>
    </tr>
    <tr>
    <cfoutput>
    <td>#[columnname]#</td>
    <cfif currentrow mod 4 eq 0> </tr><tr></cfif>
    </cfoutput>
    </cfoutput>
    </tr>
    </table>
  4. Tables – Horizontal AND Vertical (Newspaper). This is similar to the system above however instead of running the records left to right, we will run them top to bottom for ½ the records and then start at the top again for the 2nd half. (you can also do this for thirds, fourths, fifths, etc).
    Regular record set: <table>
    <tr>
    <td>
    <cfoutput query=”[yourqueryname]”>
    #[columnname]#
    <cfif currentrow eq round(recordcount / 2)></td></tr><tr><td><cfelse><br /></cfif>
    </cfoutput>
    </td>
    </tr>
    </table>
    Grouped record set:
    <table>
    <tr>
    <td>
    <cfoutput query=”[yourqueryname]”>
    <p>#sectionname]#</p>
    <cfoutput>
    <p>#[columnname]#</p>
    <cfif currentrow eq round(recordcount / 2)></td></tr><tr><td></cfif>
    </cfoutput>
    </tr>
    </cfoutput>
    </table>
This is certainly not the only methods available, nor will they be the best formatted versions for your needs, but they should hopefully help you get pointed in the right direction to have your data displayed the way you wanted it.