💻 DéveloppementAvancé PS 1.6 PS 1.7 PS 8.x

Forcer l'ID produit lors de la création dans PrestaShop

Comment imposer un id_product spécifique à la création d'un produit PrestaShop. Méthode ObjectModel::add() avec force_id, alternatives SQL et bonnes pratiques.

En bref : Pour forcer un id_product à la création dans PrestaShop, utilisez $product->force_id = true avant add() plutôt que des UPDATE SQL manuels qui oublient des tables et cassent l'intégrité référentielle.

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

Forcer l'ID produit lors de la création dans PrestaShop

Lors d'une migration de catalogue, d'une synchronisation ERP ou d'un import personnalisé, il est fréquent de devoir créer des produits avec un identifiant précis plutôt que de laisser PrestaShop attribuer un auto-increment. Le réflexe naturel — affecter $product->id_product avant d'appeler add() — ne fonctionne pas. Voici pourquoi, et comment résoudre ce problème proprement.

Pourquoi `$product->id_product = 40` ne fonctionne pas

La classe Product hérite d'ObjectModel, le socle ORM de PrestaShop. Quand on appelle $product->add(), la méthode exécute un INSERT SQL classique. Par défaut, ObjectModel ignore volontairement toute valeur assignée à la clé primaire : il laisse MySQL générer l'auto-increment, puis récupère l'ID via Db::getInstance()->Insert_ID().

Concrètement, dans classes/ObjectModel.php, la méthode add() construit la requête INSERT sans inclure le champ de clé primaire, sauf si on lui indique explicitement de le faire.


// Ce code ne force PAS l'ID — il sera ignoré
$product = new Product();
$product->id = 40;
$product->name = [(int)Configuration::get('PS_LANG_DEFAULT') => 'Mon produit'];
$product->link_rewrite = [(int)Configuration::get('PS_LANG_DEFAULT') => 'mon-produit'];
$product->add(); // L'ID 40 est ignoré, MySQL attribue l'auto-increment

La solution native : le paramètre `force_id`

PrestaShop a prévu ce cas d'usage. La propriété force_id d'ObjectModel, combinée au paramètre $auto_date et $null_values de la méthode add(), permet d'imposer l'identifiant souhaité.


$product = new Product();
$product->force_id = true;  // Clé du mécanisme
$product->id = 40;          // L'ID qui sera réellement utilisé
$product->active = 1;
$product->name = [
    (int)Configuration::get('PS_LANG_DEFAULT') => 'Mon produit'
];
$product->link_rewrite = [
    (int)Configuration::get('PS_LANG_DEFAULT') => 'mon-produit'
];
$product->id_category_default = 2;
$product->id_tax_rules_group = 1;
$product->price = 29.90;

if ($product->add()) {
    // L'ID 40 est bien celui du produit créé
    StockAvailable::setQuantity($product->id, 0, 10);
}

Quand force_id vaut true, ObjectModel inclut la clé primaire dans la requête INSERT. MySQL accepte la valeur à condition qu'elle ne provoque pas de doublon.

Ce qui se passe sous le capot

Dans ObjectModel::add() (fichier classes/ObjectModel.php), le flux est le suivant :

  1. Si `force_id` est `false` (défaut) : la clé primaire est exclue de l'INSERT
  2. Si `force_id` est `true` : la clé primaire est incluse dans les champs insérés
  3. Les tables liées (`_lang`, `_shop`) reçoivent automatiquement le bon ID
  4. C'est précisément le mécanisme utilisé en interne par l'import CSV natif de PrestaShop lorsqu'on coche l'option « Forcer les ID ».

    L'approche SQL directe : pourquoi l'éviter

    Une approche de contournement consiste à créer le produit normalement, puis à modifier son ID via des requêtes SQL brutes :

    
    // ⚠️ Approche fragile — à éviter en production
    $product->add();
    $old_id = $product->id;
    $new_id = 40;
    
    $tables = ['product', 'product_lang', 'product_shop'];
    foreach ($tables as $table) {
        Db::getInstance()->execute(
            'UPDATE `' . _DB_PREFIX_ . $table . '` SET id_product = ' . (int)$new_id .
            ' WHERE id_product = ' . (int)$old_id
        );
    }
    

    Cette méthode pose plusieurs problèmes majeurs :

    Tables oubliées

    Un produit PrestaShop est référencé dans plus de 20 tables. Mettre à jour uniquement product, product_lang et product_shop laisse des orphelins dans :

    • `ps_category_product`
    • `ps_product_attribute`
    • `ps_product_attribute_combination`
    • `ps_stock_available`
    • `ps_specific_price`
    • `ps_image` et `ps_image_shop`
    • `ps_feature_product`
    • `ps_cart_product`
    • `ps_order_detail`
    • `ps_product_carrier`
    • `ps_product_tag`
    • Et bien d'autres selon les modules installés

    Contraintes de clé étrangère

    Sur PrestaShop 8.x avec InnoDB, certaines tables utilisent des contraintes FOREIGN KEY. Modifier un ID sans respecter l'ordre de mise à jour provoque des erreurs d'intégrité référentielle.

    Cache et index de recherche

    L'ancien ID reste potentiellement en cache (Smarty, Redis, module de recherche). Le produit devient introuvable ou pointe vers une fiche fantôme.

    Bonnes pratiques pour les imports avec ID forcé

    1. Vérifier la disponibilité de l'ID

    
    function isProductIdAvailable(int $id_product): bool
    {
        return !(bool)Db::getInstance()->getValue(
            'SELECT COUNT(*) FROM `' . _DB_PREFIX_ . 'product` WHERE id_product = ' . (int)$id_product
        );
    }
    

    2. Gérer l'auto-increment après import

    Après avoir inséré des produits avec des ID imposés, l'auto-increment MySQL peut se retrouver inférieur au plus grand ID inséré. Cela provoquera un conflit lors de la prochaine création sans force_id.

    
    -- Réaligner l'auto-increment après un import forcé
    ALTER TABLE ps_product AUTO_INCREMENT = 1;
    

    MySQL recalculera automatiquement la valeur à MAX(id_product) + 1.

    3. Encapsuler dans une transaction

    Pour un import massif, encapsulez le tout dans une transaction afin de pouvoir annuler proprement en cas d'erreur :

    
    Db::getInstance()->execute('START TRANSACTION');
    
    try {
        foreach ($products_to_import as $data) {
            $product = new Product();
            $product->force_id = true;
            $product->id = (int)$data['id_product'];
            $product->name = $data['name'];
            $product->link_rewrite = $data['link_rewrite'];
            // ... autres champs
    
            if (!$product->add()) {
                throw new PrestaShopException(
                    'Échec création produit ID ' . $data['id_product']
                );
            }
        }
    
        Db::getInstance()->execute('COMMIT');
    } catch (Exception $e) {
        Db::getInstance()->execute('ROLLBACK');
        PrestaShopLogger::addLog($e->getMessage(), 3);
    }
    

    4. Invalider les caches après import

    
    // Vider le cache produit après un import massif
    Cache::clean('Product::*');
    Media::clearCache();
    Tools::generateHtaccess();
    

    Cas d'usage légitimes

    Forcer l'ID produit se justifie dans ces situations :

    • **Migration de boutique** : conserver les ID pour préserver les URLs, les statistiques et les relations commandes/produits
    • **Synchronisation ERP** : aligner les ID PrestaShop sur les codes articles de l'ERP
    • **Environnement de développement** : reproduire un catalogue de production à l'identique pour déboguer
    • **Multi-boutique** : harmoniser les catalogues entre instances

    En dehors de ces cas, laissez PrestaShop gérer ses auto-increments. Forcer des ID sans raison ajoute de la complexité sans bénéfice.

    Évolution selon les versions

    VersionComportement PrestaShop 1.6`force_id` disponible mais peu documenté PrestaShop 1.7Identique, utilisé par l'import CSV natif PrestaShop 8.xToujours supporté, pas de changement de l'API ObjectModel

    Le mécanisme force_id est stable depuis PrestaShop 1.5 et reste la méthode officielle sur toutes les versions actuelles.

#ObjectModel #Product #id_product #SQL #force_id #import #migration

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.