Почему экспортируются значения в csv файл по два раза? PHP

Почему-то при этом скрипте у меня вставляются значения дубликатом. То есть должно быть 6 строчек, а получается 12, так как каждая строка из БД дублируется. В чём проблема может быть?

public function Export(){
        try {
            $fields = $this->db->prepare("SELECT * FROM `product`");
            $fields->execute();
            $file = fopen(__DIR__.'/items.csv', 'w');
            fputs($file, "\xEF\xBB\xBF"); // UTF-8
            foreach($fields as $item){
                fputcsv($file, $item, ';');
            }
            fclose($file);
            echo "Данные заполнены!";
        } catch (\Throwable $th) {
            throw "Данные не заполнены: ".$th->getMessage();
        }
  }

Вот видите повторяется на скрине введите сюда описание изображения


Ответы (2 шт):

Автор решения: SergeyPopov

Причина может быть в том, что вы неправильно используете метод fputcsv, который предназначен для записи одной строки в файл. В вашем случае вы перебираете все строки из БД и записываете каждую из них с помощью fputcsv, что в результате приводит к тому, что каждая строка записывается дважды.

Чтобы решить эту проблему, вам нужно отказаться от использования fputcsv в цикле и использовать функцию fputs или fwrite для записи в файл.

Например, чтобы записать все строки в файл с помощью fputs, вы можете сделать следующее:

$fields = $this->db->prepare("SELECT * FROM `product`");
$fields->execute();
$file = fopen(__DIR__.'/items.csv', 'w');
fputs($file, "\xEF\xBB\xBF"); // UTF-8
while ($item = $fields->fetch(PDO::FETCH_ASSOC)) {
  fputs($file, implode(';', $item) . "\n");
}
fclose($file);

Или с помощью fwrite:

$fields = $this->db->prepare("SELECT * FROM `product`");
$fields->execute();
$file = fopen(__DIR__.'/items.csv', 'w');
fwrite($file, "\xEF\xBB\
→ Ссылка
Автор решения: u_mulder

По умолчанию pdo возвращает каждую строку таблицы как массив и с числовыми и со строковыми ключами, это режим PDO::FETCH_BOTH.

Чтобы возвращались только ключи строковые - надо выставить fetchMode в PDO::FETCH_ASSOC. Выглядеть это будет так:

$fields = $this->db->prepare("SELECT * FROM `product`");
$fields->setFetchMode(PDO::FETCH_ASSOC);
$fields->execute();
// ...
→ Ссылка