Coldfusion“;例程不能声明多次";

Coldfusion“;例程不能声明多次";,coldfusion,coldfusion-9,application.cfc,Coldfusion,Coldfusion 9,Application.cfc,我们的Application.cfc中有以下代码: <cffunction name="onError" returnType="void" output="false"> <cfargument name="exception" required="true"> <cfargument name="eventname" type="string" required="true"> <cfset cfcatch = excepti

我们的Application.cfc中有以下代码:

<cffunction name="onError" returnType="void" output="false">
    <cfargument name="exception" required="true">
    <cfargument name="eventname" type="string" required="true">
    <cfset cfcatch = exception>
    <cfinclude template="standalone/errors/error.cfm">
</cffunction>

在error.cfm页面中,我们有以下代码(我没有编写):


函数GetCurrentURL(){
var theURL=“http”;
如果(cgi.https EQ“on”)theURL=“#theURL#s”;
theURL=theURL&“://#cgi.server#u name#”;
如果(cgi.server_port neq 80)URL=theURL&“:#cgi.server_port#”;
theURL=theURL&“cgi.path\u info”;
如果(len(cgi.query_string))theURL=theURL&“?#cgi.query_string#”;
返回URL;
}
这都是脚本的一部分,该脚本将有关错误的详细信息串在一起,并将其记录到数据库中

当出现错误时,我们会收到消息“例程GetCurrentURL在不同的模板中声明了两次”。然而,我用几种不同的方法搜索了整个代码库,发现“GetCurrentURL”只使用了两次,两次都在error.cfm中。第一次是声明,第二次是实际使用。所以我不知道为什么CF会说“在不同的模板中”

我的下一个想法是,问题是递归调用,error.cfm正在出错并调用自己,因此我尝试了这两个更改,其中任何一个都应该解决问题并揭示真正的错误:

<cfif StructKeyExists(variables,"GetCurrentURL") IS "NO">
    <cfscript>
            function GetCurrentURL() {
                var theURL = "http";
                if (cgi.https EQ "on" ) theURL = "#TheURL#s";
                theURL = theURL & "://#cgi.server_name#";
                if(cgi.server_port neq 80) theURL = theURL & ":#cgi.server_port#";
                theURL = theURL & "#cgi.path_info#";
                if(len(cgi.query_string)) theURL = theURL & "?#cgi.query_string#";
                return theURL;  
            }
    </cfscript>
</cfif>

函数GetCurrentURL(){
var theURL=“http”;
如果(cgi.https EQ“on”)theURL=“#theURL#s”;
theURL=theURL&“://#cgi.server#u name#”;
如果(cgi.server_port neq 80)URL=theURL&“:#cgi.server_port#”;
theURL=theURL&“cgi.path\u info”;
如果(len(cgi.query_string))theURL=theURL&“?#cgi.query_string#”;
返回URL;
}
以及:


如果(!StructKeyExists(变量,“GetCurrentURL”)){
函数GetCurrentURL(){
var theURL=“http”;
如果(cgi.https EQ“on”)theURL=“#theURL#s”;
theURL=theURL&“://#cgi.server#u name#”;
如果(cgi.server_port neq 80)URL=theURL&“:#cgi.server_port#”;
theURL=theURL&“cgi.path\u info”;
如果(len(cgi.query_string))theURL=theURL&“?#cgi.query_string#”;
返回URL;
}
}
两者都不起作用。我还尝试在函数调用之前将其添加到页面:

<cfoutput>"#StructKeyExists(variables,"GetCurrentURL")#"</cfoutput>
“#StructKeyExists(变量,“GetCurrentURL”)#”
它使“是”一词印在屏幕上。这表明上述方法应该有效,因为很明显,if语句的内容将计算为“YES”,因此if语句将计算为false,因此不会声明函数,因此我将保持理智。但出于某种原因,这个问题依然存在


对可能发生的情况或下一步如何排除故障有何想法?我被困在这一点上。

ColdFusion在将函数声明编译成字节码时仍然可以看到它。可以使用cfinclude包含函数声明:

<cfif StructKeyExists(variables,"GetCurrentURL") IS "NO">
<cfinclude template="udf.cfm" />
</cfif>


然后在udf.cfm中放置函数声明。这应该可以正常工作,并防止CF抛出错误。

另一种解决方案是在定义之前从作用域中删除函数。例如

<cfset StructDelete(variables,'myFunction')>
<cffunction name="myFunction">...</cffunction>

...

您确定error.cfm未包含在何处?它只包含在onError()中吗?是的,它只包含在onError()中。哦,是的!!为什么我没看到?仅仅解析声明是不够的。我打赌你是对的肖恩。。。美好的我最终通过将声明移动到Application.cfc来解决这个问题,但这涉及到一些负面的重新使用。在本地进行的初步测试表明,您的解决方案似乎工作得更好,因此我将努力将QAed应用到产品中。非常感谢!:)欢迎来到SO Marius,您能描述一下在哪里、如何以及为什么删除OP的函数可以解决这个问题吗?正如@SeanCoyne的回答中提到的,问题是例程声明错误不会发生在运行时——它发生在编译时。这意味着从
变量
范围中删除函数并不能解决问题。虽然@MariusMaxeiner的方法可以删除不需要的函数,但您无法使用它来防止编译错误。
<cfif StructKeyExists(variables,"GetCurrentURL") IS "NO">
<cfinclude template="udf.cfm" />
</cfif>
<cfset StructDelete(variables,'myFunction')>
<cffunction name="myFunction">...</cffunction>