Definition
cfparam (the ColdFusion tag <cfparam> or its CFScript equivalent param) is a built‑in way to declare that a variable should exist and to optionally give it a default value and validation rules. In simple terms: it ensures a variable is present, sets a default if it isn’t, and throws an error if an existing value doesn’t meet your requirements.
Why CFParam Matters
Using <cfparam> (or param) improves robustness, Security, and readability. It prevents “undefined variable” errors, centralizes input validation for URL/FORM parameters, and documents expected types and ranges for future maintainers.
How It Works
Behavior Overview
- If the variable does not exist:
- If you provided a
default, CF sets the variable to that value. - If you did not provide a
default, CF throws an error indicating the variable is required.
- If you provided a
- If the variable exists:
- CF validates it against any provided attributes (e.g.,
type,pattern,min,max,maxlength). If validation fails, CF throws an error.
- CF validates it against any provided attributes (e.g.,
Common Attributes
- name (required): The scoped variable to check/initialize (e.g.,
url.id,form.email,session.locale). - default: The value to assign if the variable is missing.
- type: Enforces a data type. Common types include
string,numeric,boolean,date,array,struct,query(support varies slightly by engine/version). - pattern: A regular expression for string validation.
- min / max: Numeric or date range checking.
- maxlength: Maximum length for strings.
Tip: If the variable exists but is an empty string, it still “exists.” Whether that should pass depends on your type, pattern, and other checks. Use additional logic if you want to treat empty as missing.
Basic Syntax Examples
Tag-based:
Script-based:
param name=”url.page” type=”numeric” default=1 min=1;
param name=”form.email” type=”string” pattern=”^[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+.[A-Za-z]{2,}$”;
Scope Awareness
Where You Use CFParam
- URL scope:
url.*for query string parameters. - FORM scope:
form.*for POSTed form fields. - COOKIE scope:
cookie.*to initialize/validate cookie inputs. - SESSION/APPLICATION: Initialize configurable app/session defaults.
- REQUEST/VARIABLES: Sanity-check local or request-level variables.
Example:
Step-by-Step: What Happens at Runtime
- CF encounters
<cfparam>at the top of your template or component method. - It looks up the variable by scope and key (e.g.,
url.id). - If not found and
defaultis present, CF assigns the default. - If not found and
defaultis missing, CF throws a “required parameter missing” error. - If found, CF validates the value; if validation fails, it throws an error.
- Execution continues with a guaranteed variable that meets the conditions.
Practical Use Cases
1) Hardening Request Entry Points
You expect url.page to be a number and url.sort to be one of defined options.
Now url.page can’t be something like “abc,” and url.sort is constrained to your allowed list.
2) Safer Form Handling
Enforce a valid email and a non-empty username:
With no default for username, missing values cause a controlled error early.
3) Application Defaults
Ensure an app-level Configuration exists:
4) Real-World Example: Product Search Page
A product search endpoint might accept a search term, page number, and sorting:
SELECT p.*
FROM Products p
WHERE 1=1
AND p.Name LIKE
ORDER BY
OFFSET
ROWS FETCH NEXT 20 ROWS ONLY
cfparam ensures your URL inputs are sane before they affect Business logic or Database access.
Best practices
Place CFParam Early
- Put
<cfparam>blocks at the top of templates or method bodies. This acts as self-documentation and defensive programming.
Be Explicit With Types and Ranges
- Use
type,min,max,pattern, andmaxlengthto guard against invalid inputs. - Favor strict checks for any user-controlled input (URL, FORM, COOKIE).
Pair With cfqueryparam
- cfparam does not sanitize SQL by itself. Always use
<cfqueryparam>when building queries to prevent SQL injection.
Treat Empty Values Deliberately
- If empty strings are unacceptable, ensure your type/pattern rejects them or add logic:
<cfif NOT Len(Trim(form.username))> throw or set a default
Choose the Right Tool: cfparam vs cfargument
- Use
cfargumentinside functions/methods to define argument requirements. - Use
cfparamfor variables from scopes like URL, FORM, SESSION, or for page-level defaults.
CFScript Equivalent
- Prefer the script form in components or script-based codebases:
param name=”url.id” type=”numeric” default=1;
Comparisons and Alternatives
CFParam vs structKeyExists/isDefined
structKeyExists(scope, "key")andisDefined("scope.key")only tell you if a variable exists; you still need to set defaults and validate.cfparamcombines existence check, defaulting, and validation in one place, with clear, declarative intent.
CFParam vs cfargument
cfargumentis for function signatures (arguments), supportingrequiredanddefault.cfparamis for scoped variables in pages or component methods and can apply type and range validation to incoming request data.
Key Points
- Purpose: Guarantee a variable exists and optionally validate it.
- Scopes: Works with
url,form,cookie,session,application,request, etc. - Validation:
type,pattern,min,max,maxlengthgive you strong input validation. - Error handling: Missing required data or invalid values cause early, explicit errors.
- Security: Helps enforce types and formats; still use
cfqueryparamfor database safety and additional sanitization as needed.
Pros and cons
Pros
- Concise and readable initialization and validation.
- Prevents undefined-variable errors.
- Encourages consistent, centralized input handling.
- Works across all common scopes in ColdFusion.
Cons
- Doesn’t automatically treat empty strings as missing.
- Not a substitute for SQL parameterization or full security validation.
- Supported types/pattern Features may vary slightly by engine/version (Adobe ColdFusion vs Lucee).
Advanced Notes
- If you need to set a true null as a default, behavior can vary by engine/version. Many developers avoid null defaults and use sentinel values instead (e.g., empty string or zero) and handle null semantics in code.
- When validating enumerations, use
patternwith a strict regex or a whitelist test (e.g.,listFindNoCase("name,price,rating", url.sort)).
Frequently Asked Questions
Does CFParam override existing values?
No. If the variable already exists, <cfparam> does not change it; it only validates it. The default is applied only when the variable is missing.
Should I use CFParam or cfargument in my CFCs?
Use cfargument to declare function arguments. Use cfparam inside a function when you need to validate/initialize variables from scopes like url, form, or session, or when you want to enforce defaults for non-argument variables.
Where should I place CFParam statements?
At the top of a template or method body. This centralizes defaults and validation, making the code easier to understand and more resilient.
Can CFParam prevent SQL injection?
It helps by enforcing types and patterns for inputs, but it’s not sufficient alone. Always use <cfqueryparam> inside your queries for true SQL injection protection.
How do I write CFParam in CFScript?
Use the param statement:
param name=”url.page” type=”numeric” default=1 min=1;
This is equivalent to <cfparam name="url.page" type="numeric" default="1" min="1">.
