🐛 DebugIntermédiaire PS 1.7 PS 8.x

Corriger l'erreur getIdProductAttributesByIdAttributes sur PrestaShop

Résolvez l'exception fatale getIdProductAttributesByIdAttributes qui bloque vos déclinaisons PrestaShop. Override complet, diagnostic et bonnes pratiques.

En bref : L'erreur 500 sur les déclinaisons PrestaShop provient de la méthode getIdProductAttributeByIdAttributes() qui lève une exception au lieu de gérer gracieusement les combinaisons manquantes. La solution : un override résilient de Product.php qui retourne 0, combiné à un nettoyage des entrées orphelines en base de données.

Publié le 21 mars 2026 6 min de lecture Alexandre Carette

Le symptôme : une erreur 500 inexplicable sur les fiches produit

Vous naviguez sur votre boutique PrestaShop, vous sélectionnez une déclinaison sur une fiche produit et — écran blanc, erreur 500. Le back-office fonctionne, les autres pages aussi, mais dès qu'un visiteur tente de choisir une combinaison de taille ou de couleur, tout s'effondre.

Le coupable est souvent la méthode getIdProductAttributesByIdAttributes() de la classe Product, qui lève une exception fatale quand elle ne trouve pas la correspondance en base de données entre un produit et ses attributs.

Activer le mode debug pour identifier l'erreur

Avant toute intervention, il est indispensable d'activer le mode debug pour obtenir la stack trace complète plutôt qu'un simple écran blanc.

Dans le fichier config/defines.inc.php :


define('_PS_MODE_DEV_', true);

Sur PrestaShop 8.x, vous pouvez également passer par le back-office : Paramètres avancés → Performances → Mode debug.

Une fois activé, l'erreur affichée ressemblera à :


PrestaShopObjectNotFoundException: Product attribute not found
in classes/Product.php at line XXXX

Cette trace vous confirme que c'est bien getIdProductAttributesByIdAttributes() qui lève l'exception.

Comprendre l'origine du problème

La méthode getIdProductAttributesByIdAttributes() interroge la table ps_product_attribute_combination pour retrouver l'identifiant d'une déclinaison à partir d'un produit et d'un groupe d'attributs (taille, couleur, etc.).

Le problème survient dans deux cas principaux :

1. Incohérence en base de données

Une déclinaison a été supprimée manuellement en base, ou un import CSV a créé des attributs orphelins. La table ps_product_attribute_combination ne contient plus la correspondance attendue, mais le front-end tente quand même de la résoudre.

Pour vérifier :


-- Rechercher les combinaisons orphelines
SELECT pac.id_product_attribute, pac.id_attribute
FROM ps_product_attribute_combination pac
LEFT JOIN ps_product_attribute pa
  ON pa.id_product_attribute = pac.id_product_attribute
WHERE pa.id_product_attribute IS NULL;

-- Vérifier les déclinaisons d'un produit spécifique
SELECT pa.id_product_attribute, pac.id_attribute, al.name
FROM ps_product_attribute pa
INNER JOIN ps_product_attribute_combination pac
  ON pac.id_product_attribute = pa.id_product_attribute
INNER JOIN ps_attribute_lang al
  ON al.id_attribute = pac.id_attribute AND al.id_lang = 1
WHERE pa.id_product = 42
ORDER BY pa.id_product_attribute, pac.id_attribute;

2. Override ou module défectueux

Un module tiers a créé un override de Product.php dans /override/classes/Product.php qui redéfinit cette méthode de manière incorrecte, ou qui appelle une signature incompatible avec la version de PrestaShop installée.

Vérifiez l'existence d'un override :


ls -la override/classes/Product.php

Si ce fichier existe, examinez-le attentivement. Sur PrestaShop 8.x, la méthode native s'appelle getIdProductAttributeByIdAttributes() (sans le s après "Attribute"). Une confusion de nommage entre versions peut provoquer l'erreur.

La solution : un override résilient

L'approche recommandée consiste à surcharger la méthode pour qu'elle retourne gracieusement 0 au lieu de lever une exception fatale quand la déclinaison n'est pas trouvée. Cela évite le crash tout en permettant au front-end de gérer le cas.

Créez ou modifiez le fichier override/classes/Product.php :


<?php
/**
 * Override Product - Gestion résiliente des déclinaisons
 */
class Product extends ProductCore
{
    /**
     * Retrouve l'id_product_attribute à partir des id_attribute.
     * Retourne 0 au lieu de lever une exception si la combinaison n'existe pas.
     *
     * @param int $idProduct
     * @param array $idAttributes
     * @param bool $findBest
     * @return int
     */
    public static function getIdProductAttributeByIdAttributes($idProduct, $idAttributes, $findBest = false)
    {
        $idProduct = (int) $idProduct;

        if (!is_array($idAttributes) && is_numeric($idAttributes)) {
            $idAttributes = [(int) $idAttributes];
        }

        if (!is_array($idAttributes) || empty($idAttributes)) {
            return 0;
        }

        $idAttributesImploded = implode(',', array_map('intval', $idAttributes));
        $nbAttributes = count($idAttributes);

        $idProductAttribute = (int) Db::getInstance()->getValue('
            SELECT pac.`id_product_attribute`
            FROM `' . _DB_PREFIX_ . 'product_attribute_combination` pac
            INNER JOIN `' . _DB_PREFIX_ . 'product_attribute` pa
                ON pa.id_product_attribute = pac.id_product_attribute
            WHERE pa.id_product = ' . $idProduct . '
                AND pac.id_attribute IN (' . $idAttributesImploded . ')
            GROUP BY pac.id_product_attribute
            HAVING COUNT(pac.id_attribute) = ' . $nbAttributes
        );

        if (empty($idProductAttribute) && $findBest) {
            // Recherche de la meilleure correspondance partielle
            $idProductAttribute = (int) Db::getInstance()->getValue('
                SELECT pac.`id_product_attribute`
                FROM `' . _DB_PREFIX_ . 'product_attribute_combination` pac
                INNER JOIN `' . _DB_PREFIX_ . 'product_attribute` pa
                    ON pa.id_product_attribute = pac.id_product_attribute
                WHERE pa.id_product = ' . $idProduct . '
                    AND pac.id_attribute IN (' . $idAttributesImploded . ')
                GROUP BY pac.id_product_attribute
                ORDER BY COUNT(pac.id_attribute) DESC
                LIMIT 1
            ');
        }

        return (int) $idProductAttribute;
    }
}

Points clés de cet override

  • **Validation d'entrée souple** : au lieu de lever une `PrestaShopException` sur un paramètre invalide, on retourne `0`. Le front-end affichera simplement le produit sans déclinaison présélectionnée.
  • **Cast systématique** : `array_map('intval', $idAttributes)` protège contre les injections SQL.
  • **Clause HAVING** : garantit que toutes les attributs demandés correspondent, pas seulement un sous-ensemble.
  • **Mode `findBest`** : permet de retrouver la correspondance partielle la plus proche quand la combinaison exacte n'existe pas.

Après l'override : vider le cache de classes

PrestaShop compile les overrides dans un fichier unique. Après toute modification :


# Supprimer le cache des classes
rm -f var/cache/prod/class_index.php
rm -f var/cache/dev/class_index.php

# Sur PrestaShop 1.7.x
rm -f app/cache/prod/class_index.php
rm -f app/cache/dev/class_index.php

Ou depuis le back-office : Paramètres avancés → Performances → Vider le cache.

Corriger les données en base si nécessaire

Si le diagnostic révèle des entrées orphelines, nettoyez-les :


-- Supprimer les combinaisons orphelines
DELETE pac FROM ps_product_attribute_combination pac
LEFT JOIN ps_product_attribute pa
  ON pa.id_product_attribute = pac.id_product_attribute
WHERE pa.id_product_attribute IS NULL;

-- Supprimer les déclinaisons sans combinaison
DELETE pa FROM ps_product_attribute pa
LEFT JOIN ps_product_attribute_combination pac
  ON pac.id_product_attribute = pa.id_product_attribute
WHERE pac.id_product_attribute IS NULL;

Important : faites toujours un backup de votre base avant d'exécuter des requêtes DELETE.

Prévenir la récurrence

Pour éviter que ce problème ne revienne :

  1. **Utilisez l'import natif** pour gérer vos déclinaisons plutôt que des requêtes SQL directes.
  2. **Auditez vos modules** : un module qui manipule les attributs sans passer par les classes ObjectModel peut créer des incohérences.
  3. **Mettez en place un cron de vérification** qui détecte les orphelins avant qu'ils ne causent des erreurs visibles :
  4. 
    // Script de vérification à exécuter en cron hebdomadaire
    $orphans = Db::getInstance()->executeS('
        SELECT pac.id_product_attribute, pac.id_attribute
        FROM `' . _DB_PREFIX_ . 'product_attribute_combination` pac
        LEFT JOIN `' . _DB_PREFIX_ . 'product_attribute` pa
            ON pa.id_product_attribute = pac.id_product_attribute
        WHERE pa.id_product_attribute IS NULL
    ');
    
    if (!empty($orphans)) {
        PrestaShopLogger::addLog(
            'Combinaisons orphelines détectées : ' . count($orphans),
            2 // Severity: Warning
        );
    }
    
#déclinaisons #override #Product.php #erreur 500 #product_attribute_combination

Questions fréquentes

Tout ce que vous devez savoir sur ce sujet.

Un projet PrestaShop ?

Discutons-en directement.

★★★★★

193 projets livrés

Gratuit & sans engagement — réponse sous 24h

Alexandre Carette

Alexandre Carette

Expert PrestaShop & Architecture E-commerce

Développeur PrestaShop depuis 2014, 193 projets livrés. Je conçois des architectures headless Nuxt + PrestaShop et des outils d'automatisation IA pour les e-commerçants.