Prestashop1.7.6.2产品自定义warranty字段保存正常读取为空问题
问题原因
$product->warranty读出来是null,本质是ObjectModel查数据的时候根本没把warranty列算进查询字段里,两个常见触发点:
- 覆写Product类时字段定义的写法有静态绑定问题,加上没清类加载缓存,系统没识别到你加的自定义字段
- 直接改核心文件后没刷新全量缓存,旧的类映射还在生效
分步修复
1. 改对Product覆写代码
打开/override/classes/Product.php,把构造函数里加字段定义的self::换成static::,用后期静态绑定避免指向父类定义,补全验证规则,修正后代码:
<?php class Product extends ProductCore { public $warranty; public function __construct($id_product = null, $full = false, $id_lang = null, $id_shop = null, Context $context = null) { // 别用self:: 这里必须用static:: 不然静态定义会指向父类,加的字段不生效 static::$definition['fields']['warranty'] = [ 'type' => self::TYPE_INT, 'lang' => false, 'validate' => 'isUnsignedInt', 'default' => 0 ]; parent::__construct($id_product, $full, $id_lang, $id_shop, $context); } }
你现在能正常存值说明warranty字段已经正确加到ps_product主表里了,不用再调整表结构。
2. 手动删全量缓存
别用后台自带的清理缓存功能,直接连服务器把项目下var/cache/目录里的prod、dev两个文件夹里的所有文件全删掉,重点是要删掉class_index.php这个类索引文件——PrestaShop全靠这个文件识别override目录下的覆写类,不删的话你改的Product类根本不会被系统加载。
3. 验证加载结果
清完缓存重新进产品编辑页,在mapStep6FormData方法里先打印get_class($product),确认返回的是Product而不是ProductCore,再打印$product->warranty,这时候已经能读到数据库里存的实际值,表单自然就能正常回显。
补充说明
你现在直接修改src目录下的核心文件、核心twig模板的做法不太稳妥,后续升级PrestaShop版本的时候所有改动都会被覆盖,长期用的话最好改成模块挂载产品页相关钩子的方式扩展,临时用的话记得做好改动文件的备份。
另外你给warranty设的是INT类型,表单用的是TextType,记得在数据映射的时候把提交上来的空字符串转成0,避免存库的时候出类型错误。
内容的提问来源于stack exchange,提问作者dodo

