Тестирование на наличие области действия / структуры FORM в ColdFusion
-
05-07-2019 - |
Вопрос
Проблема: при запросе WSDL для CFC , я получаю следующую ошибку: переменная FORM не определена . Это происходит в этой строке кода, в методе OnRequestStart в application.cfc
<cfif structKeyExists(form,'resetappvars')>
<cfset OnApplicationStart() />
</cfif>
Если я запрашиваю определенный метод, он работает нормально. Я рассмотрел использование cfparam для создания структуры формы по умолчанию, если таковой не существует, но это кажется уродливым хаком, и я беспокоюсь, что это фактически создаст структуру формы в переменных или в этой области действия CFC. Может быть, это и допустимая ошибка?
Примечание. Это происходит только тогда, когда я запрашиваю WSDL, если я вызываю метод напрямую - код выполняется, как и ожидалось, без проблем.
Обновление: пример кода Application.cfc - просто добавьте любой CFC в свое приложение и запросите его с помощью ?wsdl
, чтобы увидеть проблему. Это было проверено (и не удалось) на ColdFusion 7 и ColdFusion 8.
<cfcomponent output="false">
<cffunction name="OnApplicationStart" access="public" returntype="boolean" output="false" hint="Fires when the application is first created.">
<cfset application.dsn = "my_dsn" />
<cfreturn true />
</cffunction>
<cffunction name="OnRequestStart" access="public" returntype="boolean" output="false" hint="Fires at first part of page processing.">
<cfargument name="TargetPage" type="string" required="true" />
<cfif structKeyExists(form,'resetappvars')>
<cfset OnApplicationStart() />
</cfif>
<cfreturn true />
</cffunction>
</cfcomponent>
Решение
В этой записи Бена Наделя приведен подробный список Области доступны для различных типов запросов.
Прочитав его, вы легко обнаружите, что область действия form недоступна в данном контексте, но url есть.
Другие советы
Возможно, попробуйте добавить:
<cfif IsDefined("form")>...</cfif>
вокруг приведенного выше кода?
Вы также можете cfparam
найти нужную переменную и просто немного изменить логику (при условии, что resetAppVars является логическим значением:
<cfparam name="form.resetAppVars" default="false" />
...
<cfif form.resetAppVars>
<cfset OnApplicationStart() />
</cfif>
Редактировать: я не уверен, что приведенный выше код можно считать хаком, но мне кажется, что это довольно стандартный CF.
Я слышал, что это просто вопрос мнения, но мне кажется, что неправильно ссылаться на вашу область формы в CFC, так как нет никакой гарантии, что область формы будет доступна при вызове вашего cfc и когда ваш метод вызывается. Лучше убедиться, что любые данные, которые должны быть доступны для метода, предоставлены явно вашему объекту. Это можно сделать, включив аргумент:
<cfargument name="resetAppVars" type="boolean" required="false" default="false" />
Затем вы проверяете arguments.resetAppVars, и он всегда определяется, но по умолчанию имеет значение false.
Или путем создания атрибута для вашего объекта и создания метода явного набора:
(вверху вашего cfc)
<cfset this.resetAppVars = false />
<cffunction name="setResetAppVars" access="public" returnType="void" output="false">
<cfargument name="flagValue" type="boolean" required="true" />
<cfset this.resetAppVars = arguments.flagValue />
</cffunction>
В этом случае вы будете проверять this.resetAppVars. Вы также можете ограничить это локально, используя <cfset var resetAppVars = false />
в качестве объявления, что делает его закрытым атрибутом вашего объекта и, вероятно, является правильным, поэтому код, вызывающий объект, не может неправильно перезаписать эту переменную не-логическим типом. В этом случае вы просто будете обращаться непосредственно к resetAppvars в своем тесте, а не использовать эту область.
Вы также можете сделать это:
<cfif NOT isSoapRequest()>...
и вставьте оставшуюся логику в этот кусок.