Ask a Jedi: Where in the heck is this PATH variable coming from?

This post is more than 2 years old.

Dan Vega had an interesting issue today. He noticed that following code would work, even though he didn't create the variable:

<cfoutput> #path# </cfoutput>

My buddy Todd Sharp wasn't able to reproduce this yet I was. Turns out there was a simple explanation. The path value existed in the CGI scope. I was able to confirm this by just doing:

<cfoutput> #path# versus #cgi.path# </cfoutput>

So why couldn't Todd duplicate it? Turns out the path value was supplied by the web server as a CGI variable on the web servers Dan and I tried, but not Todd's, and since the CGI scope is one of the scopes tested when you don't fully scope a variable, the result just worked.

A few interesting things to note about the CGI scope. If you cfdump it, you won't see a PATH value. So why did it work? Since CGI variables are provided by the web server and Adobe doesn't know which CGI vars may exist, I believe that they simply used a set of common variables for the dump.

Another odd thing with the CGI scope is that you can output any variable. If you do:


You will get a blank string. I believe (again, I need confirmation from Adobe on this) they did this because of the fuzzyness in what CGI variables may exist on your web server.

You could consider this an example of why you should always scope your variables, but frankly, I don't bother. I scope everything but Variables in normal CFML templates, and scope everything in CFCs. I only bother scoping Variables stuff in CFCs to help differentiate between the local (unnamed) scope and the Variables scope.

Edit: Turns out - CGI variables depend on the server and the web browser.

Second Edit - Here is quote from the CFML Reference, page 14:

By default, when you use the cfdump tag to display the CGI scope, or when you request debug output of the CGI scope, ColdFusion attempts to display a fixed list of standard CGI environment variables. Because the available variables depend on the server, browser, and the types of interactions between the two, not all variables are normally available, and are represented by empty strings in the debug output. You can request any CGI variable in your application code, including variables that are not in the list variables displayed by dump and debug output.

Raymond Camden's Picture

About Raymond Camden

Raymond is a senior developer evangelist for Adobe. He focuses on document services, JavaScript, and enterprise cat demos. If you like this article, please consider visiting my Amazon Wishlist or donating via PayPal to show your support. You can even buy me a coffee!

Lafayette, LA

Archived Comments

Comment 1 by Mike Rankin posted on 1/3/2008 at 2:29 AM

Wouldn't it be great if there were a switch on the server that just let you set the unnamed scope to "variables"? Code that takes advantage of the scope cascade just feels like horrible kludges to me.

I wonder if there is a reason that the scope cascade has to be maintained other than for backward compatibility issues.

Comment 2 by Ben Nadel posted on 1/3/2008 at 2:31 AM

This can be particularly annoying because it doesn't show misspellings:


... very easily.

Comment 3 by Raymond Camden posted on 1/3/2008 at 2:34 AM

What are these "misspellings" you speak of?

Comment 4 by Scott P posted on 1/3/2008 at 3:27 AM

Looks familiar to this old post:

Comment 5 by Raymond Camden posted on 1/3/2008 at 3:39 AM

Well come on, that was almost two years ago. I got to be allowed to repeat myself _some_ times. ;)

Comment 6 by Adam Cameron posted on 1/3/2008 at 2:17 PM

Just as well they allow misspellings. cgi.REFERER, indeed ;-)


Comment 7 by Geoff posted on 1/3/2008 at 7:15 PM

Another good reason to use StructKeyExists instead of IsDefined:

<cfif structkeyexists(cgi,"scrip_name")>
Key exists!
Key doesn't exist!
<br />
<cfif isdefined("cgi.scrip_name")>
Is defined!
Is not defined!

Comment 8 by Kam posted on 1/3/2008 at 7:21 PM

I remember some version of Apache 2.0.x would also expose environment variables in the CGI scope (on Windows, anyway). I was using a variable called "systemroot" and ran into the same 'wheres this value coming from?' issue. Interestingly, dumping the CGI scope didn't show the environment variables' existence.