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



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

我正在onApplicationStart((生命周期处理程序中设置Application数据源属性,但数据源属性在CFM模板中不可访问。

我认为这可能与onApplicationStart((方法中如何处理thisScope有关,但我不确定。我尝试使用this.datasourceApplication.datasource设置数据源属性,但在CFM模板中都无法访问。

应用程序.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);
}

数据库测试.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作用域一样,因为组件在每次请求时都会被实例化

从中定义应用程序及其事件处理程序Application.cfc

当ColdFusion接收到请求时,它实例化应用程序CFC并运行Application.CFC代码。。。

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

总而言之,Application.cfc的this作用域不打算以这种方式使用。


测试用例

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

应用程序.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""}

最新更新