Application, Session, and Request Scope in ColdFusion 9

0
134
7 min read

(For more resources on ColdFusion, see here.)

The start methods

We will have a look at the start methods and make some observations now. Each method has its own set of arguments. All Application.cfc methods return a Boolean value of true or false to declare if they completed correctly or not. Any code you place inside a method will execute when the start event occurs. These are the events that match with the name of the method. We will also include some basic code that will help you build an application core that is good for reuse and discuss what those features provide.

Application start method—onApplicationStart()

The following is the code structure of the application start method. You could actually place these methods in any order in the CFC, as the order does not matter. Code that uses CFCs only require the methods to exist. If they exist, then it will call them. We place them in our code so that it helps us to read and understand the structure from a human perspective.

<cffunction name="onApplicationStart" output="false">
<cfscript>
// create default stat structure and pre-request values
application._stat = structNew();
application._stat.started = now();
application._stat.thisHit = now();
application._stat.hits = 0;
application._stat.sessions = 0;
</cfscript>
</cffunction>

There are no arguments for the onApplicationStart() method. We have included some extra code to show you an example of what can be done in this function. Please note that if we change the code in this method, it will only run at the very first time when an application running in ColdFusion is hit. To hit it again, we need to either change the application name or restart the ColdFusion server. The Application variables section that was previously explained shows how to change the application’s name.

From the start methods, we can see that we can access the variable scopes that allow persistence of key information. To understand the power of this object, we will be creating some statistics that can be used in most situations. We could use them for debugging, logging, or in any other appropriate use case. Again, we have to be aware that this only gets hit the first time a request is made to a ColdFusion server for that application. We will be updating many of our statistics in the request methods. We will also be updating one of our variables in the session end method.

Session start method—onSessionStart()

The session start method only gets called when a request is made for a new session. It is good that ColdFusion can keep track of these things. The following is example code that allows us to keep a record of the session-based statistics that is similar to the application-based statistics:

<cffunction name="onSessionStart" output="false">
<cfscript>
// create default session stat structure and pre-request values
session._stat.started = now();
session._stat.thisHit = now();
session._stat.hits = 0;
// at start of each session update count for application stat
application._stat.sessions += 1;
</cfscript>
</cffunction>

You might have noticed that in the previous code we used +=. In ColdFusion prior to version 8, you had to type that particular line in a different way. The following two examples are the same in functionality (example one works in all versions and two works only in version 8 and higher):

  • Example 1: myTotal = myTotal +3
  • Example 2: myTotal += 3

This is common in JavaScript, ActionScript, and many other languages. This syntax was added in ColdFusion version 8. We change the application-based setting because sessions are hidden from one another and cannot see each other. Therefore, we use the application CFC to either count or add a count every time a new session starts.

Request start method—onRequestStart()

This is one of the longest methods in the article. The first thing you will notice is that the script that is called is passed to the onRequestStart() method by ColdFusion. In this example, we will instruct ColdFusion to block any scripts from execution that begin with an underscore when called remotely. This means that you can call the server and request any .cfm page or .cfc page with an underscore at the start, and this protects it from being called outside the local server. The files can still be run if called from pages inside the server. This makes all these files locally accessible:

<cffunction name="onRequestStart" output="false">
<cfargument name="thePage" type="string" required="true">
<cfscript>
var myReturn = true;
//fancy code to block pages that start with underscore
if(left(listLast(arguments.thePage,"/"),1) EQ "_")
{
myReturn = false;
}
// update application stat on each request
application._stat.lastHit = application._stat.thisHit;
application._stat.thisHit = now();
application._stat.hits += 1;
// update session stat on each request
session._stat.lastHit = session._stat.thisHit;
session._stat.thisHit = now();
session._stat.hits += 1;
</cfscript>
<cfreturn myReturn>
</cffunction>

The methods in the following sections are used to update all the application and session statistics variables that need to be updated with each request. You should also notice that we are recording the last time the application or session was requested.

The end methods

Previously, some of the methods in this object were impossible to achieve with the earlier versions of ColdFusion. It was possible to code an end request function, but only a few programmers made use of it. We find that by using this object many more people are taking advantage of these features.

The new methods that are added have the ability to run code specifically when a session ends, and when an application ends. This allows us to do things that we could not do previously. We can keep a record of how long a user is online without having to access the database with each request. When the session starts, you can store it in the session scope. When the session ends, you can take all that information and store it in the session log table if logging is desired in your site.

Request end method—onRequestEnd()

We are not going to use every method that is available to us. As we have the concept from the other sections, this would be redundant. The concepts of this method are very similar to the onRequestStart() method with the exception that it occurs after the requested page has been called. If you create content in this method and set the output attribute to true, then it will be sent back to browser requests. Here you can place the code that logs information about our requests:

<cffunction name="onRequestEnd" returnType="void" output="false">
<cfargument name="thePage" type="string" required="true">
</cffunction>

Session end method—onSessionEnd()

In the session end method, we can perform logging functions for analytical statistics that are specific to the end of a session if desired for your site. You need to use the argument’s scope variables to read both the application and session variables. If you are changing application variables as in our example code, then you must use the argument’s scope for that.

<cffunction name="onSessionEnd" returnType="void" output="false">
<cfargument name="SessionScope" type="struct" required="true">
<cfargument name="ApplicationScope" type="struct" required="false">
<cfscript>
// NOTE: You must use the variable scope below to access the
// application structure inside this method.
arguments.ApplicationScope._stat.sessions -= 1;
</cfscript>
</cffunction>

Application end method—onApplicationEnd

This is our end method for applications. Here is where you can do the logging activity. As in the session method, you need to use the argument’s scope in order to read variables for the application. It is also good to note that at this point, you can no longer access the session scope.

<cffunction name="onApplicationEnd" returnType="void" output="false">
<cfargument name="applicationScope" required="true">
</cffunction>

On Error method—onError()

The following code demonstrates how we can be flexible in managing errors sent to this method. If the error comes from Application.cfc, then the event (or method that had an issue) will be contained in the value of the arguments.eventname variable. Otherwise, it will be an empty string. In our code, we change the label on our dump statement, so that it is a bit more obvious where it was generated.

<cffunction name="onError" returnType="void" output="true">
<cfargument name="exception" required="true">
<cfargument name="eventname" type="string" required="true">
<cfif arguments.eventName NEQ "">
<cfdump var="#arguments.exception#" label="Application core
exception">
<cfelse>
<cfdump var="#arguments.exception#" label="Application
exception">
</cfif>
</cffunction>

LEAVE A REPLY

Please enter your comment!
Please enter your name here