每个请求的应用程序范围变量都将刷新

时间:2019-04-03 11:42:46

标签: coldfusion coldfusion-2016 application.cfm

我们已将ColdFusion应用程序从ColdFusion 10迁移到ColdFusion2016。迁移之后,应用程序变量不再停留在其范围内,而是在每个请求中刷新。

考虑以下示例,

Application.cfm

<cfsetting enablecfoutputonly="true" />

<CFAPPLICATION  NAME="Test App"
                SETCLIENTCOOKIES="YES"
                CLIENTMANAGEMENT="YES"
                SESSIONMANAGEMENT="YES"
                SESSIONTIMEOUT="#CREATETIMESPAN(0,8,0,0)#"                                   
                APPLICATIONTIMEOUT="#CREATETIMESPAN(1,0,0,0)#">

<cfdump var="#Application#" label="app">

<CFLOCK SCOPE="APPLICATION" TYPE="EXCLUSIVE" TIMEOUT="10">
    <CFSET Application.Email = "test@test.com">
    <CFSET Application.DataSource="test">
</cflock>

Test.cfm

<CFLOCK SCOPE="APPLICATION" TYPE="READONLY" TIMEOUT="10">
    <cfset Application.one = 1>
    <cfset Application.two = 2>
    <cfset Application.three = 3>
</cflock>

OnRequestEnd.cfm

<cfsetting showdebugoutput="false" />
<cfdump var="#Application#" label="onRequestEnd">

因此,如果我们请求/test.cfm 它会抛出以下输出 enter image description here

再次刷新页面也将提供相同的输出 enter image description here

不确定为什么应用程序范围的变量会丢失其持久性。

以下是预期的输出。

enter image description here

关于为什么每个请求中的应用程序变量都会丢失并得到刷新的任何想法?

1 个答案:

答案 0 :(得分:2)

我尚未测试此代码,但是您看到的是Application.cfm执行的程序操作顺序。您实质上是在每个请求上都重新定义应用程序,这就是为什么名称存在于初始转储中,而其余名称存在于onRequestEnd中的转储中的原因。

如果您更新代码以使用Application.cfc,则可以放弃cflock代码,更好地组织“触发器”,并在需要时使用onApplicationStart一次定义应用程序变量。

<cfcomponent>

    <cfset this.name = "Test App">
    <cfset this.SETCLIENTCOOKIES="YES">
    <cfset this.CLIENTMANAGEMENT="YES">
    <cfset this.SESSIONMANAGEMENT="YES">
    <cfset this.SESSIONTIMEOUT="#CREATETIMESPAN(0,8,0,0)#">
    <cfset this.APPLICATIONTIMEOUT="#CREATETIMESPAN(1,0,0,0)#">
    <cfsetting enablecfoutputonly="true" />

    <cffunction name="onApplicationStart" access="public" returnType="void" output="false">
        <cfset application.Email = "test@test.com">
        <cfset application.DataSource="test">
    </cffunction>

    <cffunction name="onRequestStart" access="public" returntype="boolean" output="false">

        <cfset application.one = 1>
        <cfset application.two = 2>
        <cfset application.three = 3>

        <cfreturn true>
    </cffunction>

    <cffunction name="onRequestEnd" access="public" returntype="boolean" output="false">

        <cfsetting showdebugoutput="false" />
        <cfdump var="#application#" label="onRequestEnd">

        <cfreturn true>
    </cffunction>

</cfcomponent>

这应该在应用首次加载时一次在应用范围内定义emaildatasource。变量onetwothree将在每个请求开始时创建,但是您可以添加检查以仅在变量不存在时对其进行设置。

然后,您可以使用子Application.cfc文件使用子文件夹和特定于子应用程序的变量来帮助您的应用程序模块化。它们仍将存在于较大的应用程序范围内,但是您可以通过这种方式从特定于子应用程序的位置管理它们。