【问题标题】:Application scoped variables are getting refreshed for each requests应用程序范围的变量正在为每个请求刷新
【发布时间】:2019-04-03 11:42:46
【问题描述】:

我们已将 ColdFusion 应用程序从 ColdFusion 10 迁移到 ColdFusion 2016。迁移后,应用程序变量不在其范围内,而是在每次请求时都会刷新。

考虑以下示例,

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 它会抛出以下输出

再次刷新页面也给出相同的输出

不确定为什么 Application 范围的变量会失去持久性。

以下是预期的输出..

知道为什么应用程序变量会丢失并在每次请求时刷新吗?

【问题讨论】:

  • @Rajesh,Application.cfm 页面中的&lt;cfdump var="#Application#" label="app"&gt; 只是在Test.cfm 页面运行之前运行。一旦该页面运行,则应用程序变量已设置。所以页面的下一个请求/刷新会显示它们。由于您使用的是较新版本的 ColdFusion,因此您应该停止使用 Application.cfm 并切换到 Application.cfc。它使您可以更好地控制处理生命周期。
  • @Miguel-F 在下一个请求中,输出也是相同的,这就是我来 SO :)。 Application.cfc,我们可以使用,但应用程序在迁移后来到我这里:)
  • 除此之外 - 您的第二个应用程序锁是只读的,但我认为这不会影响问题。
  • @Kannan.P 是的,我同意除了本地环境很可能与服务器环境不完全匹配(否则它们的行为方式相同)。跨度>
  • ...和相同的操作系统,相同的操作系统版本,相同的操作系统补丁,相同的java版本,等等等等等等

标签: coldfusion coldfusion-2016 application.cfm


【解决方案1】:

我没有测试过这段代码,但你看到的是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 文件来帮助使用子文件夹和子应用程序特定变量来模块化您的应用程序。它们仍然存在于更大的应用程序的范围内,但您可以通过这种方式从特定于子应用程序的位置管理它们。

【讨论】:

  • 正是我试图在 cmets 中向他们传达的内容,但没有时间创建答案。感谢发帖。
猜你喜欢
  • 2018-07-13
  • 2019-07-26
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-04-27
相关资源
最近更新 更多