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

有帮助吗?

解决方案

有几个范围可用于代码的任何部分:会话、客户端、Cookie、应用程序和请求。有些不建议以某些方式使用(即在自定义标签或 CFC 中使用请求或应用程序范围;这是 耦合, ,违反了封装原则,被认为是不好的做法),有些有特殊用途: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 的博客上推荐这篇文章.

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

其他提示

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

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

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

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

我猜想您的前任使用此作用域作为一种方便设置变量的方法,这些变量需要在封装或嵌套代码单元之间的跳转中生存,而无需显式传递它们。

好吧,我只是想对你的代码发表评论。如果我看起来很疯狂,请原谅我。但您已经在一开始就验证了 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>

好吧。

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

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

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top