ColdFusion cfc 方法可以确定自己的名称吗?

发布于 2024-07-14 09:58:46 字数 331 浏览 8 评论 0原文

我正在创建一个 API,并在每个方法中调用日志记录方法以进行审核和故障排除。 例如:

<cffunction name="isUsernameAvailable">
    <cfset logAccess(request.userid,"isUsernameAvailable")>
    ......
</cffunction>

我想避免手动重复方法名称。 有没有办法以编程方式确定它?

我查看了 GetMetaData(),但它只返回有关组件的信息(包括所有方法),但没有返回有关当前正在调用哪个方法的信息。

I am creating an API, and within each method I make a call to a logging method for auditing and troubleshooting. Something like:

<cffunction name="isUsernameAvailable">
    <cfset logAccess(request.userid,"isUsernameAvailable")>
    ......
</cffunction>

I'd like to avoid manually repeating the method name. Is there a way to programatically determine it?

I've looked at GetMetaData() but it only returns info about the component (including all the methods) but nothing about which method is currently being called.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

ペ泪落弦音 2024-07-21 09:58:47

我同意 tpryan。 ColdSpring 让这一切变得非常简单。 然而,这里还有另一种选择。 您可以解析 CFC 文件本身,而不是解析堆栈跟踪。

<cffunction name="foo" displayname="foo" hint="this is just a test function" access="public" returntype="string">
    <cfset var test = getFunctionName(getMetaData().path, getPageContext().getCurrentLineNo()) />
    <cfreturn test />
</cffunction>

<cffunction name="getFunctionName" hint="returns the function name based on the line number" access="public" returntype="string">
    <cfargument name="filepath" type="string" required="true" />
    <cfargument name="linenum" type="any" required="true" />
    <cfset var line = "" />
    <cfset var functionName = "" />
    <cfset var i = 1 />
    <!---- loop over CFC by line ---->
    <cfloop file="#ARGUMENTS.filepath#" index="line">
        <cfif findNoCase('cffunction', line, 1)>
            <cfset functionName = line />
        </cfif>
        <cfif i EQ ARGUMENTS.linenum><cfbreak /></cfif>
        <cfset i++ />
    </cfloop>
    <!---- parse function name ---->
    <cfset functionName = REMatchNoCase("(\bname=[""|'])+[a-z]*[""|']", functionName) />
    <cfset functionName = REMatchNoCase("[""']+[a-z]*[""']", functionName[1]) />
    <cfset functionName = ReReplaceNoCase(functionName[1], "[""']", "", "all") />
    <!---- return success ---->
    <cfreturn functionName />
</cffunction>

上面是为 ColdFusion 8 编写的。CFLOOP 添加了对逐行循环文件的支持(并且不会将整个文件读入内存)。 我做了一些测试来比较堆栈跟踪方法与文件解析。 两者在直接从单个 CFM 模板调用的小型 CFC 上表现同样出色。 显然,如果您有非常大的 CFC,则解析方法可能会慢一些。 另一方面,如果您有较大的堆栈跟踪(例如您正在使用任何流行的框架),那么文件解析可能会更快。

-= Viva ColdFusion =-

I agree w/ tpryan. ColdSpring makes this very easy. However, here is another alternative. Instead of parsing the stack trace, you can parse the CFC file itself.

<cffunction name="foo" displayname="foo" hint="this is just a test function" access="public" returntype="string">
    <cfset var test = getFunctionName(getMetaData().path, getPageContext().getCurrentLineNo()) />
    <cfreturn test />
</cffunction>

<cffunction name="getFunctionName" hint="returns the function name based on the line number" access="public" returntype="string">
    <cfargument name="filepath" type="string" required="true" />
    <cfargument name="linenum" type="any" required="true" />
    <cfset var line = "" />
    <cfset var functionName = "" />
    <cfset var i = 1 />
    <!---- loop over CFC by line ---->
    <cfloop file="#ARGUMENTS.filepath#" index="line">
        <cfif findNoCase('cffunction', line, 1)>
            <cfset functionName = line />
        </cfif>
        <cfif i EQ ARGUMENTS.linenum><cfbreak /></cfif>
        <cfset i++ />
    </cfloop>
    <!---- parse function name ---->
    <cfset functionName = REMatchNoCase("(\bname=[""|'])+[a-z]*[""|']", functionName) />
    <cfset functionName = REMatchNoCase("[""']+[a-z]*[""']", functionName[1]) />
    <cfset functionName = ReReplaceNoCase(functionName[1], "[""']", "", "all") />
    <!---- return success ---->
    <cfreturn functionName />
</cffunction>

The above is written for ColdFusion 8. CFLOOP added support for looping over files line by line (and doesn't read the entire file into memory). I did a few tests comparing the stack trace method vs. file parsing. Both performed equally well on a small CFC being called directly from a single CFM template. Obviously if you have very large CFCs the parsing method might be a bit slower. On the other hand, if you have a large stack trace (like if you are using any of the popular frameworks) then file parsing may be faster.

-= Viva ColdFusion =-

夜深人未静 2024-07-21 09:58:47

好吧,你可以尝试这个:

 <cffunction name="getFunctionName" returntype="any">
        <cfset meta =getMetaData(this)> 
        <cfreturn meta.functions[numberOfFunction].name>
    </cffunction>

我尝试了各种方法,但这并不准确,因为函数似乎是按相反的字母顺序添加到函数数组中的。 这似乎是有限制的(并且不能解决问题)。 我想可以调用一些本机java代码,但我需要对此进行研究。

这个看起来像是有关相关内部函数的有趣阅读。

回复:关于冷泉的另一个答案。 我发现这篇关于函数的深入文章元数据与 Coldspring。

相关问题:如何获取在 ColdFusion 中扩展我的组件的名称?

Well you might try this:

 <cffunction name="getFunctionName" returntype="any">
        <cfset meta =getMetaData(this)> 
        <cfreturn meta.functions[numberOfFunction].name>
    </cffunction>

I've tried various things, and this is not accurate as the functions seem to be added to the array of functions in reverse alphabetical order. This seems limiting (and not solving the problem). I would imagine some native java code could be invoked, but i'm going to need to look into that.

This and This look like interesting reading on related internal functions.

Re: The other answer on coldspring. I found this in depth article on function metadata with coldspring.

Related question : How to get the name of the component that’s extending mine in ColdFusion?

倾城°AllureLove 2024-07-21 09:58:47

我想到了另一种可行的方法。

设置一个像这样的 OnMissingMethod :

<cffunction name="onMissingMethod">
    <cfargument name="missingMethodName" type="string"> 
    <cfargument name="missingMethodNameArguments" type="struct">

    <cfset var tmpReturn = "">
    <cfset var functionToCallName = "Hidden" & Arguments.missingMethodName>
    <cfset arguments.missingMethodArguments.calledMethodName = Arguments.missingMethodName>
    <cfinvoke method="#functionToCallName#" argumentcollection="#Arguments.missingMethodArguments#" returnvariable="tmpReturn" />
    <cfreturn tmpReturn>
</cffunction>

然后用前缀命名每个常规方法(在本例中为“Hidden”),并将它们标记为私有。 因此,我最初的示例将变为:

<cffunction name="HiddenisUsernameAvailable" access="private">
    <cfset logAccess(request.userid,Arguments.calledMethodName)>
    ......
</cffunction>

现在所有调用都将被 onMissingMethod 拦截,这会将方法名称添加到传递给实际方法的参数中。

我认为这样做的缺点是内省不再正常工作,并且您必须使用命名参数来调用所有函数。 如果您不使用命名参数,则args将随机更改missingMethodNameArguments结构中的顺序。

I thought of another way that could work.

Setup an OnMissingMethod something like this:

<cffunction name="onMissingMethod">
    <cfargument name="missingMethodName" type="string"> 
    <cfargument name="missingMethodNameArguments" type="struct">

    <cfset var tmpReturn = "">
    <cfset var functionToCallName = "Hidden" & Arguments.missingMethodName>
    <cfset arguments.missingMethodArguments.calledMethodName = Arguments.missingMethodName>
    <cfinvoke method="#functionToCallName#" argumentcollection="#Arguments.missingMethodArguments#" returnvariable="tmpReturn" />
    <cfreturn tmpReturn>
</cffunction>

Then name each of the regular methods with a prefix ("Hidden" in this example), and mark them as private. So my initial example would become:

<cffunction name="HiddenisUsernameAvailable" access="private">
    <cfset logAccess(request.userid,Arguments.calledMethodName)>
    ......
</cffunction>

Now all the calls will be intercepted by onMissingMethod, which will add the method name to the arguments that get passed to the real method.

The downsides I see to this are that introspection no longer works properly, and you must be using named arguments to call all your functions. If you are not using named arguments, the args will randomly change order in the missingMethodNameArguments structure.

情愿 2024-07-21 09:58:47

getFunctionCalledName() 为您提供活动方法的名称。

getFunctionCalledName() gives you the name of the active method.

故事未完 2024-07-21 09:58:46

所以现在有3种方法。

如果您使用的是 ColdFusion 9.0 或更高版本,现在有一个名为 GetFunctionCalledName() 的函数。 它会返回您正在寻找的内容。
http://help.adobe.com/en_US/ ColdFusion/9.0/CFMLRef/WS7cc222be8a31a47d-6e8b7083122cebfc8f2-8000.html

使用 ColdSpring 和面向方面的编程(http://www.coldspringframework.org/coldspring/examples/quickstart/index.cfm?page=aop) 来为您处理这个问题。

或者

使用 cfthrow 生成包含您的信息的堆栈跟踪:

<cffunction name="determineFunction" output="FALSE" access="public"  returntype="string" hint="" >
<cfset var functionName ="" />
<cfset var i = 0 />
<cfset var stackTraceArray = "" />
<cftry>
<cfthrow />
<cfcatch type="any">
    <cfset stacktraceArray = ListToArray(Replace(cfcatch.stacktrace, "at ", " | ", "All"), "|") />

    <!---Rip the right rows out of the stacktrace --->
    <cfloop index ="i" to="1" from="#ArrayLen(stackTraceArray)#" step="-1">
        <cfif not findNoCase("runFunction", stackTraceArray[i]) or FindNoCase("determineFunction", stackTraceArray[i])>
            <cfset arrayDeleteAt(stackTraceArray, i) />
        </cfif>
    </cfloop>

    <!---Whittle down the string to the func name --->
    <cfset functionName =GetToken(stacktraceArray[1], 1, ".") />
    <cfset functionName =GetToken(functionName, 2, "$")/>
    <cfset functionName =ReplaceNoCase(functionName, "func", "", "once")/>

    <cfreturn functionName />
</cfcatch>
</cftry></cffunction>

我的建议是使用 getFunctionCalledName,或者如果不在 CF 9 ColdSpring 上,因为它可能会为您购买一些其他东西。

So now 3 ways.

If you are using ColdFusion 9.0 or higher there is now a function named GetFunctionCalledName(). It will return what you are looking for.
http://help.adobe.com/en_US/ColdFusion/9.0/CFMLRef/WS7cc222be8a31a47d-6e8b7083122cebfc8f2-8000.html

OR

Use ColdSpring and Aspect Oriented Programming (http://www.coldspringframework.org/coldspring/examples/quickstart/index.cfm?page=aop) to handle this for you.

OR

Use a cfthrow to generate a stack trace that has the information for you:

<cffunction name="determineFunction" output="FALSE" access="public"  returntype="string" hint="" >
<cfset var functionName ="" />
<cfset var i = 0 />
<cfset var stackTraceArray = "" />
<cftry>
<cfthrow />
<cfcatch type="any">
    <cfset stacktraceArray = ListToArray(Replace(cfcatch.stacktrace, "at ", " | ", "All"), "|") />

    <!---Rip the right rows out of the stacktrace --->
    <cfloop index ="i" to="1" from="#ArrayLen(stackTraceArray)#" step="-1">
        <cfif not findNoCase("runFunction", stackTraceArray[i]) or FindNoCase("determineFunction", stackTraceArray[i])>
            <cfset arrayDeleteAt(stackTraceArray, i) />
        </cfif>
    </cfloop>

    <!---Whittle down the string to the func name --->
    <cfset functionName =GetToken(stacktraceArray[1], 1, ".") />
    <cfset functionName =GetToken(functionName, 2, "$")/>
    <cfset functionName =ReplaceNoCase(functionName, "func", "", "once")/>

    <cfreturn functionName />
</cfcatch>
</cftry></cffunction>

My recommendation would be use getFunctionCalledName, or if not on CF 9 ColdSpring, as it will probably buy you some other things.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文