Variable scoping, or lack of scoping, is a topic that comes up nearly every day on the various ColdFusion discussion lists and blogs I follow. An unscoped variable, in my opinion, is an immediate red flag during a code review and requires immediate correction or a detailed (and convincing) explaination on why it should remain unscoped.

Aside from readability issues, unscoped variables may cause interesting, and sometimes difficult to trace, bugs in your code. When CF processes a code template and reaches an unscoped variable, it looks in the following scopes in order:

  1. Function local (UDFs and CFCs)
  2. Thread local (new in CF 8)
  3. Arguments
  4. Variables (local scope)
  5. Thread (new in CF 8)
  6. CGI
  7. CFFile
  8. URL
  9. Form
  10. Cookie
  11. Client

The following example illustrates one of the many problems that unscoped variables can bring about.

view plain print about
1<cfparam name="customerID" value="100">
2
3<cfquery name="customer" datasource="example">
4    SELECT customerid, customername
5    FROM customers
6    WHERE customerid = <cfqueryparam value="#customerID#" cfsqltype="cf_sql_numeric">
7</cfquery>

We have a simple page that retrieves a database record for a customer based on their customerid. The cfparam makes sure a default value exists.

So, where is the customerID value coming from - a form post, a url parameter, a cookie? In this respect, the code is not self-documenting. It is also not a performant as it could be. ColdFusion will check each scope in order, starting with the function local scope, to find the customerID variable.

The code is also not as controlled as it could be. If, for example, the code is meant to be reached via a form post, someone could bypass the form entirely by adding customerid to the URL (&customerid=123). Since the URL scope is evaluated before the form scope, the URL value will take precedence over the form field value.

All variables, even local variables, should be scoped. No exceptions without a very good reason. It increases code readability and decreases inadvertant value changes due to scope precedence rules.