Список статических ключей/значений ColdFusion?

У меня есть таблица базы данных, которая представляет собой словарь определенных терминов — ключ, значение. Я хочу загрузить словарь в область приложения из базы данных и сохранить его там для производительности (он не меняется).

Я понимаю, что это, вероятно, своего рода "структура", но я крайне новичок в ColdFusion (помогаю другой команде).

Затем я хотел бы выполнить простую замену строк в некоторых строках, выводимых в браузер, перебирая определенные термины и заменяя термины некоторым HTML для определения терминов (наведение или ссылка, детали будут разработаны позже). , не важно).

Это код, который сейчас находится в файле application.cfc:

<cffunction name="onApplicationStart">
<cfquery name="qryDefinedTerms" datasource="mydsn">
       SELECT term, definition FROM definedterms
    </cfquery>
<cfset application.definedterms = Array(1)>
<cfloop query="qryDefinedTerms">
    <cfset myHash = structNew()>
    <cfset myHash.put("term", qryDefinedTerms.term)>
    <cfset myHash.put("definition", qryDefinedTerms.definition)>
    <cfset ArrayAppend(application.definedterms, myHash)>
</cfloop>
</cffunction>

Вызывающая страница пытается использовать его следующим образом:

function ReplaceDefinitions(inputstring) {
    for (thisdef = 1 ;
        thisdef LTE ArrayLen(application.definedterms);
        thisdef = (thisdef+1)) {
        inputstring = Replace(inputstring, 
           application.definedterms(thisdef).term, 
           application.definedterms(thisdef).definition, "ALL");
    }
    return inputstring;
}

Когда я вызываю функцию, я получаю ответ: «Элемент DEFINEDTERMS не определен в APPLICATION».

Редактировать: принудительный вызов OnApplicationStart() сработал, видимо, application.cfc Cold Fusion не похож на web.config ASP.NET, его изменение не приводит к сбросу приложения.


person richardtallent    schedule 19.04.2010    source источник
comment
Вероятно, глупый вопрос, но перезапускали ли вы свое приложение после добавления нового кода? Если бы вы просто изменили application.cfc без перезапуска, структура не была бы создана (поскольку метод onApplicationStart уже был бы запущен). Я уже сталкивался с этим несколько раз.   -  person derivation    schedule 20.04.2010
comment
Дамми меня из ASP.NET, я предположил, что редактирование файла application.cfc поможет, особенно потому, что изменения, которые я делаю в application.cfc, вызывают ошибки, когда он не компилируется. Как сбросить приложение? (У меня есть доступ только к файловому серверу, нет доступа к инструментам администрирования CF.)   -  person richardtallent    schedule 20.04.2010


Ответы (3)


Вы задали много отдельных вопросов, но я постараюсь на них ответить! Вы также не сказали, какую версию ColdFusion вы используете, поэтому я собираюсь ответить кодом, который будет работать в ColdFusion 8 и выше.

ColdFusion использует специальный файл Application.cfc, который вы добавляете в маршрут своего веб-приложения (аналогично Global.asax в ASP.Net). У него есть метод in, называемый onApplicationStart, который выполняется только при запуске приложения (поэтому не при каждом запросе). Это отличное место для размещения любых констант. Вот простой пример, который задает структуру (например, карту в других языках) с использованием синтаксиса {}:

Приложение.cfc

<cfcomponent>
  <cffunction name="onApplicationStart">
    <!--- set global constants here --->
    <cfset application.foo = { a=1, b=2, c="my string" }>
  </cffunction>
</cfcomponent>

Если вы хотите получить данные из базы данных, вот простой способ сделать это (есть много других способов, которые, вероятно, лучше, но это должно помочь вам начать!)

<cfcomponent>
  <cffunction name="onApplicationStart">
    <!--- set global constants here --->
    <cfset application.datasource = "mydsn">

    <cfquery name="qryConstants" datasource="#application.datasource#">
      select key, value
      from tblConstants
    </cfquery>

    <cfset application.constants = {}>
    <cfloop query="qryConstants">
      <cfset application.constants[ qryConstants.key ] = qryConstants.value>
    </cfloop>
  </cffunction>

</cfcomponent>

Что касается замены значений в строке, вы можете сделать что-то вроде этого:

какой-то скрипт.cfm

<cfsavecontent variable="somestring">
Hello, ${key1} how are you? My name is ${key2} 
</cfsavecontent>

<!--- replace the ${key1} and ${key2} tokens --->
<cfloop collection="#application.constants#" item="token">
  <cfset somestring = ReplaceNoCase( somestring, "${#token#}", application.constants[ token ], "all" )>
</cfloop>

<!--- show the string with tokens replaced --->
<cfoutput>#somestring#</cfoutput>

Как я уже сказал, есть много способов решить ваш вопрос, однако, надеюсь, вы найдете это хорошей отправной точкой (хотя я не проверял это!).

Удачи и добро пожаловать в ColdFusion!

  • Джон
person John Whish    schedule 19.04.2010
comment
Должно быть, я использую более старую версию ColdFusion... Я получаю Invalid token '{' в строке вместо cfset application.constants. - person richardtallent; 20.04.2010
comment
Ах, хорошо, вы можете узнать, какую версию вы используете, используя SERVER.ColdFusion.ProductVersion. Вы не можете использовать сокращенный синтаксис для структур до CF8, но вы можете создавать их следующим образом: application.constants = StructNew(); application.constants.key1 = 123; application.constants.key2 = ABC; - person John Whish; 20.04.2010

Кроме того, исправьте объявление массива в Application.cfc. Это должен быть ArrayNew(1), а не Array(1). Затем попробуйте повторно инициализировать переменные приложения. Один из способов — использовать cfinvoke:

<cfinvoke component="Application" method="OnApplicationStart" />

После того, как вы сделали это и внесли некоторые изменения, упомянутые Беном. Функция должна работать. Примечание. Вы можете использовать более короткие операторы ‹= и ++, если используете CF8+.

<cfscript>
   // Added variable scoping
   function ReplaceDefinitions(inputstring) {
      var thisdef = "";
      var newString = arguments.inputstring;
       for (thisdef EQ 1 ; thisdef LTE ArrayLen(application.definedterms); thisdef = thisdef+1) {
           newString = Replace(   newString, 
                                application.definedterms[thisdef].term, 
                                application.definedterms[thisdef].definition, 
                                "ALL" );
       }   
       return newString;
   }
</cfscript>
person Leigh    schedule 19.04.2010

Не заглядывая слишком глубоко, я вижу, что это:

application.definedterms(thisdef).term

должно быть так:

application.definedterms[thisdef].term

В CF (как и во многих языках) круглые скобки означают вызов функции, а квадратные скобки — ссылку на массив.

person Ben Doom    schedule 19.04.2010
comment
Спасибо... исправлено, но в строке выше вызов ArrayLen() не работает. - person richardtallent; 20.04.2010
comment
Попробуйте передать массив структур в качестве аргумента функции вместо того, чтобы пытаться вызывать область приложения из вашей функции. например, ReplaceDefinitions(inputstring,definedterms) и ссылка как часть области действия аргументов. - person Ben Doom; 20.04.2010