在 CFM 模板中无法访问 ColdFusion 应用程序数据源 属性
ColdFusion Application datasource Property not accessible in CFM Template
以下是 ColdFusion 2018 服务器上的 运行(如果这是特定于版本的问题)。
我正在 onApplicationStart() 生命周期处理程序中设置应用程序数据源 属性,但数据源 属性 在 CFM 模板中不可访问。
我认为这可能与 this
作用域在 onApplicationStart() 方法中的处理方式有关,但我不确定。我尝试使用 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>
test.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 2018 服务器上的 运行(如果这是特定于版本的问题)。
我正在 onApplicationStart() 生命周期处理程序中设置应用程序数据源 属性,但数据源 属性 在 CFM 模板中不可访问。
我认为这可能与 this
作用域在 onApplicationStart() 方法中的处理方式有关,但我不确定。我尝试使用 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>
test.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""}