A reader asks:
Is there anyway to share variables between two different applications within one website?
Actually there is a very simple, but slightly dangerous way - the Server scope. As you can guess, the Server scope is global to the ColdFusion server. So any application could set a Server variable and any other application could read it. So why is this dangerous?
-
If you are hosting your sites on an ISP, it is very easy for another customer to view and modify the Server scope. While they probably wouldn't, you can't be certain that your data won't be changed by others. If you use this route, I would only suggest it in a case where you have the entire ColdFusion server to yourself. To be anal, even Application variables aren't safe. If someone can guess the name of your application scope, they can just use the <cfapplication> tag to switch to your application and read/modify values.
-
If you have multiple applications reading and writing to the server scope, then you definitely want to ensure you use <cflock>. If you don't, there is a risk of data getting messed up and corrupted. At least (thank god!) you won't have the memory issues that plagues pre-MX versions of ColdFusion.
I'd highly recommend you build a CFC to make this easier. You can imagine a CFC whose sole purpose is to read and write to the Server scope. This makes your code easier. You can do something like so:
<cfset theVal = application.serverFacade.read("numberpirates")>
Inside the CFC the locks would be handled for you. Ditto for a write:
<cfset application.serverFacade.write("status","Klingons on the starboard bow.")>
What's nice is that if you change your mind about how the data is persisted, your client code doesn't have to change, just your component.
Archived Comments
Maybe a service-oriented architecture (SOA) is a better approach. Still use CFC's but as web services and build the methods for the interchange of data between the applications.
An easier solution would be to replicate the idea of the CLIENT scope.
Create a datasource that is a common repository for transient key-value pairs. All applications can use the same datasource and you would not lose security, modify the server scope (bad mojo) or create an additional HTTP request to get the variable.
If you don't like the database idea, store the variable in an xml file and call it from javascript, webservice, http request...etc.
Although it's rarely a "good thing" to do, you could also just share Application names in the CFAPPLICATION tag. In fact, you can switch among applications with multiple CFAPPLICATION tags -- you could even maintain two different Applications, but still share the variables of one in the other by doing something like:
<cfset currentApplicationName = application.applicationName>
<cfapplication name="NameOfAppFromWhichToShareVars">
<cfset tempAppRef = application>
<cfapplication name="#currentApplicationName#">
<cfset structCopy(currentApplicationName,tempAppRef)>
Again, this is not exactly a best practice, but it is possible. If you have a set of constants shared across applications it would likely make more sense to store them somewhere as XML and then load them up into each application, or build a third "application" that acts as as service to the other two applications.
Another solution might be to do a cfhttp call to the other application which would return a wddx package or use a webservice.
Nathan,
An interesting approach and probably not something I would think of first.
I imagine it will work, but I would think of the next developer behind and how confused he/she will look.
=)
Server scope = scary!
I've actually done some application variable sharing on my production box, mostly because I'm afraid what could happen if I put it live.
I have a single FCKEditor install for multiple blogCFCs on one site, and FCKEditor needs to know a directory location for images, but I don't want one shared folder for all the blogs. I want each blog to have it's own images folder.
So when an admin logs in, I have a UDF that passes some variables using <cfhttpparam> to an setAppVar.cfm file sitting in my FCKEditor directory, which then sets the application variables for the FCKEditor application to use.
Each blog gets it's own unique folder name, and just for good measure I throw in some <cflocks>.
Not sure if it's the best method, but this server cfc thing might be better - *shrug*
If you want the application scope of another application, you can use a java object on the coldfusion server to get the application scope.
<cfset appTracker = createObject("java","coldfusion.runtime.ApplicationScopeTracker")>
<cfdump var="#appTracker.getApplicationScope('application_name')#">
Sean Corfield reminded me on IRC that there is a much easier way to get all app names. Just do:
<cfapplication name="">
Then dump the app scope. You will see a collection of info which also includes all the apps on your site.
I would think that MM would give shared hosting companies the ability to block writting to the server scope all together!
Where can one find all the "java" objects that are accessible by CF? I keep seeing new objects everywhere
> <cfapplication name="">
> <cfdump var="#application#">
Now that's a scary one! I've played with the JAVA object just to see how open my shared servers are, but that method is scary easy. I've seen CC and personal data in some applications, which really makes you re-think how you code in a shared environment.
It just gets me one step closer to a dedicated server...
T