【问题标题】:Mapping to a CFC in ColdFusion在 ColdFusion 中映射到 CFC
【发布时间】:2011-12-10 11:47:09
【问题描述】:

在我的应用程序中,我的所有 CFC 都位于 cfc 文件夹中。从站点根目录我可以轻松访问它们,只需在我的<cfinvoke> 标记中将它们称为component=cfc.mycomponent method=mymethod

问题是,当我想从不在根目录中的另一个页面访问 cfc 时,我无法使用 component=../.cfc.mycomponent 与该 cfc 取得联系。

我在这里做错了什么?

【问题讨论】:

  • 上次我检查,不支持那种相对路径。从那个位置,您需要使用根目录的绝对路径,即root.cfc.mycomponent
  • 仅供参考:这是 CF 搜索组件的方式:help.adobe.com/en_US/ColdFusion/9.0/Developing/…
  • 谢谢利。我正在为这个特定站点使用 CF8。我确实注意到说明看起来有些相似。

标签: coldfusion mapping cfc


【解决方案1】:

您不能对组件使用相对路径。

您需要的是 ColdFusion 映射。有两种方法可以做到这一点。

首先是进入您的 ColdFusion 管理员,进入映射部分并添加一个指向您的 cfc 文件夹的 /cfc 映射。

另一种方法是使用特定于应用程序的映射; 在应用程序的 Application.cfc 中,您可以像在 ColdFusion 管理员映射下一样添加应用程序映射。在应用程序 cfc 的顶部添加 this.mappings 的 cfset 作为数组。在此数组中设置与目录路径的映射。

<cfset this.mappings["/cfc"] = GetDirectoryFromPath( GetCurrentTemplatePath() )&"cfc">

通过 /cfc 到您的 cfc 文件夹的映射,任何对 cfc.objectname 的组件调用都会在您的 cfc 文件夹中加载相应的组件。

【讨论】:

  • 一定是&lt;cfset this.mappings["/cfc"] = ... - 你忘记了“s”。
【解决方案2】:

有几个选项可以让它发挥作用。不幸的是,学习它们让我进行了大量的试验和错误。让我分享一下我学到的东西。

首先,您可以使用经典的方法在您的 CF 管理员中创建映射。指定组件的确切路径(例如c:\wwwroot\cfc),以及您想要调用它的映射(伪文件夹)(例如MyCFCs)。现在,您可以在应用程序的任何位置引用创建new MyCFCs.mycomponent()(使用 CF9+ 的 new 关键字,您可以替换 createObject("component","MyCFCs.mycomponent") 以兼容回 CF6)。

使用服务器映射的缺点是您必须在运行应用程序的每台服务器上进行配置。我通常有一个本地开发服务器,它的配置与我的生产服务器完全不同,在生产服务器上进行更改对我来说很痛苦,所以我尽量避免服务器映射。

第二,您可以从 web-root-relative 路径引用您的 CFC,这意味着如果您的应用程序位于服务器的根目录中,并且 /cfc 路径直接在 web 之外root,您始终可以在应用程序的任何位置执行new cfc.mycomponent()。 ColdFusion 6.1 及更高版本将正确映射到您网站的根目录。这就像使用/images/mypicture.jpg 引用图像一样,在您网站的任何位置,/images 将直接进入同一目录。

使用 web-root-relative 路径的缺点是,如果您的应用程序将位于 Web 根目录之外的不同文件夹中,或者将位于子目录中并且有时位于 Web 根目录中,则相对路径来自 web 根目录的内容会发生变化,从而破坏这些链接。

第三,您可以创建特定于应用程序的映射。这是在 CF8 中引入的,需要您有一个 Application.cfc 文件。添加起来很简单。雷蒙德卡姆登有a great reference。语法本质上是这样的。

<cfset this.name = "MyAppName"/>
<cfset this.mappings = structNew() />
<cfset this.mappings["/cfc"] = getDirectoryFromPath(getCurrentTemplatePath()) & "cfc/" />

此方法的唯一缺点是您的 Application.cfc 无法扩展映射文件夹中的 CFC。这是一个晦涩难懂的问题,可能不会影响您。此外,您需要有一个 Application.cfc,这是一个很好的做法,但我不知道您是否正在这样做。

第四,您可以在OnApplicationStart() 方法中将您的CFC 实例化到您的应用程序范围内,可能是在上述Application.cfc 中。这会将任何编译/实例化时间移至应用程序的第一次命中,并将其从后续命中中删除。代码很简单。

<!--- from Application.cfc, inside onApplicationStart() --->
<cfset application.myComponent = new cfc.myComponent() />

<!--- from anywhere else in your application --->
<cfset application.myComponent.callMyMethod() />

这样做的缺点是,一旦您的组件位于应用程序内存中,您在开发应用程序时对其所做的任何更改都不会反映,直到您清除应用程序内存或再次调用 onApplicationStart()。解决起来并不难,但它只是更多的代码,更多的管理。

最后一点,您可能需要考虑从 &lt;cfinvoke&gt; 转移到 createObject("component",...),或者,如果您使用的是 CF9,请考虑 new。 cfinvoke 语法很好,但是每次从路径调用组件时,都会重新实例化它,而且它也不是一种非常面向对象的调用组件的方式。深思熟虑,接受或离开它:)

【讨论】:

  • 难以置信的细节和实用的描述。谢谢。
  • 只是想报告这件事。我已经实现了选项 3,它的效果非常好。再次感谢您。
  • 我可能为时已晚,但是,我可以使用第三个选项来映射其他文件夹,例如我的脚本和图像文件夹吗?
  • 它适用于服务器端资源,但不适用于客户端文件。你可以通过你的网络服务器添加一个虚拟目录,或者通过 CF,你可以构建一个指向你的脚本和图像文件夹的 web-root-relative 链接,并使用它。从您的 Application.cfc 中,类似于:&lt;cfset application.imagePath = replace(expandPath("images/"), expandPath("."), "") /&gt; 然后将其引用为 #application.imagePath#/myPhoto.jpg - 我没有对此进行测试,但您明白了。
【解决方案3】:

确保如果您的组件扩展了其他组件,则使用完整路径。

即产品控制器

<cfcomponent displayname="Products" hint="Handles all product requests" extends="core.controller.controller"  output="false">

【讨论】:

    【解决方案4】:

    您绝对可以使用映射扩展 cfc。我必须自己做。

    我在 ColdFusion 中不得不处理的最令人沮丧的事情之一是尝试创建一个对公众开放的外部应用程序,并且必须使用子文件夹中的应用程序来保护该站点的一部分并扩展来自基础 application.cfc 的逻辑。我将向您介绍开发人员用来解决此问题的当前方法,并向您展示如何在可能存在使用虚拟目录的托管服务提供商时额外使用映射。

    这是一篇比较长的文章,如果你想跳转到精简摘要,请向下滚动到本页底部。

    多年前,我第一次尝试执行此操作时,无论我如何尝试都收到以下消息:“找不到 ColdFusion 组件或接口 xxx'。简而言之, 使用这种方式的问题是根目录和子文件夹都同名,即Application.cfc,ColdFusion无法正确识别扩展什么组件。最后,经过一番认真的调查,有人想出了主意创建一个proxy.cfc,它与根Application.cfc 位于同一根目录中,并且子文件夹中的Application.cfc 扩展了一个空的proxy.cfc,该proxy.cfc 扩展了根cfc,如下所示:

    根目录:Application.cfc
    此根 Application.cfc 不扩展任何内容

    也在根目录:Proxy.cfc
    Proxy.cfc 有以下代码,它基本上是空的Proxy.cfc 所做的唯一 是扩展同一目录中的 Application.cfc:




    子目录,例如名为 admin 的文件夹。
    该子目录还有另一个 Application.cfc。假设该组件负责保护应用程序并具有登录逻辑以及调试设置等功能。 此 Application.cfc 将扩展 Proxy.cfc 以获得根目录中 Application.cfc 的方法和属性,如下所示:




    这种方法是天赐之物,并且在博客中广为流传。 Ben Nadel 发表了许多非常有用的帖子,我将在本文底部分享这些帖子。

    这很有效,除非您在托管域或使用虚拟目录的服务器上。在这种情况下,我们是在我们开始的同一条船上。现在我们又回到了“找不到ColdFusion组件或接口xxx'的地狱!

    虽然这个棘手的问题有一个解决方案,但我们还需要使用映射!

    不能使用映射来扩展组件是一个常见的误称。我不太确定这种误解最初是从哪里来的,但事实证明这是不正确的。在某些情况下,我们必须使用映射来解决一些烦人的问题,比如这里。

    此特定站点由hostek.com 托管。 他们是一家很好的公司,但我的网站所在的服务器由于目录结构而有一些特殊性。在这里,当我使用 Proxy.cfc 方法将逻辑从基本 Application.cfc 扩展到管理文件夹中的 Application.cfc 时,我收到可怕的“找不到...组件”错误。当我第一次看到它时,我很沮丧,不再想这个,所以我转向了 ColdFusion CFC 映射。映射告诉 ColdFusion 在哪里可以找到文件以及文件关系是什么。

    让我们回顾一下刚才讨论的 CFC 结构。例如,想象以下目录结构:

    根目录:即www.gregoryalexander.com/
    子目录:www.gregoryalexander.com/admin/

    如前所述,我们在 根目录 中有一个 Application.cfcProxy.cfc,并且我们有 Application.cfc 在“admin”子目录中。 Proxy.cfc 扩展了 Application.cfc,也在根目录中,而子目录 (admin) 中的 Application.cfc 扩展了根目录中的 Proxy.cfc。

    根目录:包含 Application.cfc 和 Proxy.cfc(扩展了根 Application.cfc)。
    子目录:Application.cfc(扩展 Proxy.cfc)。

    现在我们还需要在根 Application.cfc 中添加以下映射。此映射逻辑应根 Application.cfc 的顶部附近,并且它不应在任何 Application.cfc 事件处理程序(onApplicationStart、onApplicationRequest 等)中.此映射代码不需要位于根 Application.cfc 以外的任何其他位置:




    我使用 rootCfc 来识别根目录中的 Application.cfc,而 adminCfc 适用于 admin 目录中的 Application。这些变量可以任意命名。请注意,adminCfc 映射末尾的“/admin”字符串指向“admin”文件夹,这是一个子目录。

    现在我们在根 Application.cfc 中有映射,我们需要将它们应用到位于子目录的 Application.cfc 中的 extends 语句。在 /admin/Application.cfc 模板中使用:

    /admin/Application.cfc

    当然,rootCfc 告诉子目录中的 Application.cfc 在根目录中查找 Proxy.cfc 模板。与其他“扩展”语句一样,您无需在 Proxy 末尾指定“.cfc”。

    您无需在根 Proxy.cfc 或 Application.cfc 模板中使用此“扩展”映射。他们已经可以找到彼此,因为他们都在同一个根目录中。

    /Proxy.cfc

    概括

    为了绝对清楚起见:
    root Application.cfc
    包含映射逻辑。具有根目录和子目录的映射。
    不使用“扩展”语句



    root Proxy.cfm
    一个简单的 'extends="Administrator" 就可以了。
    没有映射逻辑。

    子目录 Application.cfc
    extends 语句必须是文件夹的映射变量名称 (rootCfc)、一个点 (.),最后是不带 .cfc 前缀的 Proxy.cfc 模板的名称 (Proxy)

    我很抱歉如此冗长。写这篇文章的时候我很恼火——但当我试图解决这个问题时却没有那么恼火!

    保重!

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2010-10-20
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-10-26
      相关资源
      最近更新 更多