cfc 教程

tech2024-04-05  66

cfc 教程

So last time we learned the basics of creating a CFC and the overall structure of a very basic CFC. Today we’re going to talk about the different ways in which we can use this CFC in our code.

因此, 上次我们学习了创建CFC的基础知识和非常基本的CFC的整体结构。 今天,我们将讨论在代码中使用此CFC的不同方法。

So how do we access this function in our CFC? Can we just include it into a CFML page using the CFInclude tag or is there more to it? If you guessed there’s more to it then you are spot on! CFCs have a few ways in which they can be used, tag based, script based and yet another tag based implementation.

那么我们如何在CFC中访问此功能? 我们可以使用CFInclude标签将其包含到CFML页面中吗? 如果您猜想还有更多的话,那么您来了! CFC有几种使用方式,基于标签,基于脚本和另一种基于标签的实现。

基于标签的实现#1 (Tag Based Implementation #1)

Now CFCs ,at their most basic level, are a lot like custom tags. In order to use the functions you create in a CFC you have to call them and then output the data they return. So for our greeting CFC we would call it like so:

现在,最基本的CFC就像自定义标签一样。 为了使用在CFC中创建的功能,必须调用它们,然后输出它们返回的数据。 因此,为了问候CFC,我们将其命名为:

<cfinvoke component="greeting" method="getGreeting" returnvariable="myGreeting"> <cfoutput>#myGreeting#</cfoutput>

This will display Welcome guest! Enjoy your visit and please come back soon. wherever we output the variable myGreeting. Here we are using the CFInvoke tag to “invoke” our CFC, which is just a fancy way of saying “to call”, “instantiate” or even “create”. The CFInvoke tag takes a good amount of attributes but we only care about 3 for now. Component is the name of the component we want to use. In the code above the greeting component lives in the same folder as the page which the CFInvoke tag is written. If I had the CFC in another folder I would use do notation to tell ColdFusion where to find my CFC. For example if my page lived in the root folder but my CFCs lived in a folder called components below my root folder I could use this code:

这将显示欢迎客人! 祝您访问愉快,请尽快回来。 无论我们在哪里输出变量myGreeting。 在这里,我们使用CFInvoke标记“调用”我们的CFC,这只是说“打电话”,“实例化”甚至“创建”的一种奇特方式。 CFInvoke标签具有大量的属性,但目前我们只关心3个。 组件是我们要使用的组件的名称。 在上面的代码中,greeting组件与写入CFInvoke标签的页面位于同一文件夹中。 如果我的CFC在另一个文件夹中,我会使用“ Do”表示法告诉ColdFusion在哪里可以找到我的CFC。 例如,如果我的页面位于根文件夹中,而我的CFC则位于根文件夹下的名为components的文件夹中,则可以使用以下代码:

<cfinvoke component="components.greeting" method="getGreeting" returnvariable="myGreeting"> <cfoutput>#myGreeting#</cfoutput>

If my CFCs lived in a mapping called Global outside of my root folder but in a sub folder called CFC I would call it like so:

如果我的CFC位于我的根文件夹之外的一个名为Global的映射中,但是位于一个名为CFC的子文件夹中,则我会这样称呼它:

<cfinvoke component="Global.cfc.greeting" method="getGreeting" returnvariable="myGreeting"> <cfoutput>#myGreeting#</cfoutput>

You can even use variables when telling ColdFusion where to find your CFCs:

在告诉ColdFusion在哪里可以找到CFC时,甚至可以使用变量:

<cfinvoke component="#application.CFCPath#.greeting" method="getGreeting" returnvariable="myGreeting"> <cfoutput>#myGreeting#</cfoutput>

Now what if we wanted to pass in a visitors name how would we do that? Our CFC can take in an argument called “visitor” and to pass a value into this argument you would use the CFInvokeArgument tag like so:

现在,如果我们想传递访客姓名怎么办? 我们的CFC可以接受一个名为“ visitor”的参数,并将值传递给该参数,您可以使用CFInvokeArgument标记,如下所示:

<cfinvoke component="greeting" method="getGreeting" returnvariable="myGreeting">      <cfinvokeargument name="visitor" value="Eric"> </cfinvoke> <cfoutput>#myGreeting#</cfoutput>

You can see in the code above that we’ve added lines 2 and 3. Line 2 is the actual CFInvokeArgument tag and it takes two attributes, name which is the name of the variable in our CFC and value which is the value we want to pass into our CFC. Line 3 is the closing CFInvoke Tag which was absent in our previous examples. For those wondering you can pass in variables in the value attribute, just remember to pound (#) them.

您可以在上面的代码中看到我们添加了第2行和第3行。第2行是实际的CFInvokeArgument标记,它具有两个属性,name是CFC中变量的名称,value是我们想要的值传递到我们的CFC中。 第3行是我们前面的示例中没有的封闭CFInvoke标签。 对于那些想知道您可以在value属性中传递变量的人,只需记住将它们打成#号即可。

基于标签的实施2 (Tag Based Implementation #2)

So why would we need 2 ways to call a CFC with tags? Well implementation #1 is good and effective but the CFC only exists right then and there. When you call a CFC using the code in implementation #1 the CFC gets created by ColdFusion, you could also say instantiated which is the same thing, the function then gets called and that data gets output. THEN ColdFusion destroys the CFC and wipes it from existence in the servers memory, but not the file itself so don’t worry. Now this is fine if you don’t want to use the CFC or any of it’s functions later on but if decide that you do then ColdFusion has to go through this whole creation process all over again. In programming we call this creation / destruction process “expensive” because it uses memory and processor units to accomplish the task each and every time. It would be so much better if we could create the CFC and then store it in an application scope, or session scope and reuse it throughout the site and that is where implementation #2 comes in.

那么,为什么我们需要两种方法来调用带有标签的CFC? 实施#1很好并且有效,但是CFC仅在那时和那里存在。 当您使用实现#1中的代码调用CFC时,CFC是由ColdFusion创建的,您也可以说实例化这是同一件事,然后调用该函数并输出数据。 然后ColdFusion销毁CFC并将其从服务器内存中删除,但不会删除文件本身,因此不必担心。 现在,如果您以后不想使用CFC或它的任何功能,那很好,但是如果决定这样做,则ColdFusion必须重新经历整个创建过程。 在编程中,我们将此创建/销毁过程称为“昂贵”的过程,因为它每次都使用内存和处理器单元来完成任务。 如果我们可以创建CFC,然后将其存储在应用程序范围或会话范围中,并在整个站点中重复使用它,那就更好了,那就是实现2的地方。

First we have to create the CFC and since we want the CFC to stick around this time we’re going to create it in our Application scope. For those unaware the Application scope is a persistent scope, meaning that any variables created in this scope will persist until they are over written, deleted or the server is restarted. It’s a great place to store things which you need throughout your entire application. Here’s the code to accomplish this little task:

首先,我们必须创建CFC,并且由于我们希望CFC保持这种状态,因此我们将在Application范围内创建它。 对于那些不知道的应用程序作用域是一个持久作用域,这意味着在该作用域中创建的任何变量将一直存在,直到被覆盖,删除或重新启动服务器为止。 这是在整个应用程序中存储所需内容的好地方。 这是完成此小任务的代码:

<cfobject type="component" name="Application.siteGreeting" component="greeting"> <cfinvoke component="#application.sitegreeting#" method="getGreeting" returnvariable="myGreeting">      <cfinvokeargument name="visitor" value="Eric"> </cfinvoke>

For the most part this code look pretty similar to what we did in implementation #1 but with a twist. First off look at line 1 and you’ll see we’ve added a new tag called CFObject and it takes 3 attributes. The type attribute tells ColdFusion what we want to create and in this case it’s a component. Next up is name, this is the variable which will be created from this tag, which will be my CFC. Last is the component attribute and it works just like the component attribute does in our CFInvoke tag, meaning it tells ColdFusion where to find the component we want to create. Now once this tag runs we’ll have a persistent instance, or copy, of our CFC and we can reference it as Application.siteGreeting.

在大多数情况下,此代码看起来与我们在实现#1中所做的非常相似,但有所不同。 首先看第1行,您会看到我们添加了一个名为CFObject的新标签,它具有3个属性。 type属性告诉ColdFusion我们要创建什么,在这种情况下,它是一个组件。 接下来是名称,这是将从该标记创建的变量,即我的CFC。 最后是component属性,它的工作方式与CFInvoke标记中的component属性一样,这意味着它告诉ColdFusion在哪里可以找到要创建的组件。 现在,一旦此标签运行,我们将拥有CFC的持久实例或副本,我们可以将其引用为Application.siteGreeting。

Next up we use our CFInvoke tag to actually use the CFC and call our getGreeting function. You’ll notice here that it’s exactly like implementation #1 with the exception of the component attribute. Here we are actually passing in the variable we created with our CFObject tag and pounding it out INSTEAD of passing it the path to our CFC. Now in this example I have the CFObject tag right before the CFInvoke tag but in reality the two tags could be multiple lines apart, or even in different files. As long as my application.siteGreeting gets created then my CFInvoke tag will run without any problems.

接下来,我们使用CFInvoke标记实际使用CFC并调用getGreeting函数。 您会在这里注意到,它与实现#1完全相同,但component属性除外。 在这里,我们实际上传入的是使用CFObject标记创建的变量,并将其传递给INSTEAD,然后将其传递给CFC的路径。 现在,在此示例中,我在CFInvoke标记之前有CFObject标记,但实际上,两个标记可能相隔多行,甚至位于不同的文件中。 只要创建了application.siteGreeting,我的CFInvoke标记就可以正常运行。

So why would we want to this? After all it is an extra line of code and is it really saving us that much? For this example no, probably not, but over time it could be very costly to keep creating and destroying our CFC using just the CFInvoke tag.Think if thousands of people hit this page at the same time. ColdFusion would be creating and destroying the same CFC each and every time the page was run. By creating it into a scoped variable it’s more persistent and it isn’t as expensive to use since it already exists. Think of it like buying a soda at a corner store. Each time you want to get a drink you have to go to the store, pick out your soda, pay for it at the register and then you get to drink it. This is how implementation #1 works but if you already had the soda, or even a case of soda,  bought and they were sitting in your fridge you could cut out the “going to the store”, “picking it out”, and “paying for it at the register” steps because you already have it and can enjoy the soda whenever you want to.

那我们为什么要这么做呢? 毕竟,这是额外的一行代码,它真的为我们节省了很多吗? 对于此示例,可能不是,但是随着时间的推移,仅使用CFInvoke标签继续创建和销毁CFC可能会非常昂贵。请考虑一下是否有成千上万的人同时访问此页面。 每当页面运行时,ColdFusion都会创建和销毁相同的CFC。 通过将其创建到作用域变量中,它可以更持久,并且使用起来并不昂贵,因为它已经存在。 可以将其视为在一家角落商店购买苏打水。 每次想要喝一杯饮料时,都必须去商店,挑选苏打水,在收银机上付款,然后再喝一杯。 这是实施方案1的工作方式,但是如果您已经购买了苏打水,甚至一箱苏打水,而且它们正坐在您的冰箱中,则可以省去“去商店”,“挑选”和“只需在收银机上付款”即可,因为您已经拥有了它,可以随时随地享用苏打水。

基于CFScript的实现 (CFScript based implementation)

If you’re a script person, and I am sometimes for sure, you might like this version:

如果您是脚本编写者,并且有时可以肯定,那么您可能会喜欢以下版本:

Version #1

版本1

<cfscript>      siteGreeting = CreateObject('component','greeting');      myGreeting = siteGreeting.getGreeting(visitor='Eric'); </cfscript>

Version #2

版本#2

<cfscript>      application.siteGreeting = CreateObject('component','greeting');      myGreeting = application.siteGreeting.getGreeting(visitor='Eric'); </cfscript>

Version #1 and Version #2 are 99% identical with the exception that in version #2 we are creating the CFC in the application scope just like the tag based implementation #2. Here you see we’ve used the CFScript tag to setup the ColdFusion scripting environment. ColdFusion is primarily a tag based language and that’s what it’s know for but it also has a script side to it which allows you to do a lot, but not everything you can do in the tag side. Everything between the CFScript tags is ColdFusion script and it probably looks a lot like other scripting languages you’ve seen. In line 2 of the above examples we use the CreateObject function to create our CFC much in the same way we use the CFObject tag in implementation #2. When you create CFC’s via CFScript you have to always use the CreateObject function as there isn’t an all in one solution like the tag based CFInvoke. So version one we create the CFC and assign it to the variable siteGreeting and in version two it’s assigned to the variable application.siteGreeting. On line 3 we actually call our function using dot notation, remember dot notation from tag based implementation #1, using the format CFCNAME.functionName. Now since version two has the CFC in the application scope you get an extra dot in there, it’s more like scope.CFCNAME.functionName but it’s basically the same thing. You’ll notice that when I pass in our argument visitor I do it within the parenthesis as visitor=’Eric’. When doing CFC’s the CFScript way you can either pass your variables in this name=value pair or you can just pass in the values as a comma delimitated list, being sure to quote string values. BUT when you pass them in as a list you must pass the values in the exact order that your CFC has the cfargument tags setup. For example if my CFC looked like so:

版本#1和版本#2具有99%的相同性,只是在版本#2中,我们像在基于标记的实现#2中一样,在应用程序范围内创建了CFC。 在这里,您会看到我们已经使用CFScript标记来设置ColdFusion脚本环境。 ColdFusion主要是基于标签的语言,这就是它的作用,但是它还有脚本方面的功能,使您可以做很多事情,但不能在标签方面做任何事情。 CFScript标签之间的所有内容都是ColdFusion脚本,它看起来很像您所看到的其他脚本语言。 在上述示例的第2行中,我们使用CreateObject函数创建CFC的方式与在实现#2中使用CFObject标记的方式相同。 通过CFScript创建CFC时,必须始终使用CreateObject函数,因为没有像基于标签的CFInvoke这样的解决方案。 因此,在第一个版本中,我们创建了CFC,并将其分配给变量siteGreeting,在第二个版本中,将其分配给了变量application.siteGreeting。 在第3行中,我们实际上使用点符号来调用函数,请记住基于标记的实现#1中的点符号,格式为CFCNAME.functionName。 现在,由于第二版在应用程序范围内具有CFC,因此您在其中有了一个额外的点,它更像scope.CFCNAME.functionName,但基本上是同一回事。 您会注意到,当我传入参数visitor时,我会在圆括号内将其作为visitor ='Eric'。 在使用CFC的CFScript方法时,您可以在此name = value对中传递变量,也可以仅以逗号分隔列表的形式传递值,并确保引用字符串值。 但是,当您将它们作为列表传递时,必须按照CFC具有cfargument标签设置的确切顺序传递值。 例如,如果我的CFC看起来像这样:

<cfcomponent displayname="MyFirstCFC" hint="It's just a CFC folks, don't freak out">      <cffunction name="getGreeting" output="false" returntype="string" description="Returns a greeting string">           <cfargument name="visitorFirstName" required="no" type="string" displayname="Visitor First Name String" hint="The Visitors name">           <cfargument name="visitorLastName" required="no" type="string" displayname="Visitor Last Name String" hint="The Visitors name">           <cfif IsDefined('arguments.visitor') AND Len(Trim(arguments.visitor))>                <cfreturn 'Welcome ' & arguments.visitorFirstName & ' ' & arguments.visitorLastName & '! I hope you enjoy your stay.'>           <cfelse>                <cfreturn 'Welcome guest! Enjoy your visit and please come back soon.'>           </cfif>      </cffunction> </cfcomponent>

Then I’d have to either pass in my variables like so:

然后我必须像这样传递我的变量:

myGreeting = application.siteGreeting.getGreeting(visitorFirstName=’Eric’,visitorLastName=’Jones’);

myGreeting = application.siteGreeting.getGreeting(visitorFirstName ='Eric',visitorLastName ='Jones');

OR

要么

myGreeting = application.siteGreeting.getGreeting(‘Eric’,’Jones’);

myGreeting = application.siteGreeting.getGreeting('Eric','Jones');

Only in the first example where I do the name = value pair could I mix them up and put the “last name” first and the “first name” last without any issues. If I mixed them up in the second example then my name would get returned as “Jones Eric” instead of “Eric Jones”. Therefore it’s always a good idea to pass your arguments in the name=value pair unless you only have one argument to pass in.

只有在第一个示例中使用“名称=值”对时,我才可以将它们混合在一起,然后将“姓氏”放在首位,将“名字”放在最后而没有任何问题。 如果我在第二个示例中将它们混合在一起,那么我的名字将被返回为“ Jones Eric”而不是“ Eric Jones”。 因此,除非您只传递一个参数,否则最好在name = value对中传递参数。

Ok that concludes this post and I think I’m done with CFCs for the common developer for a short while but please feel free to post your questions here or on the forums. Who knows maybe you’ll inspire my next post!

好的,这篇文章结束了,我想我已经为普通开发人员准备了不久的CFC,但是请随时在这里或论坛上发表您的问题。 谁知道也许您会激发我的下一篇文章!

翻译自: https://www.sitepoint.com/cfcs-for-the-common-developer-part-2/

cfc 教程

最新回复(0)