2009-02-19 12 views
13

Tworzę interfejs API, aw ramach każdej metody nawiązuję połączenie z metodą rejestrowania w celu audytu i rozwiązywania problemów. Coś jak:Czy metoda cfc ColdFusion może określić własną nazwę?

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

Chciałbym uniknąć ręcznego powtarzania nazwy metody. Czy istnieje sposób, aby go programowo określić?

Przyjrzałem się funkcji GetMetaData(), ale zwraca ona tylko informacje o komponencie (w tym wszystkich metodach), ale nie ma informacji o tym, która metoda jest obecnie wywoływana.

Odpowiedz

1

Cóż można spróbować to:

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

Próbowałem różnych rzeczy, a to nie jest dokładne, jak funkcje wydają się być dodane do tablicy funkcji w odwrotnej kolejności alfabetycznej. Wydaje się to ograniczające (i nie rozwiązuje problemu). Wyobrażam sobie, że można użyć jakiegoś natywnego kodu java, ale muszę się nad tym zastanowić.

This i This wyglądają jak interesujące czytanie na temat powiązanych funkcji wewnętrznych.

Re: Druga odpowiedź na temat zimnego źródła. Znalazłem this in depth article dla metadanych funkcji z coldspring.

Powiązane pytanie: How to get the name of the component that’s extending mine in ColdFusion?

11

więc teraz 3 sposoby.

Jeśli używasz ColdFusion 9.0 lub nowszego, jest teraz funkcja o nazwie GetFunctionCalledName(). Zwróci to, czego szukasz. http://help.adobe.com/en_US/ColdFusion/9.0/CFMLRef/WS7cc222be8a31a47d-6e8b7083122cebfc8f2-8000.html

LUB

Zastosowanie Coldspring i Aspect Oriented Programming (http://www.coldspringframework.org/coldspring/examples/quickstart/index.cfm?page=aop) do obsługi to za Ciebie.

LUB

Użyj cfthrow wygenerować ślad stosu, który posiada informacje dla Ciebie:

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

Moja rekomendacja byłoby użyć getFunctionCalledName lub, jeśli nie na CF 9 Coldspring, jak to będzie prawdopodobnie kupię ci inne rzeczy.

+0

dobre połączenie w zimny okres, ale można by pomyśleć, że nie byłoby to tak skomplikowane. – ethyreal

4

Zgadzam się w/tpryan. ColdSpring czyni to bardzo łatwym. Jednak jest tu inna alternatywa. Zamiast analizować ślad stosu, można przeanalizować sam plik 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> 

Wyżej opisana dla ColdFusion 8. CFLOOP dodano wsparcie dla zapętlenie nad pliki linia po linii (i nie przeczytać cały plik do pamięci). Zrobiłem kilka testów porównujących metodę śledzenia stosu z analizą plików. Oba wypadły równie dobrze na małym CFC, który był wywoływany bezpośrednio z pojedynczego szablonu CFM. Oczywiście, jeśli masz bardzo duże CFC, metoda parsowania może być nieco wolniejsza. Z drugiej strony, jeśli masz duży ślad stosu (np. Jeśli korzystasz z popularnych frameworków), to parsowanie plików może być szybsze.

- = Viva ColdFusion = -

1

myślałem o inny sposób, który mógłby działać.

Konfiguracja coś OnMissingMethod tak:

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

Następnie wymienić każdego z regularnych metod z prefiksem („ukryte” w tym przykładzie), oraz oznaczyć je jako prywatne. Więc moja początkowa Przykładem może stać się:

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

Teraz wszystkie połączenia zostaną przechwycone przez onMissingMethod, która doda nazwę metody do argumentów, które przejdzie do prawdziwej metody.

Wady, jakie widzę, to to, że introspekcja nie działa poprawnie, a do wywoływania wszystkich funkcji trzeba używać nazwanych argumentów. Jeśli nie używasz nazwanych argumentów, argumenty będą losowo zmieniać kolejność w strukturze missingMethodNameArguments.

+0

To jest twórcze! nigdy nie myślałem o opakowaniu funkcji. – ethyreal

Powiązane problemy