CF 'Best Practices'

ColdFusion ?Best Practices?

Before we delve into these so-called ?Best Practices??I need to issue a caveat. ?Best Practices? are a relative term, at best.

What I might consider a best practice, others might not. Some think that writing highly, highly optimized code is a best practice. However, this often results in code that is less readable. Some think that maintaining readable code is a best practice (makes it easier for you and whoever else may follow you to work with and debug).

So with that in mind?I should point out that these are *my* best practices. Others may disagree. That?s fine. The beauty of programming is there?s never just one way to get from point A to point B. Some prefer a direct route. Some prefer a scenic route.


A) Scope your variables

What is a scope? Well, ColdFusion has quite a few. There?s the form scope. The URL scope. Application, session, client, CGI, server, query, caller, cookie, and more.

Think of each scope as a dresser drawer (trust me on this). One hold the form variables?one holds URL variables?one holds form variables, and so on.

Now, let?s say you do: <cfoutput>#URL.firstName#</cfoutput>. ColdFusion knows exactly what to do. It goes to the URL drawer and pulls out the variable firstName.

Is the prefix URL. Mandatory? No. You can do <cfoutput>#firstName#</cfoutput>, and it?s just as legitimate. However, notice what happens. ColdFusion is standing in front of a dresser looking for a specific variable (firstName). It has no idea what drawer to look in. So it has to hunt through the drawers until it finds the appropriate variable.

Obviously, it?s going to take longer to find that variable without knowing which drawer to check. Do this a few hundred times in your Web application?with a few hundred users on your site?and you can see where that time difference can start to become significant.

Now that you know why you should scope your variables, learn a little bit more about the scopes themselves. This Macromedia Live Doc will teach you a great deal.


B) Use Boolean evaluation

Have you ever needed to check to see if a form field is empty? The most straightforward way is:

<cfif form.firstName IS ??>

It simply checks to see if the specified form field is an empty string (??).

Another way of writing the same thing would be:

<cfif len(form.firstName) EQ 0>

This checks to see if the length of the form field value is 0 (empty string).
This second method can be shortened a little bit?

<cfif len(form.firstName)>

Assume that form.firstName is empty. This would then become <cfif 0>. In boolean evaluation, 0 is false. Assuming the value was not empty (let?s say it?s ?charlie?), it would become <cfif 7>. A non-zero number evaluates to true.

<cfif form.firstName IS ??> <-- equals --> <cfif len(form.firstName)>

This is a classic example of where a ?best practice? becomes subjective. I personally prefer the Boolean evaluation (on the right), for it?s performance increase. Others prefer the method on the left, as it?s much more intuitive to read, which makes maintaining your code easier.

Either way is acceptable. It?s a matter of preference.

Another example of using Boolean evaluation can be demonstrated in trying to determine if a particular query returned any records. Traditionally, one would write:

<cfif queryName.recordCount EQ 0>

Using Boolean evaluation, we can write:

<cfif NOT queryName.recordCount>

<cfif queryName.recordCount EQ 0> <-- equals --> <cfif NOT queryName.recordCount>


C) Learning to debug


Okay?not necessarily a ?best practice??but a very necessary skill if you want to be a good programmer.

With the advent of CF 5.0, and continuing in MX, debugging became much easier with the introduction of the <cfdump> tag. Want to know exactly what your query returned? <cfdump var=?#myQueryName#?>. Want to know what?s in that array? <cfdump var=?#myArray#?>. Previously, to ?see? the contents of an array or structure, you?d have to loop (and for 2d arrays you?d have to do nested loops). <cfdump> changes all that. It?s an invaluable tool that I?ve seen too many people forget about.

If you are getting unexpected results after a form submission, do <cfdump var=?#form#?> on the form?s action page, and you?ll see everything that was passed in the form.

Another debugging technique would be turning debugging on in the ColdFusion Administrator (assuming you have access). This will output all relevant (and some irrelevant) variables and values at the bottom of the page. However, not everybody has access to do this. Since the introduction of <cfdump>, I?ve never had to resort to CF?s debug output option.


D) Using structure functions to your advantage

Just about all scopes in CFMX are stored in structures. If you are using session variables, they are stored in a structure (don?t believe me? Try this: <cfdump var=?#session#?>). When you submit a form, those form variables are stored in a structure on the action page. Again, a quick <cfdump var=?#form#?> will demonstrate this.

(if you?re not familiar with structures, peruse my 3 part tutorial on complex datatypes in ColdFusion, which teaches arrays and structures).

How to use this to your advantage?

Well, let?s say you have a form action page. You obviously don?t want people to load that page directly?you want to make sure that they came from your form, right? (right).

You could put the following code at the top of the page:

<cfif NOT isDefined(?form.firstName?)>
    <cflocation URL=
?myFormPage.cfm?>
</cfif>


This, of course, works just fine. But it would be a little bit quicker to check the form structure for a specific key:

<cfif NOT structKeyExists(form, ?firstName?)>
    <cflocation URL=?myFormPage.cfm?>
</cfif>


The isDefined() function must parse a string?which is relatively slow compared to other operations. The second method does not require CF to do any parsing?it simply checks a given structure (in this case, the form structure) for the existence of a specific key (in this case, ?firstName?).

The two are functionally identical. Once again, it?s your choice as to which one to use. While the second one is arguably faster (and how much faster is actually debatable), the first one is probably easier to read and understand it?s purpose.

E) Efficient use of <cfoutput> tags

Over the course of any given day, I generally help at least a handful of people with coding problems. And all too often, I see something like:

<cfloop from=?1? to=?100? index=?i?>
    <cfoutput>
       
this is iteration #i#<br />
    </cfoutput>
</cfloop>


This code won?t throw an error?so many people wouldn?t think there?s anything wrong with it. However, it is quite inefficient.

Think of a <cfoutput> tag as starting a car. Likewise, a </cfoutput> tag is similar to shutting a car off. This analogy holds true because with every instance of <cfoutput>, the CF Server leaps into action (red tights and all). With every </cfoutput>, it stops.

Now look at the code snippet above again. The ?car? is going to start and stop 100 times. Would you knowingly do that to your car?

A much better way of writing the same code is:

<cfoutput>
    <cfloop from=
?1? to=?100? index=?i?>
        this is iteration #i#<br />
    </cfloop>
</cfoutput>


Now the car is started once?the loop iterates as many times as necessary, and the car is shut off.


F) Those darn pound signs

Ben Forta (Mr. ColdFusion himself) wrote an article dealing with the overuse of pound signs. It?s that much of an issue.

Of course, the term ?issue? is relative. It?s not earth-shattering?but it deserves to be mentioned.

Pound signs are most often used to output a variable?s value. For example:

<cfoutput>#myName#</cfoutput>

However, in setting that variable, you need not use pound signs.

<cfset myName = ?Charlie?>

is not only perfectly valid?but generally more acceptable than:

<cfset #myName# = ?Charlie?>

Too many people think every CF variable in every set, condition, loop, etc needs to be enclosed in pound signs. The fact of the matter is that overuse of pound signs could conceivably slow up your application?as well as making your code less readable/manageable.

<cfif #myName# IS ?Charlie?>
    Hi, Charlie
<cfelseif #myName# IS ?Pablo?>
    Hi, Pablo
</cfif>

<cfif myName IS ?Charlie?>
    Hi, Charlie
<cfelseif myName IS ?Pablo?>
    Hi, Pablo
</cfif>

While both of these code blocks will function the same, the bottom one is arguably more readable. Especially if you think about a particularly long page of code. Reducing the pound sign usage can significantly ?clean up? the look of your code.

Ben Forta is feared by men and worshipped by women for a reason. I don?t think for a second that I can say it better than him, so I won?t even try. To hear it straight from the horse?s mouth, see Ben?s article at http://www.defusion.com/articles/index.cfm?ArticleID=26

Macromedia has also put out a page trying to clarify when to use pound signs and when to leave them alone (see Macromedia Live Doc)


G) Writing Better SQL

Two rules of thumb immediately come to mind in this area:

1) Avoid SELECT * when possible. If you know the columns that you need, specify them. It may take longer to type, but your queries will execute faster and your query objects will be smaller and easier to work with.

2) Use <cfqueryparam>. Not only will it significantly speed up your queries, it will also add an additional level of security to your database by preventing users from trying to force malicious queries. <shameless_plug>http://tutorial138.easycfm.com/</shameless_plug> <--
I should mention that use of <cfqueryparam> is NOT one of those subjective best practices. It should always, always, always be used. Always.


H) Write valid markup

This should probably be much higher on the list. But whether it?s CFML or HTML or XHTML or XML, write valid code (with the latter two, there?s really no other alternative).

HTML was, by its nature, very forgiving of bad code. However, the current version of HTML will be the last. There will be no HTML 5.0. XHTML will replace HTML as the base markup language of the Web.

In a nutshell, XHTML is nothing more than well-formed markup. What does this mean to you? It means no incorrect nesting of tags (eg <b><i>FOO</b></i>). It means all tags must be closed (including <li>, which needs a </li>, and <option>, which need an </option>).

A full explanation/tutorial on XHTML is WAY beyond the scope of this tutorial. However, getting into these good coding habits now will save you a world of heartache when XHTML becomes ?the- standard (it currently *is* an accepted W3C standard).

Valid markup also means a page that loads faster, and is more easily portable to other platforms (such as wireless).


That should be enough for now. Again, I stress that these are not ?official? best practices. They are endorsed by nobody but me. Obviously, I do prefer these coding methods. Do I suggest that you spend time ?cleaning up? all of the previous code you?ve written? No.

I do suggest that you get into good habits from here on in. That means writing valid markup. That means using cfqueryparam. That means not overusing pound signs. These are the more universally accepted of the concepts that I?ve presented. The others are your choice.

As I?ve said, the beautiful thing about programming is that there is no one right way to do any particular task (this can also be a very frustrating thing about programming). My point is that if you disagree with my opinions of what constitutes a ?best practice?, I?d like to hear about it. I?d like to know why. Your ?best practice? that contradicts mine could very well be a better way to do something, and I would welcome the opportunity to have another option available to me.

This tutorial is also not meant to be an all-inclusive reference to best coding practices. Certainly, there are many more techniques/subjects that I did not cover here. Error handling techniques, for example, come to mind.

Let?s open up the EasyCFM forums with some discussion about this. I?d like to not only hear about whether or not you agree or disagree with my programming ?styles??but I?d also like to hear yours. What do you do that you think makes your code better/faster?

We all stand to benefit through the sharing of ideas. I?d love to hear yours.

CJ
 

All ColdFusion Tutorials By Author: Charlie Griefer (CJ)
  • CFSCRIPT Intro
    An introductory look at CFSCRIPT. Rules, some basic syntax, and a couple of examples of loops and conditional processing.
    Author: Charlie Griefer (CJ)
    Views: 46,873
    Posted Date: Saturday, January 18, 2003
  • ColdFusion Mad Libs - Part I
    A silly but fun time-waster that you can easily include on your Web site. You might be surprised at how addicting it can become :)
    Author: Charlie Griefer (CJ)
    Views: 27,666
    Posted Date: Thursday, May 29, 2003
  • ColdFusion Mad Libs - Part II
    You've finished the first Mad Libs tutorial, but you feel like there's something missing. Of course there is! You want to be able to save the final output to a database to let your visitors browse through other user's stories. Includes a bad-words filter for the more conservative among us :)
    Author: Charlie Griefer (CJ)
    Views: 22,839
    Posted Date: Thursday, May 29, 2003
  • to cfqueryparam or not to cfqueryparam
    It's been out there since ColdFusion 4.5...most of us have heard of it...few of us use it. Here are some compelling reasons why you should get into the habit of using the tag.
    Author: Charlie Griefer (CJ)
    Views: 34,135
    Posted Date: Thursday, May 29, 2003
  • Dynamic Column Output (Part One)
    Have you ever wanted to display your content in rows of 3 columns? If you ever wanted to specify the number of columns per row within your content, here's the tutorial for you.
    Author: Charlie Griefer (CJ)
    Views: 34,987
    Posted Date: Thursday, May 29, 2003
  • Dynamic Column Output (Part Two)
    This tutorial picks up where the Dynamic Columns tutorial left off, showing you how to not only output your data in a specified number of columns, but how to do it while still publishing well formed HTML.
    Author: Charlie Griefer (CJ)
    Views: 27,534
    Posted Date: Saturday, May 31, 2003
  • Remote File Management
    Manage text-based files on your server from any Web browser. Create a new file, edit a file, or delete a file. Can be a life saver if you're on the road, and find an error in some of your code that needs a quick fix.
    Author: Charlie Griefer (CJ)
    Views: 27,815
    Posted Date: Tuesday, June 3, 2003
  • Save your visitor's clickstreams
    A nifty little custom tag that will allow you to save a visitor's clickstream through your site, as well as display it back to them (with links). Did I really just say 'nifty'?
    Author: Charlie Griefer (CJ)
    Views: 25,608
    Posted Date: Monday, June 16, 2003
  • Grouping Output in CF
    How to group cfquery output in order to effectively display relational database data. Includes an overview of how to output nested groups as well.
    Author: Charlie Griefer (CJ)
    Views: 32,508
    Posted Date: Tuesday, June 17, 2003
  • arrays and structures - part 1
    part one of a three-part tutorial designed to gently introduce you to the world of complex variables.
    Author: Charlie Griefer (CJ)
    Views: 38,749
    Posted Date: Monday, August 11, 2003
  • arrays and structures - part 2
    part two of a three-part tutorial designed to gently introduce you to the world of complex variables.
    Author: Charlie Griefer (CJ)
    Views: 28,290
    Posted Date: Monday, August 11, 2003
  • arrays and structures - part 3
    part three of a three-part tutorial designed to gently introduce you to the world of complex variables.
    Author: Charlie Griefer (CJ)
    Views: 33,333
    Posted Date: Monday, August 11, 2003
  • JavaScript Form Validation
    Yes, I know we're a ColdFusion site...but ColdFusion does not live in a vacuum. We have to know SQL, HTML, CSS...and sometimes...JavaScript! This tutorial focuses on using JavaScript (in lieu of cfform) to create client side form validation (and explains why writing your own is better than using ).
    Author: Charlie Griefer (CJ)
    Views: 58,284
    Posted Date: Thursday, August 14, 2003
  • CF 'Best Practices'
    Some tips and techniques that I've picked up over the years. I don't maintain that these are 'official' or 'absolute'...they are simply my preference and things that have worked for me. I would like to share them here, and leave you to make the decision as to whether or not they fit in your 'code arsenal' :)
    Author: Charlie Griefer (CJ)
    Views: 35,638
    Posted Date: Friday, August 15, 2003
  • Helping users obtain their passwords
    Your site requires your visitors to log in. of course, some of your visitors are going to forget their passwords (ok, most will forget their passwords). You don't want them to have to send you an e-mail, and then wait for a response. They need immediate access.

    This tutorial shows two methods by which you can accomodate them.
    Author: Charlie Griefer (CJ)
    Views: 26,199
    Posted Date: Thursday, August 28, 2003
Download the EasyCFM.COM Browser Toolbar!