Доброго времени суток! Подскажите пожалуйста, как реализовать выгрузку данных из таблицы MySQL в текстовый файл без сохранения его на сервере. Суть такая: нужно сделать нечто подобное ф-ции Import в PhpMyAdmin. Там формируется текстовый файл с запросом и отдается для скачивания пользователю. Как я понял, сам скачиваемый файл при этом на сервере не сохраняется. Как это сделать? Ну может в PHP есть что-то типа потока. Самое главное как отдать файл из памяти, а то все примеры для скачивания файла с диска. Спасибо.
После формирования переменной с данными, отдавай её пользователю как здесь: viewtopic.php?f=13&t=9221
Спасибо, но у меня почти мегабайт текста, как я его в переменную засуну? Я в PHP новичок, но обычно в языках программирования используются потоки. Может тут есть какой-нибудь аналог?
да запросто. Но раз на то пошло, ты можешь отправить заголовки из примера, а дальше делать echo хоть по одному символу.
Понял, т.е. там, где в примере echo $string у меня будет цикл вывода строк из массива + <br>. Правильно? А вот это: Код (Text): Header('Content-Length: '.strlen($string)); обязательно? А не хочется сервер заставлять сначала все длины строк пересчитывать.
нет, не обязательно. Но так больше риска, что загрузка закончится преждевременно, если возникнут проблемы с сетью.
Спасибо большое, сейчас попробую, оказывается ничего сложного Добавлено спустя 9 минут 27 секунд: Ну ещё маленький вопрос. Когда буду подсчитывать длину файла переводы строк считаются? Если да, то как? В смысле 2 байта или 1? Кодировка на сервере koi-8, т.е. юникод.
Столкнулся с новой проблемой. Написал функцию для формирования текстового файла. В коде пока закоментировал код загрузки файла. В таблице 9016 записей, а этот код выводит только 6658. В чем может быть проблема? Может где-то ограничения какие-то есть? Например в MySQL, или массив не может больше вместить? Код (PHP): function DownloadFl($inp) { $sql = "SELECT `ID`,`Long`,`Lat`,`CamType`,`Speed`,`Direct`,`Azimut`,`CamName` FROM Radars WHERE 1"; $result = mysql_query($sql); $i=0; $cntbytes = 0; while ($row = mysql_fetch_assoc($result)) { $arr[] = $row['ID'].','.$row['Long'].','.$row['Lat'].','.$row['CamType'].','.$row['Speed'].','.$row['Direct'].','.$row['Azimut'].','.$row['CamName']; $cntbytes += strlen($arr[i]); $i += 1; }; /* if(isset($_SERVER['HTTP_USER_AGENT']) and strpos($_SERVER['HTTP_USER_AGENT'],'MSIE')) Header('Content-Type: application/force-download'); else Header('Content-Type: application/octet-stream'); Header('Accept-Ranges: bytes'); Header('Content-Length: '.cntbytes); Header('Content-disposition: attachment; filename="SpeedCam22.txt"'); */ for($n=0;$n < $i;$n++) { echo $arr[$n].'<br>'; }; return 1; };
Код (PHP): $arr[] = $row['ID'].','.$row['Long'].','.$row['Lat'].','.$row['CamType'].','.$row['Speed'].','.$row['Direct'].','.$row['Azimut'].','.$row['CamName']; implode(',',$row); на вид должно работать как ожидается. Если ты считаешь записи по последнему ID, то имей в виду, что где-то в середине таблице может тупо не хватать 3к строк, а айдишники от этого не меняются и только увеличиваются.
Спасибо! Нет, в таблице всё по порядку, в ней именно 9016 записей, ну и максимальный ID такой же, но он по понятным причинам может и отличаться. За implode - отдельное спасибо, сейчас переделаю. А вопрос снимается, тестировал на WAMP (локальный), Перенес на сервер - всё нормально стало выводится. Но... опять проблемы. Никак я не могу победить этот download. 1. Код приведенной функции у меня в отдельном файле download.php. На странице, откуда происходит загрузка такой код: Код (Text): <?php if (isset($_POST['download'])&&!empty($_POST['download'])) { include("download.php"); DownloadFl(); echo "<script> showDlg('none');</script>"; header("Location: Adm.php"); }; ?> Это форма (модальное окно), а страница, на которой она расположена - Adm.php. У меня всё на них сделано. Последняя строка закрывает модальное окно. Файл формируется и скачивается, а модальное окно не закрывается. Если ф-цию DownloadFl убрать - всё происходит корректно. 2. В начале скачанного файла кроме нужных мне данных ещё кусок html кода, который находится до вызова функции DownloadFl. Как его убрать? 3. У меня не получается сформировать построчный вывод в файл. В приведенной в первом посте ф-ции я использовал <br>. Но это только для теста, чтобы браузер выводил корректно. А как вставить переводы строк в формируемый файл?
Хорошо, это, я понимаю, по п.1? Буду разбираться, здесь вряд ли кто подскажет без всего кода. А по п.2 и п.3? Тут я даже не знаю куда копать...
п.2 Убрать из программы вывод этого лишнего html кода, например выводить его только когда ты не отдаёшь файл на загрузку п.3 PHP_EOL https://secure.php.net/manual/ru/reserved.constants.php
Спасибо. Но у меня никакой html код не выводится, может я чего-то не понимаю. В функции формирования файла на отдачу я использую exit(). Если его убрать, то в файл на отдачу включается и код страницы, который следует за вызовом функции. Но от кода, который перед вызовом я не могу избавиться. По п.3. - PHP_EOL не помогает, вчера пробовал. Вот так: Код (Text): echo $arr[$n].PHP_EOL; Всё равно все строки выводятся подряд, без переносов.
п.1 вынеси тогда код формирования и отдачи файла в отдельный файл и перенаправляй на него, тут логика, если код попадает в файл, значит ты его туда добавил, ответ: не добавляй. п.2 а как ты проверил что переносов нет?
не выводить ничего в браузер в случае, если ты файл отдаёшь. Это же очевидно. Добавлено спустя 26 секунд: "\n"
п.1. Это сделано. Функция в отдельном файле php. Как я его мог добавить? Код приведен здесь (выше). Я где-то здесь на форуме видел сообщение с подобной проблемой, но теперь найти не могу. п.2. Ну просто запустил проект и скачал файл. Он скачался, но все строки идут подряд. Формируется что-то типа бинарника. Т.е. непрерывный текст. Ну Вам может и очевидно а как это сделать? Добавлено спустя 26 секунд: "\n"[/quote] Не работает выводит в файл строки непрерывно, у каждой строки символ "\n" явно прописан в конце.
Ну снизойдите до моего уровня Так: Код (PHP): function DownloadFl() { $sql = "SELECT `ID`,`Long`,`Lat`,`CamType`,`Speed`,`Direct`,`Azimut`,`CamName` FROM Radars WHERE 1 LIMIT 100000 OFFSET 0"; $result = mysql_query($sql); $i=0; $cntbytes = 0; while ($row = mysql_fetch_assoc($result)) { $arr[] = implode(',',$row); $cntbytes += strlen($arr[i]); $i += 1; }; if(isset($_SERVER['HTTP_USER_AGENT']) and strpos($_SERVER['HTTP_USER_AGENT'],'MSIE')) Header('Content-Type: application/force-download'); else Header('Content-Type: application/octet-stream'); Header('Accept-Ranges: bytes'); Header('Content-Length: '.cntbytes); Header('Content-disposition: attachment; filename="SpeedCam22.txt"'); file_put_contents('SpeedCam22.txt', implode("\n", $arr)); //for($n=0;$n < $i;$n++) //{ // echo $arr[$n].PHP_EOL; //}; exit(); //return 1; }; Так ничего не выводит, загружается пустой файл.
а, ну ты его ж не отдаёшь, а сохраняешь этой функцией. замени file_put_contents('SpeedCam22.txt', implode("\n", $arr)); на echo implode("\n", $arr);