14

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

4

4 回答 4

21

您的代码的任何部分都可以使用多个范围:会话、客户端、Cookie、应用程序和请求。有些不建议以某些方式使用(即在您的自定义标签或 CFC 中使用 Request 或 Application 范围;这是耦合,违反封装原则,被认为是一种不好的做法),有些有特殊用途:Cookie 持久保存在客户端机器作为物理 cookie,会话范围的变量是用户特定的,并随着用户在网站上的会话过期。

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

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

<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 的更多信息,包括所有可用的特殊功能以及关于什么和如何使用它的每一个小细节,我推荐 Raymond Camden 博客上的这篇文章

总而言之,请求范围在您的代码中随处可用,但这并不一定意味着在任何地方使用它都是“正确的”。很有可能您的前任正在使用它来破坏封装,并且重构起来可能很麻烦。你可能最好保持原样,但了解哪个范围是完成这项工作的最佳工具肯定会让你未来的代码变得更好。

于 2008-08-25T19:54:19.210 回答
16

这是一个非常主观的问题,有些人甚至会争辩说,在现代 ColdFusion 应用程序中使用请求范围从来都不是“合适的”。

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

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

请注意,虽然许多应用程序使用此范围来存储应用程序级别的变量(例如配置设置),但请求范围和应用程序范围之间的巨大(有时是细微的)区别在于,相同的请求范围变量的值可以各个页面请求之间的差异。

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

于 2008-08-26T07:04:13.203 回答
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>

好的。

于 2010-08-11T22:16:18.230 回答
0

我一直在编写我公司的框架,该框架将用于为我们的网站提供动力。

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

于 2011-09-26T22:33:08.110 回答