PDO::bindValue() требует индекс ≥ 1, а $params был 0-индексированным
массивом с PostgreSQL-нативными $1,$2,$3 плейсхолдерами. Это вызывало:
PDOStatement::bindValue(): Argument #1 ($param) must be >= 1
Результат на проде: Balances::deleteAll() удалял данные магазина,
BatchSyncService->upsertBalances() падал → магазин терял ВСЕ строки.
Fix: именованные :p1,:p2,:p3 плейсхолдеры вместо $1,$2,$3.
Проверено на реальной БД: 5 магазинов (419-499 товаров) + characteristics.
return 0;
}
- // Подготовка плейсхолдеров для VALUES
+ // Подготовка плейсхолдеров для VALUES (именованные :pN для Yii2/PDO)
$placeholders = [];
$params = [];
$paramIndex = 1;
foreach ($rows as $row) {
$rowPlaceholders = [];
foreach ($columns as $column) {
- $rowPlaceholders[] = '$' . $paramIndex;
- $params[] = $row[$column] ?? null;
+ $paramName = ':p' . $paramIndex;
+ $rowPlaceholders[] = $paramName;
+ $params[$paramName] = $row[$column] ?? null;
$paramIndex++;
}
$placeholders[] = '(' . implode(',', $rowPlaceholders) . ')';