SuiteCRM 7.8中SugarBean字段访问规则的技术咨询
SuiteCRM SugarBean字段访问规则详解
我来帮你理清SuiteCRM 7.8里SugarBean对象字段访问的这两种方式的规则——这确实是老版本SuiteCRM里容易踩的坑!
先搞懂fetched_row是什么
$bean->fetched_row本质是SugarBean从数据库加载出来的原始数据快照:
- 只有当Bean是从数据库读取(比如编辑已有记录)、或者主动调用过
$bean->retrieve()方法后,这个数组才会被填充。 - 如果是新建的记录(第一次执行save操作),
fetched_row会是false或者空数组,因为这条记录还没从数据库拉取过数据。
两种访问方式的适用场景
1. 使用$bean->fetched_row['field_name']的情况
- 你需要获取记录修改前的原始值:比如在
after_save钩子中,想对比字段修改前后的差异,这时候$bean->field_name已经是修改后的新值,而fetched_row里保存的是修改前的旧值。 - 系统核心字段的特殊情况:像
date_entered、date_modified这类自动生成的系统字段,在某些模块的钩子触发时机里,Bean的直接属性可能还没同步数据库的值,这时候就需要从fetched_row中读取。比如你遇到的AOS_Quotes模块的date_entered,因为它是记录创建时数据库自动写入的,在after_save的某个阶段,Bean的直接属性还没刷新,而fetched_row里是数据库中的真实值。
2. 使用$bean->field_name的情况
- 你需要获取当前内存中Bean的最新值:包括刚修改还未保存的临时值,或者刚保存后内存里的最新数据。
- 处理新建记录的时候:因为新建记录的
fetched_row还未初始化(只有从数据库读取的Bean才会生成这个快照),比如你遇到的AOS_Products_Quotes模块,大概率是触发钩子时正在创建这条关联记录,所以fetched_row为false,只能通过直接访问属性来获取字段值。
针对你遇到的模块差异解释
- AOS_Quotes的
date_entered:这个字段是记录创建时一次性写入数据库的,在after_save钩子中,Bean的直接属性可能还没同步这个数据库自动生成的值,但fetched_row作为从数据库拉取的快照,已经包含了这个值,所以只能从这里读取。而其他用户编辑的字段,因为已经同步到Bean的内存属性中,所以可以直接访问。 - AOS_Products_Quotes的
fetched_row为false:几乎可以确定是你触发钩子时正在创建这条新的产品关联记录(比如从报价单里添加产品),此时这条记录是第一次被保存到数据库,还没有从数据库拉取过数据,所以fetched_row未被初始化,只能通过$bean->field_name访问字段。
通用兼容写法
如果你想写一个兼容两种情况的字段获取方法,可以试试这个:
function getBeanFieldValue($bean, $fieldName) { // 优先从fetched_row取(如果存在且有对应字段) if (!empty($bean->fetched_row) && isset($bean->fetched_row[$fieldName])) { return $bean->fetched_row[$fieldName]; } // 再尝试直接访问属性 elseif (isset($bean->$fieldName)) { return $bean->$fieldName; } // 都没有返回null return null; }
内容的提问来源于stack exchange,提问作者nyluje
相关产品推荐
相关产品推荐

