Glossary

What Is a ColdFusion Structure (Struct)?

Definition

A ColdFusion Structure (often called a “struct”) is a flexible, in‑memory data container that stores information as key–value pairs. Think of it as a dictionary or associative array: each piece of data is saved under a unique key (a string), and you retrieve or update it by referencing that key. In CFML (ColdFusion Markup Language), structures are used everywhere—from passing named arguments to APIs to storing Configuration, user profiles, and cached data.

Key idea: a struct is a dynamic, resizable, key-addressable container that supports fast lookup, insertion, and deletion.


How It Works

A struct internally maps keys (strings) to values (any CFML type, including other structs and arrays). You can:

  • Create a struct empty or with initial keys.
  • Add or update keys at runtime.
  • Access values using either dot notation or bracket notation.
  • Iterate its keys to read or process values.
  • Nest structs to represent hierarchical data.

Important characteristics:

  • Case-insensitive keys in most CFML engines: myStruct.firstName and myStruct.FIRSTNAME refer to the same key. The original case is preserved but key comparisons are not case-sensitive.
  • Keys must be unique; setting an existing key overwrites the previous value.
  • Order is not guaranteed in a regular struct; use an ordered struct when Iteration order matters.

Syntax and Examples

Creating and Populating Structs

  • Empty and add keys:

    • var user = structNew();
    • user.firstName = “Ada”; // dot notation
    • user[“last-name”] = “Lovelace”; // bracket notation for keys with special characters
    • user.age = 36;
  • Literal Syntax:

    • var user = { firstName = “Ada”, lastName = “Lovelace”, age = 36 };
  • Ordered struct (preserves insertion order, useful when order matters):

    • var orderedUser = structNew(“ordered”);
    • orderedUser.firstName = “Ada”;
    • orderedUser.lastName = “Lovelace”;
See also  What Is a ColdFusion Persistent Component?

Notes:

  • Use dot notation for simple, valid identifier keys (letters, numbers, underscore, not starting with a number).
  • Use bracket notation for keys with spaces, hyphens, or dynamic key names.

Access, Update, and Delete

  • Read:

    • writeOutput(user.firstName); // “Ada”
    • writeOutput(user[“last-name”]); // “Lovelace”
  • Check existence:

    • if (StructKeyExists(user, “age”)) { … }
  • Update or add:

    • user.title = “Countess”;
  • Delete:

    • StructDelete(user, “age”); // removes the key

Iteration

  • For-in loop:

    • for (var k in user) { writeOutput(k & “=” & user[k] & “
      “); }
  • Returning a list or array of keys:

    • var keysList = StructKeyList(user); // “firstName,last-name,title”
    • var keysArray = StructKeyArray(user); // [“firstName”,”last-name”,”title”]

Common Operations and Functions

Use these built-in functions and patterns regularly:

  • Existence and counting:

    • StructKeyExists(s, “key”)
    • StructCount(s)
  • Add/Update/Delete/Clear:

    • StructInsert(s, “key”, value) // explicit insert; may throw if key exists in some versions
    • StructUpdate(s, “key”, value) // update existing
    • StructDelete(s, “key”)
    • StructClear(s)
  • Merge and copy:

    • StructAppend(target, source, true) // true to overwrite keys, useful for merging configs
    • StructCopy(s) // shallow copy
    • duplicate(s) // deep copy (recursively copies nested structs/arrays)
  • Search and sort:

    • StructFindKey(s, “needle”, “ALL”) // returns array of matches including paths
    • StructFindValue(s, value, “ALL”)
    • StructSort(s, “textnocase”, “asc”) // returns an array of keys sorted by name

Tip: In recent ColdFusion versions, you also have member methods on structs (engine- and version-dependent), but the function-style (StructKeyExists, StructAppend, etc.) is widely compatible and clear.


Ordering and Case Sensitivity

Ordering

  • Regular structs do not guarantee the order of keys during iteration.
  • Use ordered structs when you need predictable ordering:
    • var s = structNew(“ordered”);
  • Algorithmically, ordered structs behave like a linked hash map: they preserve insertion order and make UI rendering or JSON output more predictable.

Case Sensitivity

  • Struct keys are typically case-insensitive for lookups. This means “Name” and “name” refer to the same key.
  • Best practice: choose a consistent key casing (e.g., camelCase) and stick to it for clarity and predictable serialized output.

Error handling and Nulls

  • Accessing a non-existent key with dot notation can throw an error. Always check with StructKeyExists before reading if the key might be missing.
  • Bracket notation with an unknown key also triggers errors in most cases when you attempt to use the value. Use existence checks first.
  • ColdFusion versions with null support (configurable) may return null in some contexts; prefer explicit checks:
    • if (StructKeyExists(s, “k”) && !isNull(s.k)) { … }
See also  What Is ColdFusion Lucee?

Interoperability (JSON, HTTP, Queries)

  • JSON:

    • var json = serializeJSON(user); // struct -> JSON
    • var obj = deserializeJSON(json); // JSON -> struct/array
  • HTTP and forms:

    • URL, FORM, COOKIE, and CGI scopes are structs. Example: URL.id or FORM.email.
  • Argument collections:

    • Some tags and functions accept argumentCollection as a struct to pass named parameters dynamically:
      • myFunc(argumentCollection = { firstName = “Ada”, age = 36 });
  • Queries or records:

    • When fetching rows from a database and transforming them into caches, structs keyed by ID are common:
      • Application.userCache[userId] = rowData;

Use Cases

Configuration and Settings

  • Centralize app settings:
    • Application.config = {
      db = { dsn = “myDSN”, user = “appuser” },
      Features = { enableBeta = true }
      };

Benefits: readable, nested, easy to override via StructAppend for environment-specific configs.

HTTP Parameter Handling

  • The URL and FORM scopes are structs; consolidate and validate inputs:
    • var params = {};
    • if (StructKeyExists(URL, “page”)) params.page = URL.page;

Caching and Lookups

  • Cache complex objects keyed by identifier:
    • lock scope=”Application” type=”exclusive” timeout=5 {
      Application.productCache[productId] = productData;
      }

Real-World Example: User Profile Store in Session

  • Goal: Maintain the current user profile across requests, including preferences and permissions.

Implementation outline:

  • On login:
    • Session.user = {
      id = userId,
      name = dbUser.name,
      roles = dbUser.roles, // array
      prefs = structNew(“ordered”) // maintain predictable order in UI
      };
  • Updating preferences:
    • if (!StructKeyExists(Session, “user”)) throw(“Not authenticated”);
    • Session.user.prefs.theme = “dark”;
    • Session.user.prefs.itemsPerPage = 50;
  • Checking authorization:
    • if (ArrayFind(Session.user.roles, “admin”)) { … }

Why a struct?

  • Fast key-based access (Session.user.prefs.theme).
  • Easy to serialize to JSON for Client-side rendering.
  • Ordered prefs can be shown consistently in a settings page.

Best practices

  • Use the right notation:
    • Dot notation for simple keys; bracket notation for dynamic or special-character keys.
  • Guard access with existence checks:
    • Use StructKeyExists before reading or deleting keys.
  • Choose ordered structs intentionally:
    • When you rely on the display or iteration order, use structNew(“ordered”).
  • Manage concurrency:
    • Structures in shared scopes (Application, Session, Server) are not inherently thread-safe. Use cflock or lock in CFScript for writes and sensitive reads.
  • Copy carefully:
    • Use duplicate() for deep copies (nested structs/arrays). StructCopy is shallow and may lead to unintended shared references.
  • Keep keys consistent:
    • Adopt consistent casing and naming conventions to simplify team usage and JSON output stability.
  • Avoid Evaluate() for dynamic access:
    • Prefer bracket notation (s[dynamicKey]) instead of Evaluate(), for safety and Performance.
  • Validate input early:
    • When turning URL/FORM scopes into your own structs, validate and whitelist keys to prevent unwanted data propagation.
See also  What Is CFTHREAD in ColdFusion?

Performance and Memory Considerations

  • Lookups and updates in structs are generally fast (hash-map-like behavior).
  • Deep nesting increases complexity for read/write operations; consider flattening keys or using clear hierarchical access patterns.
  • Memory:
    • Large nested structs can consume substantial memory. Clear or null out unused keys with StructDelete or StructClear when appropriate.
  • Serialization cost:
    • serializeJSON on big structs can be expensive. Consider only serializing the properties needed for a given response.

Key Points

  • A struct is a key–value map that’s central to CFML development.
  • Use dot or bracket notation to access values. Brackets are safer for dynamic/special keys.
  • For predictable iteration, create an ordered struct.
  • Protect shared structs with locking to avoid Race conditions.
  • Use duplicate() to deep-copy and avoid unintended side effects from shared references.
  • JSON conversion is straightforward with serializeJSON/deserializeJSON.

Comparison: Struct vs. Array vs. Query (Quick View)

  • Struct: key–value pairs, fast lookup by key, unordered by default (use ordered struct to preserve order), great for configuration, dictionaries, caches.
  • Array: index-based list, ordered by index, great for sequences and lists.
  • Query: tabular data structure, row/column access, great for datasets returned from databases.

FAQ

What is the difference between a struct and an array in ColdFusion?

A struct stores values by named keys (like a dictionary), while an array stores values by numeric index. Use a struct when you need fast access via meaningful names (e.g., user.email), and an array when you have an ordered list of items (e.g., a list of product IDs).

When should I use an ordered struct?

Use an ordered struct when you need predictable iteration order—such as rendering fields in a specific sequence, preserving configuration precedence, or producing stable JSON output for front-end consumers.

How do I safely check if a key exists before reading it?

Use StructKeyExists(myStruct, “keyName”). This avoids runtime errors if the key is missing. Combine with isNull checks if your environment enables null support.

What’s the safest way to copy a struct?

Use duplicate() for a deep copy (copies nested structs/arrays fully). StructCopy() creates a shallow copy; nested references remain shared and can lead to side effects if modified.

How do I avoid Race conditions with structs in shared scopes?

Wrap writes (and sensitive reads) inside a lock. Example in CFScript:
lock scope=”Application” type=”exclusive” timeout=5 {
Application.cache[id] = data;
}
This ensures only one thread updates the struct at a time.

About the author

Aaron Longnion

Aaron Longnion

Hey there! I'm Aaron Longnion — an Internet technologist, web software engineer, and ColdFusion expert with more than 24 years of experience. Over the years, I've had the privilege of working with some of the most exciting and fast-growing companies out there, including lynda.com, HomeAway, landsofamerica.com (CoStar Group), and Adobe.com.

I'm a full-stack developer at heart, but what really drives me is designing and building internet architectures that are highly scalable, cost-effective, and fault-tolerant — solutions built to handle rapid growth and stay ahead of the curve.