Coldfusion syntax - how to use Evaluate
-
10-02-2021 - |
Question
I'm trying to determine if a variable with a variable name is defined. Please help with my syntax... my attempts so far:
<cfif isDefined(Evaluate("session['#url.sessionSQL#']['SQL_ALL']"))>
<cfif isDefined('Evaluate("session[#url.sessionSQL#]")["SQL_ALL"]')>
<cfif isDefined(Evaluate("session['#url.sessionSQL#']['SQL_ALL']"))>
<cfif isDefined('session[Evaluate("#url.sessionSQL#")]["SQL_ALL"]')>
<cfif isDefined('session["#url.sessionSQL#"]["SQL_ALL"]')>
Thanks.
Solution
Your question is a little confusing ;)
If session[url.sessionSQL]['SQL_ALL'] contains the name of a variable, you can use structKeyExists to verify that variable exists in a particular scope.
<cfif structKeyExists(scopeToCheck, "TestForThisVariableName")>
... ie
<cfif structKeyExists(variables, session[url.sessionSQL].SQL_ALL)>
On the other hand, if just want to verify those session variables exist
<cfif structKeyExists(session, url.sessionSQL) AND
structKeyExists(session[url.sessionSQL], "SQL_ALL")>
Either way, you do not need the evaluate() function.
Update: From comments, a key difference between IsDefined
and StructKeyExists
is precision. IsDefined examines a whole list of scopes when deteriming if a variable exists. Usually (though not always) that is undesirable because it can lead to unexpected results if you forget a particular variable exists in multiple scopes. (Using IsDefined
inside a function is a prime example.) When you specifically want to check multiple scopes, then IsDefined()
is more appropriate. Otherwise, I would stick with StructKeyExists
as its results are less ambiguous.
OTHER TIPS
Even though the answer below from Henry is best, I will point out the problem with your syntax above.
You want the string inside of isDefined() to be evaluated to a string but it is in quotes (which of course is required for isDefined() because it expects the name of a variable, not an actual variable. So you need hashmarks to make evaluate() run within the quotes.
<cfif isDefined('#Evaluate("session[url.sessionSQL]")#["SQL_ALL"]')>
Otherwise it is looking for a variable named "session[#url.sessionSQL#]")["SQL_ALL"]"
I did not actually test this, but I believe this should work. But clearly, the other way is MUCH better.
<cfif isDefined("#session[url.sessionSQL].SQL_ALL#")>
update
Assuming the name of the variable you want to check is stored in session[url.sessionSQL].SQL_ALL
, but the pieces may not have been defined in url
nor session
nor in SQL_ALL
Then the safest version:
<cfif isDefined("url.sessionSQL")
and isDefined("session[url.sessionSQL]")
and isDefined("session[url.sessionSQL].SQL_ALL")
and isDefined("#session[url.sessionSQL].SQL_ALL#")>
EDIT:
As it turns out, Leigh's answer above works just fine, but not Henry's. In the interim, I found my own solution, as follows.
In the original question, I had a struct
"#session#"
which had an element referenced by a variable
"#url.sessionSQL#"
in other words,
"#session[sessionSQL]#"
and I was trying to find whether that element had a structKey defined, named "SQL_ALL". I was able to make things work like so:
<cfset sessionSQL = #session[url.sessionSQL]# />
<cfif structKeyExists(sessionSQL, "SQL_ALL")>