Может ли метод ColdFusion cfc определить свое собственное имя? - PullRequest
13 голосов
/ 20 февраля 2009

Я создаю API, и в каждом методе я вызываю метод ведения журнала для аудита и устранения неполадок. Что-то вроде:

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

Я бы хотел избежать повторения названия метода вручную. Есть ли способ программно определить это?

Я посмотрел на GetMetaData (), но он возвращает только информацию о компоненте (включая все методы), но ничего не говорит о том, какой метод вызывается в данный момент.

Ответы [ 4 ]

11 голосов
/ 20 февраля 2009

Так что теперь 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), чтобы справиться с этим за вас.

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, так как он, вероятно, купит вам другие вещи.

4 голосов
/ 20 февраля 2009

Согласен с тпрян. 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 добавлена ​​поддержка циклического перемещения по файлам построчно (и не чтение всего файла в память). Я провел несколько тестов, сравнивая метод трассировки стека и анализ файла. Оба одинаково хорошо работают на небольшом CFC, вызываемом напрямую из одного шаблона CFM. Очевидно, что если у вас очень большие CFC, метод синтаксического анализа может быть немного медленнее. С другой стороны, если у вас трассировка большого стека (например, если вы используете какую-либо из популярных платформ), анализ файла может быть быстрее.

- = Viva ColdFusion = -

1 голос
/ 22 февраля 2009

Я подумал о другом способе работы.

Настройте метод 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») и отметьте их как private. Итак, мой первоначальный пример стал бы:

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

Теперь все вызовы будут перехвачены onMissingMethod, который добавит имя метода к аргументам, которые передаются реальному методу.

Недостатки, которые я вижу в этом, это то, что самоанализ больше не работает должным образом, и вы должны использовать именованные аргументы для вызова всех ваших функций. Если вы не используете именованные аргументы, аргументы будут случайным образом менять порядок в структуре missingMethodNameArguments.

1 голос
/ 20 февраля 2009

Ну, вы можете попробовать это:

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

Я пробовал разные вещи, и это не совсем верно, поскольку функции, кажется, добавляются в массив функций в обратном алфавитном порядке. Это кажется ограничивающим (и не решающим проблему). Я полагаю, что может быть вызван некоторый нативный код Java, но мне нужно разобраться в этом.

Это и Это выглядит как интересное чтение по связанным внутренним функциям.

Re: Другой ответ на coldspring. Я нашел эту статью о метаданных функции с coldspring.

Смежный вопрос: Как получить имя компонента, расширяющего мой в ColdFusion?

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...