ColdFusion的隐式访问器出现问题

时间:2019-01-21 13:49:55

标签: coldfusion accessor cfml cfc

带有隐式访问器的问题

我们的开发团队最近发现,使用隐式get访问器(person.firstName)而不是生成的get访问器(person.getFirstName())时,我们遇到了多个错误。以下是有关如何重现该错误的说明:

  1. 使用以下文件创建新的ColdFusion应用程序:

Application.cfc:

component {
    this.invokeImplicitAccessor = true;
}

Person.cfc:

component accessors=true {
    property firstName;
}

index.cfm:

local.person = new Person();
local.person.firstName = "Zachary";

for( local.i = 0; local.i lt 1000; local.i++ ) {
    local.j = local.person.firstName;
}

index2.cfm:

local.person = new Person();
local.person.firstName = "Zachary";

for( local.i = 0; local.i lt 1000; local.i++ ) {
    local.j = local.person.getFirstName();
}
  1. 使用JMeter测试index.cfm,使用2000个线程,启动周期为10秒,循环计数为1(测试计划:https://pastebin.com/nBtpL4zP

  2. 在我们的测试中,页面总是失败,并显示相同的错误消息:

元素PERSON.FIRSTNAME在本地中未定义。

  1. 使用上述设置得到的错误%通常介于8%至10%之间,这意味着> 2000个请求中有160至200个请求失败。

  2. 当使用相同的设置测试index2.cfm时,我们不会出现任何错误

以下是有关测试环境的一些详细信息:

操作系统:Windows Server 2016 Standard ColdFusion:Adobe ColdFusion 2018版本 JMeter 5.0(https://jmeter.apache.org/download_jmeter.cgi

有人知道为什么会这样吗?有一些我们可以调整的ColdFusion设置吗?上面的示例应用程序非常小,我们没有做任何特别的事情,因此我看不到任何隐式访问器失败的原因,尤其是当生成的访问器似乎通过了相同的测试而没有任何问题时。

我们非常感谢您对如何使隐式访问器起作用的任何帮助或建议。

编辑:修复了index2.cfm使用get()方法代替隐式访问器的问题。

EDIT2:完整的错误消息/页面:https://pastebin.com/budqiV1m

EDIT3:我为此创建了一个错误报告:https://tracker.adobe.com/#/view/CF-4203997

1 个答案:

答案 0 :(得分:0)

访问器是函数。如果有

  component accessors=true {
    property name="foo";
  }

使用隐式访问器的正确方法是 this.getFoo() getFoo()(在组件内部)或 myComponent.getFoo()< / strong>。

this.getFoo 是指向吸气剂的指针,而不是吸气剂本身的指针。在您的示例中, local.j = local.person.firstName; 将j设置为指向吸气剂的指针,而不是属性的值;如果确实要使用隐式访问器,则应为 person.getFirstName()

现在已经不是很多年了,显式getter或setter更快(在ACF或Lucee上)。当然,您仍然可以在需要时编写它们,并且它们会覆盖隐式函数。

尽管此示例来自Adobe的ORM文档,但它更好地说明了应如何使用隐式访问器:

https://helpx.adobe.com/coldfusion/developing-applications/coldfusion-orm/working-with-objects/generated-accessors.html

这是一个更完整的解释-即使是针对Lucee的,它在ACF中也是如此:

https://rorylaitila.gitbooks.io/lucee/content/properties.html

最后,虽然与问题不相关,但 local 范围是函数范围,而在.cfm页面上只是变相的变量范围。您可以从所有代码中删除 local ,因为这可能会误导您-除非您位于.cfm页(不应属于)中的函数定义内,否则您位于变量范围内如果您想明确一点,那就应该使用变量。