Yii2+MySQL批量复制商品描述时img宽高属性丢失求助
解决批量复制商品描述时img标签宽高属性丢失问题
问题定位步骤
先明确问题出在读取数据阶段还是写入数据阶段:
- 在循环里添加日志代码,输出从
Parsing表读取到的原始描述内容:
查看项目$rowParse = Parsing::find()->where(['art_post' => $value])->one(); // 新增日志,查看原始描述 Yii::info("当前商品art_post: {$value},原始描述:" . $rowParse->description, 'copy-debug'); $desc = $rowParse->description; // 后续更新代码不变runtime/logs/app.log日志文件,如果日志里的img标签已经没有宽高属性,说明问题出在Parsing模型的读取逻辑;如果日志里属性存在,说明问题出在写入products表的过程中。
针对性解决方案
情况1:读取阶段丢失属性
检查Parsing模型代码,排查自动修改描述的逻辑:
- 查看模型的
afterFind方法,是否存在清理img属性的代码,比如:
若有这类逻辑,注释掉或修改正则表达式以保留宽高属性。public function afterFind() { parent::afterFind(); // 这类代码会移除宽高属性 $this->description = preg_replace('/<img(.*?)width=".*?"(.*?)height=".*?"(.*?)>/i', '<img$1$3>', $this->description); } - 检查是否有自定义的
getDescription方法,确认返回值未被处理。 - 检查模型是否附加了
HtmlPurifierBehavior等HTML净化行为,确保配置中允许width和height属性:public function behaviors() { return [ [ 'class' => \yii\behaviors\HtmlPurifierBehavior::class, 'attributes' => ['description'], 'purifierConfig' => [ 'HTML.AllowedAttributes' => 'img.src,img.width,img.height', // 必须包含width和height ], ], ]; }
情况2:写入阶段丢失属性
检查products模型代码:
- 查看
beforeSave或beforeUpdate方法,是否存在净化描述的逻辑,处理方式同上,确保保留img的宽高属性。 - 确认
products表的description字段类型为TEXT或LONGTEXT,字符集设置为utf8mb4,避免因字段长度不足导致内容截断。
优化方案:改用批量更新
循环单条更新效率低且易触发不必要的模型钩子,可改用批量更新方式减少数据库交互:
// 假设$batchData是包含id_post、art_post的数组集合 $artPostList = array_column($batchData, 'art_post'); // 批量获取Parsing表中的描述数据 $parsingMap = Parsing::find() ->select(['art_post', 'description']) ->where(['art_post' => $artPostList]) ->indexBy('art_post') ->asArray() ->all(); // 构建批量更新语句 $caseClauses = []; $conditionClauses = []; $params = []; foreach ($batchData as $item) { $artKey = ":art_{$item['art_post']}"; $descKey = ":desc_{$item['art_post']}"; $idKey = ":id_{$item['id_post']}"; $caseClauses[] = "WHEN {$artKey} THEN {$descKey}"; $conditionClauses[] = "`art_post` = {$artKey} AND `id_post` = {$idKey}"; $params[$artKey] = $item['art_post']; $params[$descKey] = $parsingMap[$item['art_post']]['description'] ?? ''; $params[$idKey] = $item['id_post']; } $updateSql = <<<SQL UPDATE `products` SET `description` = CASE `art_post` {$caseClauses} END WHERE {$conditionClauses} SQL; Yii::$app->db->createCommand($updateSql)->bindValues($params)->execute();
内容的提问来源于stack exchange,提问作者riskindness
相关产品推荐
相关产品推荐

