Copy link to clipboard
Copied
MIgrating sites from application.cfm to application.cfc and had a simple question. Does every variable I set in application.cfc (application.dsn, session.sitename, etc.) need to be called with it's prefix (#application.dsn#, #session.sitename#) in all the other pages in the site or can I just call it by the variable name without the prefix? I ask this because all the var's set in the existing application.cfm were set without a prefix and I really dont want to go through the entire site adding the prefix to every variable.
Thanks in advance
Ah you need to set local "variable" scope variables. In an Applicaiton.cfc file you can only do that in the OnRequestStart and|or OnRequst functions.
My first guess would be an OnRequest function that may look a bit like this.
<cffunction name="onRequest">
<cfargument name="targetPage" type="String" required=true/>
<cfset dbs = 'mydb'>
<cfset sitename = 'mysite'>
<cfinclude template="#Arguments.targetPage#">
</cffunction>
Note the <cfinclude...> line. That is requred to get the act
...Copy link to clipboard
Copied
It will still work with out the scope preface just like from an Applicaiton.cfm files. But it is still just as bad as pratice as it has always been.
The problem is that if there is no scope preface, the ColdFusion starts searching through a set list of scopes until it finds a matching variable. Sooner or later an applicaiton will be modified creating a conflict with a variable with the same name in more then one scope. Then it can be quite possible for ColdFusion to find the wrong one. This will cause logic errors that can be very hard and expensive to track down.
But ColdFusion will not enforce this best pratice on you.
Copy link to clipboard
Copied
Thanks Ian,
I agree with respect to the prefixing of scopes. Same policy is applied to relational db's in SK and FK as oppposed to a simple ID for your key. Back to the matter at hand. I was unable to call any vars set in application.cfc wihtout the prefix. I tried application.varname, request.varname, session.varname (obviously varname is an alias) and was only able to output the variable with the prefix. I might also mention any change to the OnApplicationStart function required a server restart though not related to this post, still good to know. So any other thoughts on this?
Copy link to clipboard
Copied
I would need to see some code examples on how and where you where trying to set and call these various variables to have a better idea of what you are describing. There are some definite rules in an Appliaiton.cfc on where you can define certain variable scopes.
As to the need to restart the server for changes in onApplicationStart, that is strictkly not necessary. As the name implies, code in that function will run only when An 'Application' starts. With the default setting for a ColdFusion server being '2 days' for how long an Application lives after any HTTP requests for a file belonging to that application was made, this can be a rather rare event.
Other ways to trigger new 'application' starts is to change the name of the application, i.e. this.name property in Application.cfc OR to set the application timeout to something much shorter then 2 days. Usually with the this.applicationtimeout property so that the short time out only applies to the one application, but one can do this with the global property in the ColdFusion Administrator portal as well, if one wants the short timeout to apply to all the applications running on the ColdFusion application server.
Copy link to clipboard
Copied
FYI I tried to reduce the application timeout to 1 minute but was unsuccessful. I am guessing the reason for this is the application is still running under the 2 day timeout. (CF 8, Win2003, IIS6)
Here is a piece of application.cfc
<cfcomponent output="false">
<cfset this.name = "donnie">
<cfset this.applicationTimeout = createTimeSpan(0,0,2,0)>
<cfset this.clientManagement = true>
<cfset this.clientStorage = "registry">
<cfset this.loginStorage = "session">
<cfset this.sessionManagement = true>
<cfset this.sessionTimeout = createTimeSpan(0,0,1,0)>
<cfset this.setClientCookies = false>
<cfset this.setDomainCookies = false>
<cfset this.scriptProtect = false>
<cffunction name="onApplicationStart" returntype="boolean" output="true">
<cfset application.dbs = 'my_db'>
<cfreturn true>
</cffunction>
</cfcomponent>
=============================================
Here is the call on a test page
<cfif isdefined('application.dbs')>
WITH PREFIX:
<cfoutput>#rapplication.dbs#</cfoutput><br>
WITHUOT PREFIX:
<cftry>
<cfoutput>#dbs#</cfoutput>
<cfcatch type="any">
ERROR
</cfcatch>
</cftry>
<Cfelse>
NOT HERE
</cfif>
Copy link to clipboard
Copied
Learn (relearn) something every day.
I tried you code and got the same results, so then I went to the documentation and lol and behold there is the answer.
http://livedocs.adobe.com/coldfusion/8/htmldocs/Variables_32.html
Evaluating unscoped variables
If you use a variable name without a scope prefix, ColdFusion checks the scopes in the following order to find the variable:
- Function local (UDFs and CFCs only)
- Thread local (inside threads only)
- Arguments
- Variables (local scope)
- Thread
- CGI
- Cffile
- URL
- Form
- Cookie
- Client
As you can see from that list, the Application scope is not, and never was, one of the scopes ColdFusion will search for an unscoped variable name.
Copy link to clipboard
Copied
Yes and I dont see "session" or "request". So I am guessing I can set any unscoped variables that I want to call as a cookie in the application.cfc?
Plus I cant understand why a URL variable would trump a form variable (unscoped). That seems strange they would place priority on a variable anyone can change in a URL over a hidden form variable that cant be changed.
Copy link to clipboard
Copied
Duke Snyder wrote:
I cant understand why a URL variable would trump a form variable (unscoped). That seems strange they would place priority on a variable anyone can change in a URL over a hidden form variable that cant be changed.
I guess they chose the older scope to come first. It is a misconception that can be very dangerous that a hidden form variable can not be changed. It is just as easy to change form variable, hidden or otherwise, as it is to change a URL variable for anybody who would actually be interested in trying.
I do not understand your comment about setting unscoped variables as a cookie? I can not imagine any common reason to do such a thing.
It may be important to understand that this scope issue has nothing to do with whether the variables are set in an Application.cfm file or an Applicaiton.cfc file. The same scopes would have been searched and the others would not have been.
So going back to your original post, there should be no change to the behavior of these variables from changing to a Applicaiton.cfc from the older Application.cfm file.
Copy link to clipboard
Copied
The issue is this. I am working with an existing site and it is very large. They set a dozen variables in application.cfm
<cfset dbs = 'mydb'>, <cfset sitename = 'mysite'>, etc. These site wide variables are called hundreds of times through the site as #dbs# and #sitename#.
When I change to application.cfc these varables will no longer be available. I am looking for a way to make them available without replacing every #dbs# with a #application.dbs#. Any suggestions Ian?
Copy link to clipboard
Copied
AND how would you change a hidden form variable before posting to a cfm page looking for the variable? (without creating the page on another site and posting it to the script url)
Copy link to clipboard
Copied
Well first off, doing just that creating a copy of the page on my local workstation and submitting it to your server is dirt simple to do.
But beyond that, there are inumerable tools out there that one can use that allow one to have control of the requests sent back and forth between the browser and the server. In fact many of the tools can be added to a browser. They are developed as debugging tools, usually, but they can be used for much more then that.
It is one of the biggest concepts in security NEVER TRUST DATE FROM A USER, there is no way to confirm that the data has not been manimpulated in some manner.
Copy link to clipboard
Copied
Ah you need to set local "variable" scope variables. In an Applicaiton.cfc file you can only do that in the OnRequestStart and|or OnRequst functions.
My first guess would be an OnRequest function that may look a bit like this.
<cffunction name="onRequest">
<cfargument name="targetPage" type="String" required=true/>
<cfset dbs = 'mydb'>
<cfset sitename = 'mysite'>
<cfinclude template="#Arguments.targetPage#">
</cffunction>
Note the <cfinclude...> line. That is requred to get the actual content of the request file. I would sugest you read up on the onRequst method. It has some well know gotcha's when one starts trying to use AJAX, web services or Flash Remoting requests
Copy link to clipboard
Copied
I had already tried that with and without using the scope prefix in the cfc without luck. The only way I could call it from a page was with the prefix in the cfc and on the page I called it from.
<cffunction name="onRequestStart" returnType="boolean" output="false">
<cfargument name="thePage" type="string" required="true">
<cfset request.dsn = "mydsn">
<cfreturn true>
</cffunction>
<cffunction name="onSessionStart" returnType="void" output="false">
<cfset session.dsn2 = mydsn>
</cffunction>
Copy link to clipboard
Copied
Yes, the documentation says that if you want to set local variables in the OnRequestStart function you must also include an onRequest method that includes the body of the requested file. Otherwise the OnRequestStart function only has accesss to the request scope.
So rather then spit all that into two functions, I just did it all in the OnRequest function.
Copy link to clipboard
Copied
that was exactly what I was looking for. Thanks for your time and effort on my behalf Ian.