Data types

ColdFusion is often referred to as typeless because you do not assign types to variables and ColdFusion does not associate a type with the variable name. However, the data that a variable represents does have a type, and the data type affects how ColdFusion evaluates an expression or function argument. ColdFusion can automatically convert many data types into others when it evaluates expressions. For simple data, such as numbers and strings, the data type is unimportant until the variable is used in an expression or as a function argument.

ColdFusion variable data belongs to one of the following type categories:

Data type notes

Although ColdFusion variables do not have types, it is often convenient to refer to a variable's type as a shorthand for the type of data that the variable represents.

ColdFusion can validate the type of data contained in form fields and query parameters. Form more information on form field data type validation, see "Validating form field data types," in Chapter 26. For more information on query parameter validation, see "Using cfqueryparam," in Chapter 20.

The cfdump tag displays the entire contents of a variable, including ColdFusion complex data structures. It is an excellent tool for debugging complex data and the code that handles it.

ColdFusion provides the following functions for identifying the data type of a variable:

ColdFusion also includes the following functions for determining whether a string can be represented as another simple data type:

ColdFusion does not use a null data type. However, if ColdFusion receives a null value from an external source such as a database, a Java object, or some other mechanism, it maintains the null until you use it as a simple value. At that time, ColdFusion converts the null to an empty string ("").

Numbers

ColdFusion supports integers and real numbers. You can intermix integers and real numbers in expressions; for example, 1.2 + 3 evaluates to 4.2.

Integers

ColdFusion supports integers between -2,147,483,648 and 2,147,483,647 (32-bit signed integers). You can assign a value outside this range to a variable, but ColdFusion initially stores the number as a string. If you use it in an arithmetic expression, ColdFusion converts it into a floating point value, preserving its value, but losing precision as the following example shows:

<cfset mybignum=12345678901234567890>
<cfset mybignumtimes10=(mybignum * 10)>
<cfoutput>mybignum is: #mybignum#</cfoutput><br>
<cfoutput>mybignumtimes10 is: #mybignumtimes10# </cfoutput><br>

This code generates the following output:

mybignum is: 12345678901234567890
mybignumtimes10 is: 1.23456789012E+020

Real numbers

Real numbers, numbers with a decimal part, are also known as floating point numbers. ColdFusion real numbers can range from approximately -10300 to approximately 10300. A real number can have up to 12 significant digits. As with integers, you can assign a variable a value with more digits, but the data is stored as a string. The string is converted to a real number, and can lose precision, when you use it in an arithmetic expression.

You can represent real numbers in scientific notation. This format is xEy, where x is a positive or negative real number in the range 1.0 (inclusive) to 10 (exclusive), and y is an integer. The value of a number in scientific notation is x times 10y. For example, 4.0E2 is 4.0 times 102, which equals 400. Similarly, 2.5E-2 is 2.5 times 10-2, which equals 0.025. Scientific notation is useful for writing very large and very small numbers.

Strings

In ColdFusion, text values are stored in strings. You specify strings by enclosing them in either single or double quotation marks. For example, the following two strings are equivalent:

"This is a string"
'This is a string'

You can write an empty string in the following ways:

Strings can be any length, limited by the amount of available memory on the ColdFusion Server. There is, however, a 64K limit on the size of text data that can be read from and written to a ColdFusion database or HTML text area. The ColdFusion Administrator lets you increase the limit for database string transfers, but doing so can reduce server performance. To change the limit, select the Enable retrieval of long text option on the Advanced Settings page for the data source.

Escaping quotes and pound signs

To include a single-quotation character in a string that is single-quoted, use two single quotation marks (known as escaping the single quotes). The following example uses escaped single quotes:

<cfset myString='This is a single quote: '' This is a double quote: "'>
<cfoutput>#mystring#</cfoutput><br>

To include a double-quote character in a double-quoted string, use two double quotes (known as escaping the double quote). The following example uses escaped double quotes:

<cfset myString="This is a single quote: ' This is a double quote: """>
<cfoutput>#mystring#</cfoutput><br>

Because strings can be in either double quotes or single quotes, both of the preceding examples display the same text:

This is a single quote: ' This is a double quote: "

Note:   To insert a pound sign in a string, you must escape the pound sign, as in:
"This is a pound sign ##"

Lists

ColdFusion includes functions that operate on lists, but it does not have a list data type. In ColdFusion, a list is just a string that consists of multiple entries separated by delimiter characters.

The default delimiter for lists is the comma. If you use any other character to separate list elements, you must specify the delimiter in the list function. You can also specify multiple delimiter characters. For example, you can tell ColdFusion to interpret a comma or a semicolon as a delimiter, as the following example shows:

<cfset MyList="1,2;3,4;5">
<cfoutput>
List length using ; and , as delimiters: #listlen(Mylist, ";,")#<br>
List length using only , as a delimiter: #listlen(Mylist)#<br>
</cfoutput>

This example displays the following output:

List length using ; and , as delimiters: 5
List length using only , as a delimiter: 3

Each delimiter must be a single character. For example, you cannot tell ColdFusion to require two hyphens in a row as a delimiter.

If a list has two delimiters in a row, ColdFusion ignores the empty element. For example, if MyList is "1,2,,3,,4,,,5" and the delimiter is the comma, the list has five elements and list functions treat it the same as "1,2,3,4,5".

Booleans

A Boolean value represents whether something is true or false. ColdFusion has two special constants-True and False- to represent these values. For example, the Boolean expression 1 IS 1 evaluates to True. The expression "Monkey" CONTAINS "Money" evaluates to False.

You can use Boolean constants directly in expressions, as in the following example:

<cfset UserHasBeenHere = True>

In Boolean expressions, True, nonzero numbers, and the string "Yes" are equivalent, and False, 0, and the string "No" are equivalent.

Boolean evaluation is not case-sensitive. For example, True, TRUE, and true are equivalent.

Date-Time Values

ColdFusion can perform operations on date and time values. Date-time values identify a date and time in the range 100 AD to 9999 AD. Although you can specify just a date or a time, ColdFusion uses one data type representation, called a date-time object, for date, time, and date and time values.

ColdFusion provides many functions to create and manipulate date-time values and to return all or part of the value in several different formats.

You can enter date and time values directly in a cfset tag with a constant as follows:

<cfset myDate = "October 30, 2001">

When you do this, ColdFusion stores the information as a string. If you use a date-time function, ColdFusion stores the value as a date-time object, which is a separate simple data type. When possible, use date-time functions such as CreateDate and CreateTime to specify dates and times, because these functions can prevent you from specifying the date or time in an invalid format and they create a date-time object immediately.

Date and time formats

You can directly enter a date, time, or date and time, using standard U.S. date formats. ColdFusion processes the two-digit-year values 0 to 29 as twenty-first century dates; it processes the two-digit-year values 30 to 99 as twentieth century dates. Time values are accurate to the second. The following table lists valid date and time formats:
To specify
Use these formats
Date
October 30, 2001
Oct 30, 2001
Oct. 30, 2001
10/30/01
2001-10-30
10-30-2001
Time
02:34:12
2:34a
2:34am
02:34am
2am
Date and Time
Any combination of valid date and time formats, such as these:
October 30, 2001 02:34:12
Oct 30, 2001 2:34a
Oct. 30, 2001 2:34am
10/30/1 02:34am
2001-10-30 2am
10-30-2001 2am

Locale-specific dates and times

ColdFusion provides several functions that let you input and output dates and times (and numbers and currency values) in formats that are specific to the current locale. A locale identifies a language and locality, such as English (US) or French (Swiss). Use these functions to input or output dates and times in formats other than the U.S. standard formats. (Use the SetLocale function to specify the locale.) The following example shows how to do this:

<cfset oldlocale = SetLocale("French (Standard)")>
<cfoutput>#LSDateFormat(Now(), "ddd, mmmm dd, yyyy")#</CFOUTPUT>

This code outputs a line like the following:

ven., juin 15, 2001

For more information on international functions, see CFML Reference.

How ColdFusion stores dates and times

ColdFusion stores and manipulates dates and times as date-time objects. Date-time objects store data on a time line as real numbers. This storage method increases processing efficiency and directly mimics the method used by many popular database systems. In date-time objects, one day is equal to the difference between two successive integers. The time portion of the date-and-time value is stored in the fractional part of the real number. The value 0 represents 12:00 AM 12/30/1899.

Although you can use arithmetic operations to manipulate date-and-time values directly, this method can result in code that is difficult to understand and maintain. Use the ColdFusion date-time manipulation functions instead.

Binary data type and Base64 encoding

Binary data is raw data, such as the contents of a GIF file or an executable program file. You do not normally use binary data directly, but you can use the cffile tag to read a binary file into a variable, typically for conversion to Base64 encoding before transmitting the file by e-mail.

Base64 format encodes the data in the lowest six bits of each byte. It ensures that binary data and non-ANSI character data can be transmitted by e-mail without corruption. The MIME specification defines the Base64 encoding method.

ColdFusion does not have a Base64 data type; it processes Base64 encoded data as string data.

ColdFusion provides the following functions that convert among string data, binary data, and Base64 encoded string data:
Function
Description
ToBase64
Converts string and binary data to Base64 encoded data.
ToBinary
Converts Base64 encoded data to binary data.
ToString
Converts most simple data types to string data. It can convert numbers, date-time objects, and boolean values. (It converts date-time objects to ODBC timestamp strings.) It cannot convert binary data that includes bytes that are not printable characters.

The ToString function cannot convert Base64 encoded data directly to an unencoded string. Use the following procedure to convert Base64 encoded data that was originally a string back to a readable string:

  1. Use the ToBinary function to convert the Base64 data into binary format.
  2. Use the ToString function to convert the binary data to string.

For example, the following two lines print the same results:

<cfoutput>This is a test</cfoutput>
<cfoutput>#ToString(ToBinary(ToBase64("This is a test")))#</cfoutput>

Do not use binary data or Base64 data directly in ColdFusion expressions.

Complex data types

Arrays, structures, and queries are ColdFusion built-in complex data types. Structures and queries are sometimes referred to as objects, because they are containers for data, not individual data values.

For details on using arrays and structures, see Chapter 5, "Using Arrays and Structures".

Arrays

Arrays are a way of storing multiple values in a table-like format that can have one or more dimensions. To create an array and specify its initial dimensions, use the ColdFusion ArrayNew function. For example, the following line creates an empty two-dimensional array:

<cfset myarray=ArrayNew(2)>

You reference elements using numeric indexes, with one index for each dimension. For example, the following code sets one element of a two-dimensional array to the current date and time.

<cfset myarray[1][2]=Now()>

The ArrayNew function can create arrays with up to three dimensions. However, there is no limit on array size or maximum dimension. To create arrays with more than three dimensions, create arrays of arrays.

After you create an array, you can use functions or direct references to manipulate its contents.

When you assign an existing array to a new variable, ColdFusion creates a new array and copies the old array's contents to the new array. The following example creates a copy of the original array:

<cfset newArray=myArray>

For more information on using Arrays, see Chapter 5, "Using Arrays and Structures".

Structures

ColdFusion structures consist of key-value pairs, where the keys are text strings and the values can be any ColdFusion data type, including other structures. Structures let you build a collection of related variables that are grouped under a single name. To create a structure, use the ColdFusion StructNew function. For example, the following line creates a new, empty, structure called depts:

<cfset depts=StructNew()>

You can also create a structure by assigning a value in the structure. For example, the following line creates a new structure called MyStruct with a key MyValue equal to 2.

<cfset MyStruct.MyValue=2>

Note:   In previous ColdFusion versions, this line created a Variables scope variable named "MyStruct.MyValue" with the value 2.

After you create a structure, you can use functions or direct references to manipulate its contents, including adding key/value pairs.

You can use either of the following methods to reference elements stored in a structure:

The following examples show these methods:

depts.John="Sales"
depts["John"]="Sales"

When you assign an existing structure to a new variable, ColdFusion does not create a new structure. Instead, the new variable accesses the same data (location) in memory as the original structure variable. In other words, both variables are references to the same object.

For example, the following code creates a new variable myStructure2 that references the same structure as the myStructure variable:

<CFSET myStructure2=myStructure>

When you change the contents of myStructure2, you also change the contents of myStructure. To copy the contents of a structure, use the ColdFusion Duplicate function, which copies the contents of structures and other complex data types.

Structure key names can be the names of complex data objects, including structures or arrays. This lets you create arbitrarily complex structures.

For more information on using Structures, see Chapter 5, "Using Arrays and Structures".

Queries

A query object, sometimes referred to as a query, query result, or record set, is a complex ColdFusion data type that represents data in a set of named columns, similar to the columns of a database table. The following ColdFusion tags can create query objects:

In these tags, the name attribute specifies the query object's variable name. The QueryNew function also creates queries.

When you assign a query to a new variable, ColdFusion does not copy the query object. Instead, both names point to the same record set data. For example, the following code creates a new variable myQuery2 that references the same record set as the myQuery variable.

<CFSET myQuery2 = myQuery>

If you make changes to data in myQuery, myQuery2 also shows those changes.

You reference query columns by specifying the query name, a period, and the column name; for example:

myQuery.Dept_ID

When you reference query columns inside tags, such as cfoutput and cfloop, in which you specify the query name in a tag attribute, you do not have to specify the query name.

You can access query columns as if they are one-dimensional arrays. For example, the following code assigns the contents of the second row of the Employee column in the myQuery query to the variable myVar:

<CFSET myVar = myQuery.Employee[2]>

You cannot use array notation to refer to a row (of all columns) of a query.

Working with structures and queries

Because structure variables and query variables are references to objects, the rules in the following sections apply to both types of data.

Multiple references to an object

When multiple variables refer to a structure or query object, the object continues to exist as long as at least one reference to the object exists. The following example shows how this works:

<cfscript> depts = structnew();</cfscript>
<cfset newStructure=depts>
<cfset depts.John="Sales">
<cfset depts=0>
<cfoutput>
  #newStructure.John#<br>
  #depts#
</cfoutput>

This example displays the following output:

Sales
0

After the <cfset depts=0> tag executes, the depts variable does not refer to a structure; it is a simple variable with the value 0. However, the variable newStructure still refers to the original structure object.

Assigning objects to scopes

You can give a query or structure a different scope by assigning it to a new variable in the other scope. For example, the following line creates a server variable, Server.SScopeQuery, using the local myquery variable:

<CFSET Server.SScopeQuery = myquery>

To clear the server scope query variable, reassign the query object, as follows:

<CFSET Server.SScopeQuery = 0>

This deletes the reference to the object from the server scope, but does not remove any other references that might exist.

Copying and duplicating objects

You can use the Duplicate function to make a true copy of a structure or query object. Changes to the copy do not affect the original.

Using a query column

When you are not inside a cfloop, cfoutput, or cfmail tag that has a query attribute, you can treat a query column as an array. However, query column references do not always behave as you might expect. This section explains the behavior of references to query columns using the results of the following cfquery tag in its examples:

<cfquery dataSource="CompanyInfo" name="myQuery">
  SELECT FirstName, LastName
  FROM Employee
</cfquery>

To reference elements in a query column, use the row number as an array index. For example, both of the following lines display the word "ben":

<cfoutput> #myQuery.Firstname[1]# </cfoutput><br>
<cfoutput> #myQuery["Firstname"][1]# </cfoutput><br>

ColdFusion behavior is less straightforward, however, when you use the query column references myQuery.Firstname and myQuery["Firstname"] without using an array index; as the two reference formats produce different results.

Here are the rules for these references:

If you refer to myQuery.Firstname, ColdFusion automatically converts it to the first row in the column. For example, the following line prints outs the word "ben":

<cfset myCol = myQuery.Firstname >
<cfoutput>#mycol#</cfoutput>

But the following lines display an error message:

<cfset myCol = myQuery.Firstname >
<cfoutput>#mycol[1]#</cfoutput><br>

If you refer to Query["Firstname"], ColdFusion does not automatically convert it to the first row of the column. For example, the following line results in an error message indicating that ColdFusion cannot convert a complex type to a simple value:

<cfoutput> #myQuery['Firstname']# </cfoutput><br>

Similarly, the following code prints out the name "marjorie", the value of the second row in the column

<cfset myCol = myQuery["Firstname"]>
<cfoutput>#mycol[2]#</cfoutput><br>

However, when you make an assignment that requires a simple value, ColdFusion automatically converts the query column to the value of the first row. For example, the following code displays the name "ben":

<cfoutput> #myQuery.Firstname# </cfoutput><br>
<cfset myVar= myQuery['Firstname']>
<cfoutput> #myVar# </cfoutput><br>

Comments