如何在不覆盖父函数的情况下扩展application.cfc?

时间:2016-08-10 15:12:56

标签: coldfusion application.cfc

我已经在线搜索了一下,看看是否可以做到这一点,并且没有找到任何可以说明的事情。我在根目录下有一个application.cfc,并且有一些子文件夹,我希望它的功能是相同的,只有很小的差异。例如,根目录下的cfc在onRequestStart()中有一个函数,它包含一个函数来确定被调用模板的相对根路径(即,它应该是“../”还是“../../”等,见http://www.bennadel.com/blog/1655-ask-ben-dynamic-web-root-and-site-url-calculations-in-application-cfc.htm)。

我想让它在所有子文件夹中的所有页面上运行,但在一个子文件夹中,我还想在每个请求上运行安全方案,检查用户是否具有查看该子文件夹中页面的有效权限。如果我在该子文件夹中创建了一个application.cfc,它在根目录下扩展了cfc,那么我放在那里的任何onRequestStart()函数都会覆盖父代的onRequestStart()。

现在,我正在想办法让孩子的onRequestStart()“与父母一样,只需要一点额外”的唯一方法是将父cfc的onRequestStart()复制到孩子身上,并添加我额外的安全性里面的代码。但是,这样做会搞砸查找页面相对webroot路径的函数。对于该子文件夹中的页面,“../../”将相对于子文件夹中的application.cfc,而不是相对于根目录中的父项,这是所需的。

我解决这个问题的方法是将代码放在父cfc的onRequestStart()中:

3  2
1  1
2 -2

基本上对于任何其他子文件夹或子文件夹也是如此,我希望为该子文件夹及其任何后代文件夹运行其他代码。在这个特定网站上哪个没关系,因为它不是那么大,但我看到这对于一个更大的网站来说会变得非常混乱。有更好的方法吗?

2 个答案:

答案 0 :(得分:3)

你的Google-foo一定是你失败了;)Ben Nadel举了一个例子,说明你要做什么。基本上,您不需要从继承的Application.cfc复制该函数,您只需要使用SUPER范围调用它(调用它)。

这是Ben的文章的链接 - Ask Ben: Extending Application.cfc And OnRequestStart() With SUPER。从那篇文章:

  

我有一句话给你:超级。当一个ColdFusion组件扩展另一个组件时,将创建SUPER范围。它可用于扩展组件,并提供从扩展组件到扩展组件的访问,有时称为扩展组件"基本组件"或"超级组件。" SUPER范围不仅允许我们访问超级组件中的值(这不是必需的,因为这些值在扩展组件中也是可用的),但更重要的是,它允许我们在超级组件中执行函数即使这些函数被扩展的ColdFusion组件覆盖(因为它们将在我们的演示中)。

     

要利用此功能并提取您的根Application.cfc ColdFusion组件中的配置数据,我们将使用SUPER范围从子应用程序调用根Application.cfc的OnRequestStart()事件方法.cfc。但首先,让我们快速浏览一下根Application.cfc,以确保我们都在同一页面上:

我不想在这里复制整篇文章,但他继续展示示例,说明正在发生的事情。我绝对建议阅读他的整篇文章。

以下是使用SUPER范围的示例Application.cfc:

<cfcomponent
    output="false"
    extends="personal.ben......app_extend2.Application"
    hint="Secondary application event handler.">

    <cffunction
    name="OnRequestStart"
    access="public"
    returntype="boolean"
    output="false"
    hint="Hanldes pre-page processing for each request.">

    <!--- Define arguments. --->
    <cfargument
        name="Page"
        type="string"
        required="true"
        hint="The template requested by the user."
        />

    <!---
        Since this application is extending the root
        Application.cfc, let's leverage the pre-processing
        power of the root OnRequestStart(). Check to see
        what value (true/false) that the root application
        would have returned for this request.
        By calling SUPER.OnRequestStart( Page ), we are
        giving the root application a chance to run logic
        on the page request. **Remember that the
        OnRequestStart() method can return false to kill the
        current page request. Therefore, we have to check to
        see what value would be returned and honor that.
    --->
    <cfif SUPER.OnRequestStart( ARGUMENTS.Page )>

        <!--- Store the sub root directory folder. --->
        <cfset REQUEST.SubDirectory = GetDirectoryFromPath(
        GetCurrentTemplatePath()
        ) />

        <!--- Return out. --->
        <cfreturn true />

    <cfelse>

        <!---
        The root application returned false for this
        page request. Therefore, we want to return
        false to honor that logic.
        --->
        <cfreturn false />

    </cfif>
    </cffunction>

</cfcomponent>

答案 1 :(得分:0)

是的,我搜索了“application.cfc”,“child”,“extends”和“subfolder”的变体,Ben的一些博客帖子在结果的顶部,但不是那个。< / p>

应该为寻找相同答案的其他人添加一件事 - Ben在其他地方解释说,当为你的孩子cfc的cfcomponent标签添加“extends”属性时,CF不会让你简单地使用“extends = 'Application'“,因为它首先在子文件夹中查找名为”application.cfc“的文件,找到它,并抛出一条错误,指出cfc无法自行扩展。

解决这个问题非常简单 - Ben接着解释说,你只需要在根目录下创建一个cfc,其名称不是“application.cfc”,它在根目录下扩展了application.cfc。它本质上是空的,没有自己的函数或变量。因此,您在根目录下创建一个名为“applicationProxy.cfc”(或任何您喜欢的)的cfc,然后将以下代码放入其中:

<cfcomponent displayName="applicationProxy" extends="Application"></cfcomponent>

然后在你的孩子application.cfc中,你只需使用:

<cfcomponent extends='applicationProxy'...