You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

PrestaShop脚本添加商品附件后前端不显示问题求助

PrestaShop商品附件前端不显示问题排查与解决思路

问题背景

我编写了PHP脚本为已导入的PrestaShop商品添加附件,ps_attachment、ps_attachment_lang等3张数据表已正确填充,后台商品页面“选项”标签中能看到附件已勾选,但附件在前端商品页面无法显示,仅在点击后台的“预览”或“保存”操作后才会显示。

已执行的操作:

  • 清空缓存
  • 删除var/cache下的dev和prod缓存文件夹
  • 编写调用$product->save()方法的PHP脚本

原附件添加脚本

<?php
$csvFile = "xxxx.csv";
if (($handle = fopen($csvFile, "r")) !== FALSE) {
// Parcours des lignes du fichier CSV
while (($data = fgetcsv($handle, 1000, ",")) !== FALSE) {

   $reference = $data[0]; // Référence du produit
   $files = explode(",", $data[1]); // Chemins vers les fichiers (séparés par une virgule)

   // Récupération de l'ID du produit
   $sql = "SELECT id_product FROM ps_product WHERE reference = '$reference'";
   $result = $conn->query($sql);

   echo "$reference";

   if ($result->num_rows > 0) {
       $row = $result->fetch_assoc();
       $productId = $row["id_product"];

       echo "$productId";

       // Parcours des fichiers joints
       foreach ($files as $file) {
           // Obtention de la taille du fichier en octets
           $fileSize = filesize($file);
           $fileName = basename($file); // Nom du fichier

           // Vérification si le fichier existe déjà pour le produit donné
           $sqlCheck = "SELECT id_attachment FROM ps_product_attachment WHERE id_product = '$productId'";
           $resultCheck = $conn->query($sqlCheck);

           $attachmentId = null;

           if ($resultCheck->num_rows > 0) {
               // Parcourir les résultats pour vérifier si le fichier existe déjà
               while ($rowCheck = $resultCheck->fetch_assoc()) {
                   $existingAttachmentId = $rowCheck["id_attachment"];

                   // Vérifier si le fichier est déjà associé au produit
                   $sqlFileCheck = "SELECT id_attachment FROM ps_attachment WHERE id_attachment = '$existingAttachmentId' AND file = '$file'";
                   $resultFileCheck = $conn->query($sqlFileCheck);

                   if ($resultFileCheck->num_rows > 0) {
                       // Le fichier existe déjà pour le produit donné
                       $attachmentId = $existingAttachmentId;
                       break;
                   }
               }
           }

           if ($attachmentId === null) {
               // Le fichier n'existe pas encore pour le produit, l'insérer dans ps_attachment
               $sqlInsertAttachment = "INSERT INTO ps_attachment (file, file_name, file_size, mime) VALUES ('$file', '$fileName', '$fileSize', 'application/pdf')";
               if ($conn->query($sqlInsertAttachment) === TRUE) {
                   $attachmentId = $conn->insert_id;
               } else {
                   echo "Erreur lors de l'ajout du fichier joint : " . $conn->error . "\n";
               }
           }

           if ($attachmentId !== null) {
               // Associer le fichier joint au produit dans ps_product_attachment
               $sqlInsertProductAttachment = "INSERT INTO ps_product_attachment (id_product, id_attachment) VALUES ('$productId', '$attachmentId')";
               if ($conn->query($sqlInsertProductAttachment) === TRUE) {
                   echo "Fichier joint ajouté avec succès pour le produit $reference.\n";

                   // Récupération de l'ID de l'attachment après insertion
                   $idAttachment = $attachmentId;

                   // Parcours des langues prises en charge
                   $idLang = 1;
                   $name = $data[$idLang]; // Récupération du nom du fichier joint dans la langue spécifiée
                   $description = $data[$idLang]; // Récupération de la description du fichier joint dans la langue spécifiée

                   // Insertion des informations de langue dans la table ps_attachment_lang
                   $sqlInsertAttachmentLang = "INSERT INTO ps_attachment_lang (id_attachment, id_lang, name, description) VALUES ('$idAttachment', '$idLang', '$name', '$description')";
                   if ($conn->query($sqlInsertAttachmentLang) === TRUE) {
                       echo "Informations de langue ajoutées avec succès pour l'attachment $idAttachment et la langue $idLang.\n";
                   } else {
                       echo "Erreur lors de l'ajout des informations de langue : " . $conn->error . "\n";
                   }
               } else {
                   echo "Erreur lors de l'association du fichier joint pour le produit $reference : " . $conn->error . "\n";
               }
           }
       }
   } else {
       echo "Produit non trouvé pour la référence : $reference.\n";
   }
}
fclose($handle);
}

$conn->close();

?>

尝试的$product->save()脚本

<?php

require(dirname(__FILE__).'/config/config.inc.php');

define('_PS_ROOT_DIR_', dirname(dirname(__FILE__)).'/');
// Inclusion de la classe Product
require_once _PS_ROOT_DIR_ . '/classes/Product.php';

// Liste des références de produits à cibler
$targetReferences = array(
'20052'
);

foreach ($targetReferences as $reference) {
// Recherche du produit par référence
$productId = Product::getIdByReference($reference);

if ($productId) {
    $product = new Product($productId);

    // Enregistrer les options sans modification
    $product->save();



    echo "Produit mis à jour pour la référence : " . $reference . "<br>";
} else {
    // Gérer le cas où la référence du produit n'est pas trouvée
    echo "Produit non trouvé pour la référence : " . $reference . "<br>";
}
}

?>

解决思路

1. 强制同步产品索引与附件关联

后台点击保存/预览时,PrestaShop会自动刷新产品索引表(如ps_product_index)并更新缓存关联。直接操作数据库添加附件后,这些关联未同步,导致前端无法读取。修改更新脚本,主动触发索引更新:

$product = new Product($productId);
// 强制重新加载附件关联
$product->attachments = $product->getAttachments(Context::getContext()->language->id);
// 触发产品属性与索引更新
Product::updateProductAttributes($productId);
$product->save();

2. 校验附件路径格式

前端显示附件需要符合PrestaShop规范的路径,对比后台手动添加的附件file字段值,确保脚本插入的路径格式一致(比如是否带/前缀、相对路径是否正确)。

3. 全量清理缓存

除删除var/cache下的文件夹,还需:

  • 后台“高级参数>性能”中点击“清除缓存”,选择清除所有缓存
  • 若使用Redis等外部缓存,同步清除对应产品的缓存数据

4. 使用官方类方法替代直接SQL操作

直接操作数据库容易遗漏内部钩子和关联逻辑,改用Attachment类方法处理:

// 创建附件
$attachment = new Attachment();
$attachment->file = $file;
$attachment->file_name = $fileName;
$attachment->file_size = $fileSize;
$attachment->mime = 'application/pdf';
$attachment->add();

// 设置多语言信息
$attachment->name[$idLang] = $name;
$attachment->description[$idLang] = $description;
$attachment->update();

// 关联到产品
$attachment->attachToProduct($productId);

该方式会自动触发内部关联更新与缓存刷新,避免遗漏步骤。


内容的提问来源于stack exchange,提问作者Bahwaimongars

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.16 05:14:54