Coldfusion 11 - 全局变量 - Application.cfc 或 Application.cfm
Coldfusion 11 - Global variables - Application.cfc or Application.cfm
我正在开发一个在 Coldfusion 9 中完成的应用程序。我必须将它迁移到 CF11 中,我想改进代码。目前在CF9中的应用是这样实现的:
Application.cfm:
<cfapplication name="MyApp"
clientManagement="yes"
clientStorage="registry"
setClientCookies="yes"
sessionManagement="yes"
sessionTimeout="#CreateTimeSpan(0,1,0,0)#"
applicationTimeout="#CreateTimeSpan(0,0,2,0)#"
/>
<cfset application.datasource = "MyApp"/>
<cfset application.name = "MyApp"/>
<cfset application.access = "App"/>
<cfset application.version = "1.1"/>
<cfset application.title = "My Application"/>
<cfset application.inc_path = "includes"/>
<cfset application.com_path = "components"/>
<cfset application.scripts_path = "scripts"/>
<cfset application.styles_path = "styles"/>
<cfset application.email = "firstname.lastnane@myapplication.com" />
<cfset application.YEAR = 2016/>
<cfif Not IsDefined("session.language_cd")>
<cfset session.language_cd = "ENG">
</cfif>
<cfset session.email_support_team = "support@myapplication.com" />
<cfinclude template="ui_lib.cfm">
在文件“ui_lib.cfm”中,定义了很多变量并在所有其他 .cfm 文件中使用:
<cfswitch expression="#session.ui_lng_cd#">
<cfcase value="FRA">
<cfset ui_lib_abbrev = "Abbréviation" />
<cfset ui_lib_acces = "Accès" />
<cfset ui_lib_active_sans_accent = "Actif" />
</cfcase>
<cfcase value="ENG">
<cfset ui_lib_abbrev = "Abbreviation" />
<cfset ui_lib_acces = "Access" />
<cfset ui_lib_active_sans_accent = "Active" />
</cfcase>
</cfswitch>
例如 menu.cfm:
<div id="menu">
<h5><cfoutput>#session.user#</cfoutput></h5>
<ul>
<li><cfoutput>#ui_lib_abbrev#</cfoutput></li>
<li><cfoutput>#ui_lib_acces#</cfoutput></li>
<li><cfoutput>#ui_lib_active_sans_accent#</cfoutput></li>
</ul>
</div>
我试图创建一个 Application.cfc 来替换 application.cfm:
<cfcomponent displayname="MyApp">
<cfset This.name = "MyApp">
<cfset This.sessionManagement="yes">
<cfset This.clientManagement="no">
<cfset This.loginStorage="session">
<cfset This.sessionTimeout = CreateTimeSpan(0,0,0,1)>
<cfset This.applicationTimeout = CreateTimeSpan(0,0,2,0) >
<cfset This.setClientCookies="no">
<cfset This.domainCookies="yes">
<cfset This.scriptProtect = "All">
<cffunction name="onApplicationStart">
<cfscript>
Application.homePage = "/index.cfm";
Application.datasource = "MyApp";
Application.name = "MyApp";
Application.access = "App";
Application.version = "1.1";
Application.title = "My Application";
Application.inc_path = "includes";
Application.com_path = "components";
Application.scripts_path = "scripts";
Application.styles_path = "styles";
Application.email = "firstname.lastnane@myapplication.com"
Application.YEAR = 2016;
</cfscript>
<cfinclude template="ui_lib.cfm">
</cffunction>
<cffunction name="onSessionStart">
<cfif Not IsDefined("session.language_cd")>
<cfset session.language_cd = "ENG">
</cfif>
<cfif Not IsDefined("session.g_exercice")>
<cfset todayDate = Now()>
<cfset SESSION.g_exercice = #DateFormat(todayDate, "yyyy")#>
</cfif>
<cfif Not IsDefined("session.sec_first_pass")>
<cfset SESSION.sec_first_pass = 0>
</cfif>
<cfset session.email_support_team = "support@myapplication.com" />
</cffunction>
</cfcomponent>
我创建了 application.cfc 并删除了 application.cfm 并尝试 运行 应用程序。没关系,但是 ui_lib.cfm 中定义的变量出现 Coldfusion 错误。服务器说变量未定义。你能告诉我为什么以及如何解决这个问题吗?
我想知道是使用具有相同定义的文件 Application.cfc 还是保留当前文件 Application.cfm 更好?
在此先感谢您的帮助。
您的 UDF 中定义的变量位于 variables
范围内,但通过将 UDF 置于 onApplicationStart()
内,包含仅发生一次而不是每次请求。我想你已经弄清楚了,并在 variables
范围内再次定义了它们。
我觉得更合适的解决方案是将它们放入 application
范围内,这样它们只定义一次,而不是在每次请求时都重新定义。
application.ui = {
"ENG" = {
"abbrev" = "Abbreviation"
, "acces" = "Access"
, "active_sans_accent" = "Active"
}
, "FRA" = {
"abbrev" = "Abbréviation"
, "acces" = "Accès"
, "active_sans_accent" = "Actif"
}
};
然后像这样更新任何现有的引用:#application.ui[session.ui_lng_cd].abbrev#
.
如果您将来管理翻译上下文的需求增加,请查看 Resource Bundles。
我已经完成了一些 cfm 到 cfc 的转换,答案取决于使用情况。如前所述,应用程序范围内基于会话的逻辑将不起作用。
如果有一种方法可以更改用户的语言,从而更新 session.ui_lng_cd 值并因此更新向用户显示的语言,那么最简单的答案是在 OnRequestStart 事件中设置语言变量。在设置和使用时,您必须将变量的范围更改为 request 范围,但希望通过全局搜索和替换这会很容易。
补充说明:
也可以将这些语言变量存储在会话中,方法是将代码放在 OnSessionStart 事件中,但通常最好将会话存储保持在最低限度,就好像您在繁忙时开始在会话中存储很多内容一样网站可能会占用大量内存。
另一种方法需要更多的工作,但我认为如果你有很多这样的方法会更有效,那就是在应用程序中创建一个两级数组来存储语言字符串并将会话语言用作第一级钥匙。这样每次对旧变量的请求只使用很少的内存。
因此在您的 application.cfc OnApplicationStart 中您将拥有:
application.languageStrings = {};
application.languageStrings["ENG"] = {};
application.languageStrings["ENG"]["ui_lib_abbrev"] = "Abbreviation";
application.languageStrings["ENG"]["ui_lib_acces"] = "Access";
application.languageStrings["ENG"]["ui_lib_active_sans_accent"] = "Active";
application.languageStrings["FRA"] = {};
application.languageStrings["FRA"]["ui_lib_abbrev"] = "Abbréviatio";
application.languageStrings["FRA"]["ui_lib_acces"] = "Accès";
application.languageStrings["FRA"]["ui_lib_active_sans_accent"] = "Actif";
要输出您要使用的正确字符串:
#application.languageStrings[session.language_cd]["ui_lib_active_sans_accent"]#
我正在开发一个在 Coldfusion 9 中完成的应用程序。我必须将它迁移到 CF11 中,我想改进代码。目前在CF9中的应用是这样实现的:
Application.cfm:
<cfapplication name="MyApp"
clientManagement="yes"
clientStorage="registry"
setClientCookies="yes"
sessionManagement="yes"
sessionTimeout="#CreateTimeSpan(0,1,0,0)#"
applicationTimeout="#CreateTimeSpan(0,0,2,0)#"
/>
<cfset application.datasource = "MyApp"/>
<cfset application.name = "MyApp"/>
<cfset application.access = "App"/>
<cfset application.version = "1.1"/>
<cfset application.title = "My Application"/>
<cfset application.inc_path = "includes"/>
<cfset application.com_path = "components"/>
<cfset application.scripts_path = "scripts"/>
<cfset application.styles_path = "styles"/>
<cfset application.email = "firstname.lastnane@myapplication.com" />
<cfset application.YEAR = 2016/>
<cfif Not IsDefined("session.language_cd")>
<cfset session.language_cd = "ENG">
</cfif>
<cfset session.email_support_team = "support@myapplication.com" />
<cfinclude template="ui_lib.cfm">
在文件“ui_lib.cfm”中,定义了很多变量并在所有其他 .cfm 文件中使用:
<cfswitch expression="#session.ui_lng_cd#">
<cfcase value="FRA">
<cfset ui_lib_abbrev = "Abbréviation" />
<cfset ui_lib_acces = "Accès" />
<cfset ui_lib_active_sans_accent = "Actif" />
</cfcase>
<cfcase value="ENG">
<cfset ui_lib_abbrev = "Abbreviation" />
<cfset ui_lib_acces = "Access" />
<cfset ui_lib_active_sans_accent = "Active" />
</cfcase>
</cfswitch>
例如 menu.cfm:
<div id="menu">
<h5><cfoutput>#session.user#</cfoutput></h5>
<ul>
<li><cfoutput>#ui_lib_abbrev#</cfoutput></li>
<li><cfoutput>#ui_lib_acces#</cfoutput></li>
<li><cfoutput>#ui_lib_active_sans_accent#</cfoutput></li>
</ul>
</div>
我试图创建一个 Application.cfc 来替换 application.cfm:
<cfcomponent displayname="MyApp">
<cfset This.name = "MyApp">
<cfset This.sessionManagement="yes">
<cfset This.clientManagement="no">
<cfset This.loginStorage="session">
<cfset This.sessionTimeout = CreateTimeSpan(0,0,0,1)>
<cfset This.applicationTimeout = CreateTimeSpan(0,0,2,0) >
<cfset This.setClientCookies="no">
<cfset This.domainCookies="yes">
<cfset This.scriptProtect = "All">
<cffunction name="onApplicationStart">
<cfscript>
Application.homePage = "/index.cfm";
Application.datasource = "MyApp";
Application.name = "MyApp";
Application.access = "App";
Application.version = "1.1";
Application.title = "My Application";
Application.inc_path = "includes";
Application.com_path = "components";
Application.scripts_path = "scripts";
Application.styles_path = "styles";
Application.email = "firstname.lastnane@myapplication.com"
Application.YEAR = 2016;
</cfscript>
<cfinclude template="ui_lib.cfm">
</cffunction>
<cffunction name="onSessionStart">
<cfif Not IsDefined("session.language_cd")>
<cfset session.language_cd = "ENG">
</cfif>
<cfif Not IsDefined("session.g_exercice")>
<cfset todayDate = Now()>
<cfset SESSION.g_exercice = #DateFormat(todayDate, "yyyy")#>
</cfif>
<cfif Not IsDefined("session.sec_first_pass")>
<cfset SESSION.sec_first_pass = 0>
</cfif>
<cfset session.email_support_team = "support@myapplication.com" />
</cffunction>
</cfcomponent>
我创建了 application.cfc 并删除了 application.cfm 并尝试 运行 应用程序。没关系,但是 ui_lib.cfm 中定义的变量出现 Coldfusion 错误。服务器说变量未定义。你能告诉我为什么以及如何解决这个问题吗?
我想知道是使用具有相同定义的文件 Application.cfc 还是保留当前文件 Application.cfm 更好?
在此先感谢您的帮助。
您的 UDF 中定义的变量位于 variables
范围内,但通过将 UDF 置于 onApplicationStart()
内,包含仅发生一次而不是每次请求。我想你已经弄清楚了,并在 variables
范围内再次定义了它们。
我觉得更合适的解决方案是将它们放入 application
范围内,这样它们只定义一次,而不是在每次请求时都重新定义。
application.ui = {
"ENG" = {
"abbrev" = "Abbreviation"
, "acces" = "Access"
, "active_sans_accent" = "Active"
}
, "FRA" = {
"abbrev" = "Abbréviation"
, "acces" = "Accès"
, "active_sans_accent" = "Actif"
}
};
然后像这样更新任何现有的引用:#application.ui[session.ui_lng_cd].abbrev#
.
如果您将来管理翻译上下文的需求增加,请查看 Resource Bundles。
我已经完成了一些 cfm 到 cfc 的转换,答案取决于使用情况。如前所述,应用程序范围内基于会话的逻辑将不起作用。
如果有一种方法可以更改用户的语言,从而更新 session.ui_lng_cd 值并因此更新向用户显示的语言,那么最简单的答案是在 OnRequestStart 事件中设置语言变量。在设置和使用时,您必须将变量的范围更改为 request 范围,但希望通过全局搜索和替换这会很容易。
补充说明:
也可以将这些语言变量存储在会话中,方法是将代码放在 OnSessionStart 事件中,但通常最好将会话存储保持在最低限度,就好像您在繁忙时开始在会话中存储很多内容一样网站可能会占用大量内存。
另一种方法需要更多的工作,但我认为如果你有很多这样的方法会更有效,那就是在应用程序中创建一个两级数组来存储语言字符串并将会话语言用作第一级钥匙。这样每次对旧变量的请求只使用很少的内存。
因此在您的 application.cfc OnApplicationStart 中您将拥有:
application.languageStrings = {};
application.languageStrings["ENG"] = {};
application.languageStrings["ENG"]["ui_lib_abbrev"] = "Abbreviation";
application.languageStrings["ENG"]["ui_lib_acces"] = "Access";
application.languageStrings["ENG"]["ui_lib_active_sans_accent"] = "Active";
application.languageStrings["FRA"] = {};
application.languageStrings["FRA"]["ui_lib_abbrev"] = "Abbréviatio";
application.languageStrings["FRA"]["ui_lib_acces"] = "Accès";
application.languageStrings["FRA"]["ui_lib_active_sans_accent"] = "Actif";
要输出您要使用的正确字符串:
#application.languageStrings[session.language_cd]["ui_lib_active_sans_accent"]#