Variables in CFML; Dynamic Variables

ColdFusion offers significant, perhaps unique flexibility in the many ways that a developer can programmatically build dynamic references to variables. Dynamic in this case indicates situations where you need to construct a variable name from multiple or derived values. For example in a web form you may present a checkbox for each item returned from a database table. The checkboxes could be named "Chck_" followed by the primary key of the related item. You would use dynamic variable techniques to access those values.

Much of this flexibility results from the way ColdFusion automatically organizes all variables into scopes and those scopes into structures. ColdFusion also provides a direct syntax for assigning data to dynamic variables and several related functions.

Determining Variable Existence

The ColdFusion function IsDefined() is used to determine the existence of a variable (it replaced the now deprecated function ParameterExists() which did not allow for dynamic variable processing). The function takes a string (or a variable containing a string or functions resulting in a string) and determines if there is a matching, existing variable. The function returns TRUE (the variable exists) or FALSE (the variable does not exist).

Some examples of IsDefined() (the last two examples are functionally equivalent):

  • IsDefined(MyVar)
  • IsDefined("URL.Foo")
  • IsDefined("URL.#Mid(Foo, 1, 3)#")
  • IsDefined("Form.Chck_#Count#")
  • IsDefined("Form.Chck_" & Count)

Variables in ColdFusion either exist (and have values) or don't exist at all. It's worth noting that because Arrays in CFML are dynamically sized and allocated it's quite difficult to reliably determine the existence of a specific element in an array.

Dynamic Variable Functions

CFML provides two functions for working with dynamic variables: Evaluate() and SetVariable().

The Evaluate() function is used to obtain and return the value of a dynamic variable. Much like the IsDefined() function it takes a string and determines if a variable of that name exists. If the variable does exist the value of it is returned, if it doesn't an error is thrown.

Evaluate() can be used to convert variables or other functions within larger strings to simple string values. Such dynamic strings can be stored in a database or other location for later use. The following is an example of this:

<cfset CustomerName="Jane">
<cfoutput>
     #Evaluate("Hello, #CustomerName#, How are you.")#
</cfoutput>

The SetVariable() function is used to set the value of a dynamic variable. It takes a string (or a variable containing a string) and a value. It then assigns the specified value to the variable specified creating it if needed.

In early versions of ColdFusion the only way to manipulate dynamic variables was through the use of these functions. The techniques available in later versions make these functions less appropriate in many cases but you will often still see them in use. Old habits die hard.

Using Scopes as Structures

Scopes accessible as structures (in CFMX, all of them) present many opportunities for dynamic variable manipulation. As noted already Indexed Notation may be used to construct dynamic references to these scopes. Some examples of this:

  • <cfset Session["Selection_" & Count] = 10>
  • <cfset Application[Cookie.UserID].UserName = "Jane">
  • <cfset CurSelection = Form["Input_#Count#"]>

In addition the entire, rich function set for working with structures may be leveraged in many ways:

  • Although ColdFusion doesn't directly provide a method for deallocating or deleting a variable the StructDelete() function does this effectively for any named scope.
  • StructClear() can be used to effectively "reset" a named scope by wiping out all the data within it. Upon the next page request the scope will be rebuilt and any default or predefined variables in it will be recreated.
  • StructKeyList() and StructKeyArray() may be used to get the names of all variables in a named scope.
  • StructCount() can be used to return a count of all the variables in a named scope.
  • The functions StructUpdate(), StructInsert() and StructDelete() can be used to create complex, programmatic interfaces to named scopes.
  • StructIsEmpty() can be used to determine if named scope like has been initialized with data. For example if "StructIsEmpty(FORM)" returns TRUE you know that no form submitted data to the current template.

Lastly any tag or function that will accept a structure will accept a named scope. You can view the contents of any named scope using <CFDUMP> (available in CF 5.0 and above) or perform actions on all variables in a scope using <CFLOOP> and the COLLECTION attribute.

Dynamic Variables to the Left of the Assignment

ColdFusion versions 5.0 and above allow developers to use dynamic variable syntax to the left as well as the right of the assignment operator ("="). All of the following are valid CFML statements:

  • <cfset "Session.#UserID#" = 10>
  • <cfset "Form.Chbk_#IncrementValue(Count)#" = True>
  • <cfset "#foo#" = 10>

The flexibility afforded by this is substantial. Almost all scenarios requiring the SetVariable() function in previous versions can be dealt with using this capability.

40 Current Sessions; Time: 22:41:05 06-01-2009; Tick: 656