我最近在CFC中创建了这个函数,它被实例化到Application范围:
Public String function url_for(path='') {
var results = '';
var these_parms = '';
var parm_delim = '?';
for (key in Arguments) {
if (len(Arguments[key])) {
switch(key) {
case "path":
results = '#arguments[key]#';
break;
case "template":
results = '/cf/#arguments[key]#';
break;
case "productid":
if (NOT comparenocase(left(arguments[key],2),'p_'))
results = real_url_for(partno=replace(arguments[key],'p_',''));
else
results = real_url_for(productid=arguments[key]);
break;
case "categoryid":
results = real_url_for(categoryid=arguments[key]);
break;
case "specialid":
results = real_url_for(specialid=arguments[key]);
break;
case "partno":
if (NOT len(arguments['path']))
results = real_url_for(partno=arguments[key]);
else
these_parms = listappend(these_parms,'#key#=#urlencodedformat(arguments[key])#','&');
break;
case "parms":
these_parms = listappend(these_parms,'#arguments[key]#','&');
break;
default:
these_parms = listappend(these_parms,'#key#=#urlencodedformat(arguments[key])#','&');
break;
}
}
}
if (len(results)) { //*********** error always occurs here
for (var i=1;i LTE variables.rewritequery.recordcount;i=i+1) {
if (NOT comparenocase(variables.rewritequery.internalurl[i], results)) {
results = variables.rewritequery.externalurl[i];
break;
}
}
}
if (len(results) AND len(these_parms)) {
if (listlen(results,'?') GT 1)
parm_delim = '&';
results = listappend(results, these_parms, parm_delim);
}
return results;
}
它每小时运行数百或数千次,有时在同一请求中运行数十次,但每隔几个小时就会抛出一个错误(总是在上面代码中标记的行):变量结果未定义
我无法检测出何时,如何或为何被抛出的模式。发生错误时使用的相同输入将在几秒后工作。主要是,我看不出它应该如何被抛出。
我认为被调用的函数(real_url_for)可能会返回一个未定义的值,但它具有相同的var results='';
,并且该变量是它返回给该函数的内容。
不知道这是否相关,但是application.cfm文件定义了一个包装函数app_url_for()
,它只是调用并返回该函数的值。这是为了避免在所有地方引用Application.URLManager.url_for()
。
这让我很难过。我想我可以检查变量是否存在,但是不应该这样做。
以下是real_url_for
功能:
Private String function real_url_for() {
var results = '';
for (key in Arguments) {
if (len(Arguments[key])) {
switch(key) {
case "productid":
results = '/cf/displaylearnmore.cfm?#key#=#arguments[key]#';
break;
case "categoryid":
results = '/cf/learnmorelist.cfm?#key#=#arguments[key]#';
break;
case "specialid":
results = '/cf/displayspecial.cfm?#key#=#arguments[key]#';
break;
case "partno":
results = '/part/#arguments[key]#';
break;
}
}
}
return results;
}
我会尝试将var key='';
添加到这两个功能中,看看是否有帮助。
答案 0 :(得分:1)
由于可变泄漏而听起来像竞争条件。略读代码我看到至少一个非变量范围的变量:key
。由于组件存储在application
范围内,多个线程很容易同时读取/写入该变量,从而导致错误或奇怪的结果。
首先检查调用的函数。验证所有函数局部变量是否已正确本地化。
答案 1 :(得分:1)
将key
变量声明为每个函数的本地变量似乎解决了问题。四天多没有复发。感谢所有提供反馈的人。