ColdFusion 应用程序数据源属性在 CFM 模板中不可访问

标签 coldfusion

以下内容在 ColdFusion 2018 服务器上运行(如果这是特定于版本的问题)。

我正在 onApplicationStart() LifeCycle 处理程序中设置应用程序数据源属性,但无法在 CFM 模板中访问该数据源属性。

我认为这可能与 onApplicationStart() 方法内处理 this 作用域的方式有关,但我不确定。我尝试使用 this.datasource 以及 Application.datasource 设置数据源属性,但无论如何都无法在 CFM 模板中访问它。

Application.cfc

// The usual App config stuff here... (omitted for brevity) 

// Instantiate Instance of Java System Object used to set System Env Vars
this.System = createObject("java", "java.lang.System");

// Include Config files
include "resources/config/AppSettings.cfm";
include "resources/config/onApplicationStart.cfm";

AppSettings.cfm

if (! isDefined(this.System.getProperty("DB_DSN_CREATED")))
{
    // Code to read values from .env file here ... (omitted for brevity) 

    // Set System Env Vars
    this.System.setProperty("DB_USER_NAME",     "DB USERNAME FROM .ENV FILE HERE");
    this.System.setProperty("DB_USER_PASSWORD", "DB PASSWORD FROM .ENV FILE HERE");
}

onApplicationStart.cfm

if (! isDefined(this.System.getProperty("DB_DSN_CREATED")))
{
    this.datasources = {MY_DSN = { PROPS FOR DB CONNECTION HERE }};

    // *** NOTE: This is the Property that isn't accessible in the CFM Template
    //           I also tried Application.datasource, but that didn't work either
    this.datasource = "MY_DSN";

    this.System.setProperty("DB_DSN_CREATED", true);
}

db-test.cfm

<cfscript>
    variables.appInstance = createObject('component', 'Application');

    variables.sql = "SQL STATEMENT HERE";
    variables.sqlParams = {};

    // *** NOTE: variables.appInstance.datasource below isn't accessible 
    //           I also tried Application.datasource but that didn't work either
    variables.sqlResult = queryExecute(variables.sql, variables.sqlParams, {datasource = variables.appInstance.datasource});

    writeDump(variables.sqlResult);
</cfscript>

有人看到我错过了什么吗?预先感谢您的任何指导!

最佳答案

再仔细考虑一下,我怀疑您可能误解了 Application.cfc 的 this 作用域的运作方式。简短回答:this 并不像 application 范围一样持久,因为组件会在每个请求上实例化

From Defining the application and its event handlers in Application.cfc

When ColdFusion receives a request, it instantiates the Application CFC and runs the Application.cfc code ...

您的代码实际上确实工作。至少从某种意义上说,include 在调用时成功更改了 this.datasource 的值。但是,由于 Application.cfc 在每个请求上都会重新实例化,因此组件的 this 作用域也会重新创建。基本上清除了 OnApplicationStart() 中之前所做的任何更改。这就是为什么代码看起来从未分配数据源值,而实际上却分配了数据源值。

底线是,Application.cfc 的 this 作用域不适合以这种方式使用。


测试用例

FWIW,您可以使用下面的测试文件查看实际行为。只需在浏览器中加载 test.cfm (至少两次),然后检查日志。输出显示应用程序第一次请求 test.cfm 时分配给 this.datasource 的值。但是,该值在下一个 http 请求时消失,因为 CF 创建了一个新的 Application.cfc 实例。

Application.cfc

component 
{
    this.name = "myApp_0001";

    function onApplicationStart(){
        writeLog("onApplicationStart()");
        writeLog(serializeJSON({"name": this.name, "datasource": this?.datasource?: "" }));
        include "onApplicationStart.cfm";
    }
    function onRequestStart( string targetPage ) {
        writeLog("onRequestStart()");
        writeLog(serializeJSON({"name": this.name, "datasource": this?.datasource?: "" }));
    }

}

OnApplicationStart.cfm

<cfscript>
    writeLog("onApplicationStart.cfm");
    writeLog(serializeJSON({"name": this.name, "datasource": this?.datasource?: "" }));
    
    writeLog("Assigning this.datasource");
    this.datasource = "MY_DSN";
    
    writeLog("Post Assign this.datasource");
    writeLog(serializeJSON({"name": this.name, "datasource": this?.datasource?: "" }));
</cfscript>

测试.cfm

<h3>Test.cfm <cfoutput>#now()#</cfoutput></h3>

结果:

Request #1 - this.Datasource gets assigned
[INFO ] ... - onApplicationStart()
[INFO ] ... - {""datasource"":"""",""name"":""myApp_0001""}
[INFO ] ... - onApplicationStart.cfm
[INFO ] ... - {""datasource"":"""",""name"":""myApp_0001""}
[INFO ] ... - Assigning this.datasource
[INFO ] ... - Post Assign this.datasource
[INFO ] ... - {""datasource"":""MY_DSN"",""name"":""myApp_0001""}
[INFO ] ... - onRequestStart()
[INFO ] ... - {""datasource"":""MY_DSN"",""name"":""myApp_0001""}

Request #2 - this.datasource is no longer assigned
[INFO ] ... - onRequestStart()
[INFO ] ... - {""datasource"":"""",""name"":""myApp_0001""}

Request #3 - this.datasource is no longer assigned
[INFO ] ... - onRequestStart()
[INFO ] ... - {""datasource"":"""",""name"":""myApp_0001""}

关于ColdFusion 应用程序数据源属性在 CFM 模板中不可访问,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/71001238/

相关文章:

sql-server-2008 - 如何处理ColdFusion存储过程结果中的错误?

sql-server - sql语句中的Cfloop?

coldfusion - cfquery 名称属性,可选?

actionscript-3 - Flex 4 应用程序,coldfusion 帮助

sql - 在 ColdFusion 中,属性值周围的单引号和双引号有什么作用?

windows - ubuntu 上的 cfdirectory 在 windows 上访问 smbfs 的奇怪问题

coldfusion - 对 ColdFusion 语法(引号和井号)感到困惑

java - coldFusion jvm垃圾收集不是

java - 尝试使用 Smackx pubsub 获取节点时出现 item-not-found(404)

coldfusion - 使用 Coldfusion 创建登录系统