ColdFusion - 何时使用“请求”范围?

时间:2008-08-25 04:59:25

标签: coldfusion railo cfml

一直在查看我的前任代码并经常查看“请求”范围的用法。该范围的适当用法是什么?

4 个答案:

答案 0 :(得分:19)

代码的任何部分都有几个范围:会话,客户端,Cookie,应用程序和请求。有些不建议以某种方式使用(即在自定义标签或CFC中使用请求或应用程序范围;这是coupling,违反封装原则,并且被认为是一种不好的做法),有些具有特殊用途:Cookie是作为物理cookie保留在客户端计算机上,会话作用域变量是特定于用户的,并在网站上与用户的会话一起过期。

如果一个变量极不可能改变(对于所有意图和目的都是常量)并且可以简单地在应用程序启动时初始化并且永远不会再次写入,通常应该将它放入应用程序范围,因为这会在每个用户和每个会话之间持续存在。正确实现后,它会被写入一次并读取N次。

Application.cfm中Application变量的正确实现可能如下所示:

<cfif not structKeyExists(application, "dsn")>
    <cflock scope="application" type="exclusive" timeout="30">
        <cfif not structKeyExists(application, "dsn")>
            <cfset application.dsn = "MyDSN" />
            <cfset foo = "bar" />
            <cfset x = 5 />
        </cfif>
    </cflock>
</cfif>

请注意,在锁定之前和之后检查应用程序范围中是否存在变量,这样如果两个用户在应用程序启动时创建竞争条件,则只有其中一个最终会设置应用程序变量。

这种方法的好处是它不会在每个请求上不断刷新这些存储的变量,浪费用户的时间和服务器的处理周期。权衡取舍是它有点冗长复杂。

添加Application.cfc大大简化了这一过程。现在,您可以指定在应用程序启动时创建的变量,而不必担心锁定和检查存在以及所有有趣的东西:

<cfcomponent>
    <cfset this.name = "myApplicationName" />

    <cffunction name="onApplicationStart" returnType="boolean" output="false">
        <cfset application.dsn = "MyDSN" />
        <cfset foo = "bar" />
        <cfset x = 5 />
        <cfreturn true />
    </cffunction>
</cfcomponent>

有关Application.cfc的更多信息,包括所有可用的特殊功能以及有关使用它的内容和方法的每一个细节,I recommend this post on Raymond Camden's blog

总而言之,您的代码中的请求范围随处可用,但这并不一定使得在任何地方使用它都“正确”。您的前任可能正在使用它来破坏封装,这可能很难重构。你可能最好离开它,但了解哪个范围是最好的工具,肯定会使你未来的代码更好。

答案 1 :(得分:15)

这是一个非常主观的问题,有些人甚至认为在现代ColdFusion应用程序中使用请求范围永远不合适。

通过该免责声明,让我们定义请求范围是什么以及它在哪里有用。

请求范围是单个ColdFusion页面请求中的绝对全局范围。它不是共享范围,如应用程序,服务器,客户端和会话范围,因此不需要锁定以使其成为线程安全(除非您使用CF8的CFTHREAD标记从单个请求生成工作线程)。作为一个全局范围,它是一种非常方便的方法,可以将变量保存在请求堆栈中的任何级别,而无需将它们从父级传递给调用者。这是通过旧CF应用程序中的嵌套或递归自定义标记来持久保存变量的一种非常常见的方法。

请注意,虽然许多应用程序使用此范围来存储应用程序级变量(例如配置设置),但请求范围与应用程序范围之间的大差异(有时是微妙的)是同一请求的值 - 各个页面请求之间的范围变量可能不同。

我猜你的前任使用这个范围来方便地设置变量,这些变量需要在封装或嵌套代码单元之间的跳转中存活,而不必明确地传递它们。

答案 2 :(得分:0)

好的,我只想对您的代码发表评论。如果我看起来很疯狂,请原谅我。但是你已经在开始时验证了structKeyExists。既然你知道它会是真的,那么再运行一次检查是没有意义的。所以我的版本就是这个...但那就是我。


<cfif not structKeyExists(application, "dsn")>
    <cflock scope="application" type="exclusive" timeout="30">
            <cfset application.dsn = "MyDSN" />
            <cfset foo = "bar" />
            <cfset x = 5 />
    </cflock>
</cfif>

好的。

答案 3 :(得分:0)

我一直在编写我公司的框架,用于为我们的网站提供支持。

我使用请求变量设置可供其他CFC使用的某些数据我必须这样做,这样数据就可以在整个应用程序中使用,而无需不断传递数据。我老实说相信使用请求和应用程序,只要它是一个静态函数组件,那么你应该没有问题。我不确定自己的想法是否错误,但一旦我发布框架,我们就会看到。