Вопрос или проблема
Я пытаюсь экспортировать результаты в файл csv, используя следующий код. Экспорт, кажется, работает, но когда я открываю файл, он содержит HTML-код страницы. Буду признателен за любую помощь.
ob_start();
global $wpdb;
$domain = $_SERVER['SERVER_NAME'];
$table = $wpdb->prefix . "qi_project_requests";
$filename = "export.csv";
$sql = $wpdb->get_results("select * from $table");
$header_row = array(
'Дата отправки',
'Имя запрашивающего'
);
$data_rows = array();
foreach ($sql as $data) {
$row = array(
$data->date,
$data->rname
);
$data_rows[] = $row;
}
$fh = @fopen( 'php://output', 'w' );
fprintf( $fh, chr(0xEF) . chr(0xBB) . chr(0xBF) );
header( 'Cache-Control: must-revalidate, post-check=0, pre-check=0' );
header( 'Content-Description: File Transfer' );
header( 'Content-type: text/csv' );
header( "Content-Disposition: attachment; filename=$filename" );
header( 'Expires: 0' );
header( 'Pragma: public' );
fputcsv( $fh, $header_row );
foreach ( $data_rows as $data_row ) {
fputcsv( $fh, $data_row );
}
fclose( $fh );
ob_end_flush();
die();
У меня есть похожий процесс, чтобы вывести все адреса электронной почты из базы данных в downloadable txt файл. Это выглядит так:
$xoutput = show_subscriber_list();
$xfile = fopen('xsubscriber.txt' , "w") or die("Невозможно открыть файл!");;
fwrite($xfile,$xoutput);
fclose($xfile);
$filename="xsubscriber.txt"; // конечно, найдите точное имя файла....
header('Pragma: public');
header('Expires: 0');
header('Cache-Control: must-revalidate, post-check=0, pre-check=0');
header('Cache-Control: private', false); // требуется для некоторых браузеров
header('Content-Type: application/pdf');
header('Content-Disposition: attachment; filename="'. basename($filename) . '";');
header('Content-Transfer-Encoding: binary');
header('Content-Length: ' . filesize($filename));
readfile($filename);
exit;
Функция show_subscriber_list
выполняет SQL-запрос данных, получая все данные в цикле по строкам, возвращаемым запросом. Эта функция возвращает эти данные в виде строки, которая используется в качестве содержимого $filename
(как в return $text_data;
).
$filename
хранится в текущей папке. Затем это $filename
используется в заголовках, что позволяет получить файл в виде диалога загрузки/открытия.
Важно ‘построить’ содержимое файла перед тем, как вы сделаете заголовки. Вы могли бы так же легко ‘построить’ данные в строку, а затем сделать заголовки.
Добавлено
Вот функция, которая возвращает содержимое базы данных в виде текста. Вызывается с
$data = mysqli_query($conn, $sql);
$output = display_data($data); // текстовый вывод, используемый в вышеуказанной функции
function display_data($data) {
$output = "";
foreach($data as $row) {
$output .= $row["email"] . PHP_EOL ;
}
return $output;
}
И обратите внимание, как упоминалось в комментарии от OP, что вам нужно установить правильный Content-Type, необходимый для содержимого вашего файла; у меня он установлен как PDF.
Проблема в том, что вы используете функции ob_start() и ob_end_flush(), которые используются для буферизации вывода вашего скрипта. Эти функции следует удалить из вашего кода, поскольку они могут вызывать включение HTML-кода страницы в экспортируемый CSV-файл.
Ответ или решение
Исходя из вашего вопроса, вы пытаетесь экспортировать данные из базы данных в файл CSV, однако сталкиваетесь с тем, что в результирующем файле появляется HTML-код. Данная проблема чаще всего возникает из-за неправильно настроенной обработки вывода. В этой статье мы рассмотрим, как правильно организовать экспорт данных без HTML-кода, а также приведем исправленный пример вашего кода.
-
Проблема с буферизацией вывода: Использование функций
ob_start()
иob_end_flush()
может привести к тому, что буферизованный вывод (включая HTML-код) будет включаться в ваш CSV-файл. Рекомендуется избегать этих функций в вашем случае. -
Правильная настройка заголовков: Убедитесь, что заголовки HTTP установлены корректно перед отправкой содержимого CSV-файла. Это включает в себя установку типа содержимого и имени файла.
Вот исправленный код для вашего экспорта данных:
// Не используем буферизацию вывода
global $wpdb;
// Настройка базы данных и переменных
$domain = $_SERVER['SERVER_NAME'];
$table = $wpdb->prefix . "qi_project_requests";
$filename = "export.csv";
// Получение данных из базы
$sql = $wpdb->get_results("SELECT * FROM $table");
// Заголовки колонок для CSV
$header_row = array(
'Date Submitted',
'Requestor Name'
);
// Массив данных
$data_rows = array();
foreach ($sql as $data) {
$row = array(
$data->date,
$data->rname
);
$data_rows[] = $row;
}
// Настройка заголовков для скачивания файла
header('Content-Type: text/csv; charset=utf-8');
header("Content-Disposition: attachment; filename=\"$filename\"");
header('Pragma: no-cache');
header('Expires: 0');
// Открытие потока для записи CSV
$output = fopen('php://output', 'w');
// Запись заголовка
fputcsv($output, $header_row);
// Запись данных
foreach ($data_rows as $data_row) {
fputcsv($output, $data_row);
}
// Закрытие потока
fclose($output);
// Завершение скрипта
exit();
Объяснение изменений:
- Удалены функции буферизации вывода: Устранение
ob_start()
иob_end_flush()
предотвратит вывод ненужного HTML. - Настройка заголовков для скачивания: Устанавливаются необходимые заголовки, чтобы браузер мог правильно интерпретировать файл как CSV.
- Использование
php://output
: Это стандартный способ вывода данных, который подходит для этой задачи.
Следуя приведенным рекомендациям, вы получите корректно формируемый CSV-файл, содержащий только нужные данные, без нежелательного HTML-кода. Это обеспечит удобство пользователей и решит проблему с экспортом данных.
В случае дополнительных вопросов или необходимости внесения изменений в логику (например, добавление дополнительных полей), не стесняйтесь задавать их.