13

API を作成しており、各メソッド内で、監査とトラブルシューティングのためにロギング メソッドを呼び出しています。何かのようなもの:

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

メソッド名を手動で繰り返すことは避けたいと思います。プログラムでそれを決定する方法はありますか?

GetMetaData() を見てきましたが、コンポーネント(すべてのメソッドを含む)に関する情報のみが返され、現在呼び出されているメソッドについては何も返されません。

4

4 に答える 4

12

だから今3つの方法。

ColdFusion 9.0 以降を使用している場合は、GetFunctionCalledName() という名前の関数が追加されました。それはあなたが探しているものを返します。 http://help.adobe.com/en_US/ColdFusion/9.0/CFMLRef/WS7cc222be8a31a47d-6e8b7083122cebfc8f2-8000.html

また

これを処理するには、ColdSpring と Aspect Oriented Programming ( 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 を使用していない場合は、他のものを購入できる可能性があります。

于 2009-02-20T01:37:55.827 に答える
4

私は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>

上記はColdFusion8用に作成されています。CFLOOPでは、ファイルを1行ずつループするサポートが追加されています(ファイル全体がメモリに読み込まれることはありません)。スタックトレース方式とファイル解析を比較するいくつかのテストを行いました。どちらも、単一のCFMテンプレートから直接呼び出される小さなCFCで同等に機能しました。明らかに、CFCが非常に大きい場合、解析方法は少し遅くなる可能性があります。一方、スタックトレースが大きい場合(一般的なフレームワークのいずれかを使用している場合など)、ファイルの解析が高速になる可能性があります。

-= VivaColdFusion =-

于 2009-02-20T03:42:57.850 に答える
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>

次に、通常の各メソッドにプレフィックス (この例では「Hidden」) を付けて名前を付け、それらをプライベートとしてマークします。したがって、私の最初の例は次のようになります。

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

これで、すべての呼び出しが onMissingMethod によってインターセプトされ、実際のメソッドに渡される引数にメソッド名が追加されます。

これの欠点は、イントロスペクションが適切に機能しなくなり、すべての関数を呼び出すために名前付き引数を使用する必要があることです。名前付き引数を使用していない場合、引数は missingMethodNameArguments 構造体でランダムに順序を変更します。

于 2009-02-22T19:28:16.627 に答える
1

あなたはこれを試すかもしれません:

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

私はさまざまなことを試しましたが、関数が逆アルファベット順で関数の配列に追加されているように見えるため、これは正確ではありません。これは制限のようです (そして問題を解決していません)。ネイティブの Java コードが呼び出される可能性があると思いますが、それについて調べる必要があります。

ThisThisは、関連する内部関数に関する興味深い読み物のように見えます。

Re: コールドスプリングに関する別の回答。Coldspring を使用した関数メタデータに関する詳細な記事を見つけました。

関連する質問: ColdFusion で私のものを拡張しているコンポーネントの名前を取得する方法は?

于 2009-02-20T00:24:34.723 に答える