2009-02-19 58 views
13

我正在創建一個API,並在每個方法中調用記錄方法進行審計和故障排除。類似於:ColdFusion cfc方法可以確定自己的名字嗎?

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

我想避免手動重複方法名稱。有沒有一種方法來編程確定它?我已經看過GetMetaData(),但它只返回關於組件(包括所有方法)的信息,但沒有關於當前調用哪個方法的信息。

回答

1

那麼你可以試試這個:

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

我已經嘗試過各種東西,這是不準確的功能似乎被添加到功能字母順序排列。這似乎是限制性的(而不是解決問題)。我會想象一些本地java代碼可以被調用,但我需要考慮這一點。

ThisThis看起來像有趣的閱讀有關內部功能。

回覆:關於coldspring的其他答案。我用coldspring在函數元數據上找到了this in depth article

相關問題:How to get the name of the component that’s extending mine in ColdFusion?

11

所以,現在3種方式。

如果您使用ColdFusion 9.0或更高版本,現在有一個名爲GetFunctionCalledName()的函數。它會返回你正在尋找的東西。 http://help.adobe.com/en_US/ColdFusion/9.0/CFMLRef/WS7cc222be8a31a47d-6e8b7083122cebfc8f2-8000.html

OR

使用ColdSpring和麪向方面編程(http://www.coldspringframework.org/coldspring/examples/quickstart/index.cfm?page=aop)來處理這個要求。

OR

使用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,因爲這將可能給你買一些其他的東西。

+0

對coldspring的良好呼籲,但你會認爲它不會這麼複雜。 – ethyreal 2009-02-20 01:51:33

4

我同意w/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解析方法可能會慢一點。另一方面,如果你有一個大的堆棧跟蹤(就像你使用任何流行的框架一樣),那麼文件解析可能會更快。

- =萬歲的ColdFusion = -

1

我想到了另外一個辦法可以工作。

設置的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> 

然後將其命名每一個前綴(在這個例子中「隱藏」)的常規方法,並將其標記爲私有。所以,我最初的例子將成爲:

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

現在所有的通話將被onMissingMethod,將方法名稱添加到獲得通過,以實際方法的參數被截獲。

我看到的缺點是內省不再正常工作,並且您必須使用命名參數來調用所有函數。如果您不使用命名參數,args將隨機更改missingMethodNameArguments結構中的順序。

+0

多數民衆贊成在創意!我從來沒有想過一個函數包裝器。 – ethyreal 2009-02-23 22:37:43