Переменные области приложения обновляются для каждого запроса - PullRequest
4 голосов
/ 03 апреля 2019

Мы перенесли приложение 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 это выдаст следующий вывод enter image description here

Снова обновляет страницу и выдает тот же результат enter image description here

Не уверен, почему переменные в области приложения теряют свое постоянство.

следующий ожидаемый результат ..

enter image description here

Есть идеи, почему переменные приложения теряются и обновляются при каждом запросе?

1 Ответ

2 голосов
/ 03 апреля 2019

Я не тестировал этот код, но вы видите процедурный порядок операций, выполняемых 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>

Это должно определить email и datasource в области приложения один раз, когда приложение загружается впервые. Переменные one, two и three будут создаваться в начале каждого запроса, но вы можете добавить проверку, чтобы установить их, только если они еще не существуют.

Затем вы можете использовать дочерние Application.cfc файлы, чтобы упростить модульную настройку вашего приложения, используя подпапки и переменные, специфичные для вложенных приложений. Они по-прежнему будут существовать в рамках более крупного приложения, но таким образом вы сможете управлять ими из местоположения, определенного для дополнительного приложения.

...