【问题标题】:ColdFusion - When to use the "request" scope?ColdFusion - 何时使用“请求”范围?
【发布时间】:2015-11-11 20:19:21
【问题描述】:

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

【问题讨论】:

    标签: coldfusion railo cfml


    【解决方案1】:

    您的代码的任何部分都可以使用多个范围:会话、客户端、Cookie、应用程序和请求。有些不建议以某些方式使用(即在您的自定义标签或 CFC 中使用 Request 或 Application 范围;这是coupling,违反封装原则,被认为是一种不好的做法),有些有特殊用途: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 的更多信息,包括所有各种可用的特殊功能以及关于什么和如何使用它的每一个小细节,I recommend this post on Raymond Camden's blog

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

    【讨论】:

      【解决方案2】:

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

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

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

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

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

      【讨论】:

        【解决方案3】:

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

        好的。

        【讨论】:

        • 最佳实践要求您在 cflock 中再次检查以避免竞争条件
        • 设置应用程序范围变量的“最佳实践”,因为 CFMX6.0 是只使用 CFLOCK,因为有可能出现竞争条件,而这里提供的代码中没有。如果只想将一个简单的值设置为应用程序范围的变量并且整个过程是原子的(即:它是一个语句,并且没有竞争条件的范围,如本例所示),则只需使用 CFPARAM 标记即可很好。
        【解决方案4】:

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

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

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2014-11-11
          • 2012-04-07
          • 1970-01-01
          • 2019-01-30
          • 1970-01-01
          • 2013-01-21
          • 1970-01-01
          相关资源
          最近更新 更多