包含文件中的 ColdFusion 用户定义函数不可用

Posted

技术标签:

【中文标题】包含文件中的 ColdFusion 用户定义函数不可用【英文标题】:ColdFusion User Defined Functions from included file aren't available 【发布时间】:2011-09-07 17:12:51 【问题描述】:

我正在使用 ColdFusion 9。

我包含一个 UDF 库 (UDF_Library.cfm),其中只有几个函数。当我尝试访问这些函数时,我收到一条错误消息,提示“变量 POPUP 未定义”。该库作为 onRequestStart 方法的第一部分包含在 Application.cfc 中。

这是我包含库的方式:

<cfscript>
// INCLUDE UDF_LIBRARY
include "/UDF/UDF_Library.cfm";
</cfscript>         

这是图书馆的内容:

<cfscript>
function popUp() 
    return "AAAAAAAAAAAAAAAAAAAAAAAAAAAAA";

</cfscript>         

我知道该功能有效。当我直接将函数写到文件中并调用该函数时,它工作正常。

<cfscript>
writeOutput(popUp());
function popUp() 
    return "AAAAAAAAAAAAAAAAAAAAAAAAAAAAA";

</cfscript>         

为什么在加载页面的任何部分之前,在 application.cfc 文件的 UDF 中包含该函数时看不到该函数?

【问题讨论】:

【参考方案1】:

我认为此处所有指南中缺少的信息是对了解变量范围如何工作的建议,这与可能在哪个 Application.cfc 事件处理程序中声明函数无关。

Application.cfc 事件处理程序不会对最初在其中声明的事物赋予任何神奇的持久性:仍然需要将任何声明的变量或函数放入适合它们访问方式的范围内。在 onRequestStart(或 onRequest)中声明一个变量并不会神奇地使该变量对请求中的所有内容都可用。而函数只是一个变量。

当你包含一个文件时——就像你正在做的那样——任何变量声明(以及相应的函数声明)都驻留在一个将它们放入的任何范围内。如果一个人声明了一个函数,并且什么都不做,那么这个函数只存在在变量范围内。

如果在 onRequestStart() 中声明了一个函数,它只是 Application.cfc 实例中的一个方法,它在每个请求开始时创建,那么该函数将被放入该 CFC 实例的变量范围内。并且将持续与该 CFC 实例的生命周期一样长。就 onRequestStart() 的执行而言,CFC 实例的持续时间与运行 onRequestStart() 所需的时间一样长。所以没多久。

另一方面,onRequest() 不是事件处理程序(如 onRequestStart() 是),它是一个事件拦截器:它发生而不是事件它拦截。一般来说, onRequest() 包括 - 从字面上 - 被请求的模板。因此,被请求的模板与包含它的 CFC 实例在相同的内存空间中运行(通过 onRequest()),因此包含的模板共享 CFC 实例的变量范围,因此变量范围可用于 onRequest()。因此,如果 onRequest() 包含一个 UDF 库,该库在变量范围内声明了一堆函数……这与 onRequest() 拦截器中包含的主请求文件的变量范围相同。与任何其他 CFC 实例方法(包括文件)相同。

所以... 这样做的结果是,仅在 onRequestStart() 中包含一个充满函数的文件并不能满足您的要求,因为 - 希望现在 - 显而易见的原因。同样,在 onRequest() 中包含一个充满函数的文件并不会赋予它们神奇的持久性:它们只是放在变量范围内。这意味着它们可以被请求的模板以及它包含的任何模板访问。它们不适用于任何自定义标签,也不适用于该请求中使用的任何 CFC 实例。

如果希望某个函数(或“某些函数”)可用于请求中的任何代码,则需要将这些函数放入请求范围(或另一个共享范围)。这样做的方法与任何变量相同:

request.something  = somethingElse;

就是这样。这是唯一的方法。无论您如何包含它,包含一个充满函数的文件都不是您想要做的完整解决方案。

【讨论】:

你已经提供了清晰的地方,只有默默无闻。【参考方案2】:

我相信要使这些函数普遍可用,它们必须包含在 onRequest() 中,而不是 onRequestStart() 中。

【讨论】:

杰森说得对。 UDF 将放置在每个方法本地的variables 范围内。所以onRequestStart 中定义的UDF 在onRequest 中将不可用。如果您需要函数通过整个请求堆栈下降,您需要将它们添加到Request 范围。否则,只需将您的函数包含在 onRequest 中或将它们移动到在整个请求中持久的范围内。您可以在每个方法中通过cfdumping variables 范围进行验证。 所以,这是来自 Ben Nadel 的博客: OnRequestStart() 当页面请求第一次运行时触发。它是一个单线程方法调用。 OnRequest() 当请求的模板需要被处理时触发。 == 那么,这是否表明变量设置和检查应该在 OnRequestStart() 中完成,所有模板包含都应该在 OnRequest() 中完成? 我通常只将onRequestStart 用于安全方面。我将验证对模板的权限,检查并确保用户不在他们不应该在的地方,然后我在onRequest 中处理其余的请求。我也可以使用它来设置持久的Request 范围变量,但仅此而已。【参考方案3】:

我认为最好将 UDF 库存储在应用程序或会话等持久范围内。我个人会遵循 Ben Nadel 在这里讨论的模式:http://www.bennadel.com/blog/257-My-ColdFusion-User-Defined-Function-Library-Structure.htm。

【讨论】:

以上是关于包含文件中的 ColdFusion 用户定义函数不可用的主要内容,如果未能解决你的问题,请参考以下文章

如何在自定义 ColdFusion 日志文件中获得新行?

Coldfusion的createObject()函数如何搜索组件?

ColdFusion/Javascript 转义单引号

ColdFusion cfpdf 缩略图编号不正确

两个表查询(SQL 和 ColdFusion)中的匹配值

从 Objective-C 中的 ColdFusion 布尔返回类型获取 BOOL 的更好方法?