Chris asked:
Recently I had to outsource some CF work as I was under the gun and buried in deadlines. I noticed something in the programmer's code that I had never tried before and never new was possible. What I am looking for is the validity in actually doing it.
The page a was a simple search results form. It took in the search query from either a form using the post method or a url link. However the programmer used code such as this ..
<cfparam name="town" default="">
<cfparam name="city" default="">
and then queried using a simple SELECT * WHERE town='#town#' OR city='#city#'
My question is this - what are the good bads and uglies of using the variable as is and not going through the usual
<cfparam name="url.town" default="">
<cfparam name="url.city" default="">
<cfparam name="form.town" default="">
<cfparam name="form.city" default="">
blah blah blah.
Should I use the seemingly easier way? I like it for sure. But will it bring the dark side down upon my site?
There's a couple of things going on here but I'd like to begin by pointing one thing out. It's a bit off topic from the rest of the conversation but it's probably more important. In your example query you used:
SELECT * WHERE town='#town#' OR city='#city#'
This may have just been Chris writing something quick in an email, but if it really is the code being used then the 'bare' variables need to replaced with cfqueryparam tags as soon as possible. Again - I'm hoping that was just for the email and not the real code - but every time I see SQL like this I speak out. Ok, so let's move on.
What you are seeing is 100% documented expected ColdFusion behavior. When ColdFusion encounters a variable and the scope is not defined, it checks a predefined list of scopes in order to find the variable. From the documentation:
If you use a variable name without a scope prefix, ColdFusion checks the scopes in the following order to find the variable:
Local (function-local, UDFs and CFCs only)
Arguments
Thread local (inside threads only)
Query (not a true scope; variables in query loops)
Thread
Variables
CGI
Cffile
URL
Form
Cookie
Client
And then immediately after the docs go on to say:
Because ColdFusion must search for variables when you do not specify the scope, you can improve performance by specifying the scope for all variables.
I think right there you will find the main reason people don't use unscoped variables. However, I'd probably say the performance penalty is not going to matter for 99.99% of us. In fact, I typically leave the scope off of Variables scoped variables.
I'd say the other reason folks avoid non-scoping (is that even a word/phrase?) is for security reasons. Imagine the following example. (Note - I'm writing this off the top of my head so pardon any typos.)
<h2>Search Page</h2>
<cfif isDefined("search")>
You searched for <cfoutput>#search#</cfoutput>
</cfif>
<cfset results = mycfc.search(search)>
<cfoutput query="results">
etc
</cfoutput>
So note the search variable. You expect this to be form or URL. ColdFusion checks the URL scope first. I could create a link that includes HTML and possibly script elements and send that link to you so that when you click it, you see my 'bad stuff' within the context of the page itself. Changing the code to a more specific form.search or url.search can help prevent this type of issue.
I hope this helps. By the way, while looking for the docs on the order of scope look up, I noticed these two pages that I thought were darn good examples of ColdFusion scopes. I recommend reviewing these or sharing them with new coders. They do a great job of enumerating and describing all of the scopes.