Importer 10 000 produits via CLI sans tomber en timeout
L'import standard PrestaShop est OK pour 500 lignes mais devient catastrophique au-delà. Un script CLI léger qui contourne timeout, mémoire, et locks DB.
L'import via le BO PrestaShop tient pour 500-1000 lignes. Au-delà, vous tapez le timeout PHP, la mémoire saute, ou la session expire. Voici le pattern qu'on utilise pour des imports 10k+ via CLI.
Le script de base
#!/usr/bin/env php
<?php
// import-products.php — à placer à la racine PS
require_once __DIR__ . '/config/config.inc.php';
if (php_sapi_name() !== 'cli') exit('CLI only');
ini_set('memory_limit', '512M');
set_time_limit(0);
$csv = fopen(__DIR__ . '/imports/products.csv', 'r');
fgetcsv($csv); // header
$batch = 0;
$batchSize = 100;
while (($row = fgetcsv($csv)) !== false) {
[$reference, $name, $price, $qty, $idCategory] = $row;
$product = new Product();
$product->reference = $reference;
$product->name = [Configuration::get('PS_LANG_DEFAULT') => $name];
$product->link_rewrite = [Configuration::get('PS_LANG_DEFAULT') => Tools::str2url($name)];
$product->price = (float) $price;
$product->id_category_default = (int) $idCategory;
$product->active = 1;
if ($product->add()) {
$product->addToCategories([(int) $idCategory]);
StockAvailable::setQuantity($product->id, 0, (int) $qty);
echo "OK $reference\n";
} else {
echo "ERR $reference\n";
}
if (++$batch % $batchSize === 0) {
// Libérer la mémoire ORM
gc_collect_cycles();
echo " Batch $batch flushé\n";
}
}
fclose($csv);
echo "Total: $batch\n";
Les optimisations qui changent tout
- Désactiver les hooks avant l'import :
Hook::exec(...)peut déclencher des envois mail, des syncs ERP, etc. Désactivez les modules non-essentiels en début de script et réactivez-les à la fin. - Indexes différés :
Search::indexation(false, $product->id)est lourd. Faites un seulSearch::indexation(true)à la fin (rebuild complet plus rapide qu'1 par produit). - Image generation différée : si vous importez aussi des images, queuez-les dans une table
app_image_queueet traitez via cron séparé.
Lancer en production
# Via screen/tmux pour ne pas perdre la session
screen -S import
php import-products.php | tee import-$(date +%F).log
# Ctrl+A puis D pour détacher
Pour 10 000 produits "simples" (sans images, sans variantes), comptez ~8-15 minutes selon la machine. Avec images : 1-2h.