За последние 24 часа нас посетили 31754 программиста и 1359 роботов. Сейчас ищут 894 программиста ...

Выгрузка данных из БД

Тема в разделе "PHP для новичков", создана пользователем Alex870, 31 авг 2015.

  1. Alex870

    Alex870 Новичок

    С нами с:
    8 дек 2013
    Сообщения:
    121
    Симпатии:
    2
    Доброго времени суток!
    Подскажите пожалуйста, как реализовать выгрузку данных из таблицы MySQL в текстовый файл без сохранения его на сервере.
    Суть такая: нужно сделать нечто подобное ф-ции Import в PhpMyAdmin. Там формируется текстовый файл с запросом и отдается для скачивания пользователю. Как я понял, сам скачиваемый файл при этом на сервере не сохраняется. Как это сделать? Ну может в PHP есть что-то типа потока. Самое главное как отдать файл из памяти, а то все примеры для скачивания файла с диска.
    Спасибо.
     
  2. [vs]

    [vs] Суперстар
    Команда форума Модератор

    С нами с:
    27 сен 2007
    Сообщения:
    10.559
    Симпатии:
    632
    После формирования переменной с данными, отдавай её пользователю как здесь: viewtopic.php?f=13&t=9221
     
  3. Alex870

    Alex870 Новичок

    С нами с:
    8 дек 2013
    Сообщения:
    121
    Симпатии:
    2
    Спасибо, но у меня почти мегабайт текста, как я его в переменную засуну? Я в PHP новичок, но обычно в языках программирования используются потоки. Может тут есть какой-нибудь аналог?
     
  4. [vs]

    [vs] Суперстар
    Команда форума Модератор

    С нами с:
    27 сен 2007
    Сообщения:
    10.559
    Симпатии:
    632
    да запросто. Но раз на то пошло, ты можешь отправить заголовки из примера, а дальше делать echo хоть по одному символу.
     
  5. Alex870

    Alex870 Новичок

    С нами с:
    8 дек 2013
    Сообщения:
    121
    Симпатии:
    2
    Понял, т.е. там, где в примере echo $string у меня будет цикл вывода строк из массива + <br>. Правильно?
    А вот это:
    Код (Text):
    1. Header('Content-Length: '.strlen($string));
    обязательно? А не хочется сервер заставлять сначала все длины строк пересчитывать.
     
  6. [vs]

    [vs] Суперстар
    Команда форума Модератор

    С нами с:
    27 сен 2007
    Сообщения:
    10.559
    Симпатии:
    632
    нет, не обязательно. Но так больше риска, что загрузка закончится преждевременно, если возникнут проблемы с сетью.
     
  7. Alex870

    Alex870 Новичок

    С нами с:
    8 дек 2013
    Сообщения:
    121
    Симпатии:
    2
    Спасибо большое, сейчас попробую, оказывается ничего сложного :)

    Добавлено спустя 9 минут 27 секунд:
    Ну ещё маленький вопрос.
    Когда буду подсчитывать длину файла переводы строк считаются? Если да, то как? В смысле 2 байта или 1? Кодировка на сервере koi-8, т.е. юникод.
     
  8. [vs]

    [vs] Суперстар
    Команда форума Модератор

    С нами с:
    27 сен 2007
    Сообщения:
    10.559
    Симпатии:
    632
    Пожалуйста) Функция strlen (не mb_strlen) считает байты в любой строке.
     
  9. Alex870

    Alex870 Новичок

    С нами с:
    8 дек 2013
    Сообщения:
    121
    Симпатии:
    2
    Столкнулся с новой проблемой.
    Написал функцию для формирования текстового файла. В коде пока закоментировал код загрузки файла.

    В таблице 9016 записей, а этот код выводит только 6658. В чем может быть проблема? Может где-то ограничения какие-то есть? Например в MySQL, или массив не может больше вместить?

    Код (PHP):
    1. function DownloadFl($inp)
    2. {
    3.  $sql = "SELECT `ID`,`Long`,`Lat`,`CamType`,`Speed`,`Direct`,`Azimut`,`CamName` FROM Radars WHERE 1";
    4.                       $result = mysql_query($sql);
    5.                       $i=0;
    6.                       $cntbytes = 0;
    7.                       while ($row = mysql_fetch_assoc($result))
    8.                       {
    9.                           $arr[] = $row['ID'].','.$row['Long'].','.$row['Lat'].','.$row['CamType'].','.$row['Speed'].','.$row['Direct'].','.$row['Azimut'].','.$row['CamName'];
    10.                           $cntbytes += strlen($arr[i]);
    11.                           $i += 1;
    12.                       };
    13.                       
    14.                       /*
    15.                       if(isset($_SERVER['HTTP_USER_AGENT']) and strpos($_SERVER['HTTP_USER_AGENT'],'MSIE')) 
    16.                         Header('Content-Type: application/force-download'); 
    17.                          else 
    18.                          Header('Content-Type: application/octet-stream'); 
    19.  
    20.                         Header('Accept-Ranges: bytes'); 
    21.                         Header('Content-Length: '.cntbytes); 
    22.                         Header('Content-disposition: attachment; filename="SpeedCam22.txt"'); 
    23.                         */
    24.                         for($n=0;$n < $i;$n++)
    25.                         {
    26.                             
    27.                           echo $arr[$n].'<br>';
    28.                         };
    29.                         
    30.                         return 1;
    31. }; 
     
  10. igordata

    igordata Суперстар
    Команда форума Модератор

    С нами с:
    18 мар 2010
    Сообщения:
    32.408
    Симпатии:
    1.768
    Код (PHP):
    1. $arr[] = $row['ID'].','.$row['Long'].','.$row['Lat'].','.$row['CamType'].','.$row['Speed'].','.$row['Direct'].','.$row['Azimut'].','.$row['CamName']; 
    implode(',',$row);


    на вид должно работать как ожидается. Если ты считаешь записи по последнему ID, то имей в виду, что где-то в середине таблице может тупо не хватать 3к строк, а айдишники от этого не меняются и только увеличиваются.
     
  11. Alex870

    Alex870 Новичок

    С нами с:
    8 дек 2013
    Сообщения:
    121
    Симпатии:
    2
    Спасибо!
    Нет, в таблице всё по порядку, в ней именно 9016 записей, ну и максимальный ID такой же, но он по понятным причинам может и отличаться.
    За implode - отдельное спасибо, сейчас переделаю.
    А вопрос снимается, тестировал на WAMP (локальный), Перенес на сервер - всё нормально стало выводится.
    Но... опять проблемы. Никак я не могу победить этот download.
    1. Код приведенной функции у меня в отдельном файле download.php. На странице, откуда происходит загрузка такой код:
    Код (Text):
    1. <?php
    2.                     if (isset($_POST['download'])&&!empty($_POST['download']))
    3.                     {
    4.                      
    5.                      include("download.php");
    6.                      DownloadFl();
    7.                      echo "<script> showDlg('none');</script>";
    8.                      header("Location: Adm.php");
    9.                     };
    10.                      
    11.                     ?>
    Это форма (модальное окно), а страница, на которой она расположена - Adm.php. У меня всё на них сделано. Последняя строка закрывает модальное окно.
    Файл формируется и скачивается, а модальное окно не закрывается. Если ф-цию DownloadFl убрать - всё происходит корректно.
    2. В начале скачанного файла кроме нужных мне данных ещё кусок html кода, который находится до вызова функции DownloadFl. Как его убрать?
    3. У меня не получается сформировать построчный вывод в файл. В приведенной в первом посте ф-ции я использовал <br>. Но это только для теста, чтобы браузер выводил корректно. А как вставить переводы строк в формируемый файл?
     
  12. igordata

    igordata Суперстар
    Команда форума Модератор

    С нами с:
    18 мар 2010
    Сообщения:
    32.408
    Симпатии:
    1.768
    смотри исходный код страницы
     
  13. Alex870

    Alex870 Новичок

    С нами с:
    8 дек 2013
    Сообщения:
    121
    Симпатии:
    2
    Извиняюсь, не понял.
     
  14. igordata

    igordata Суперстар
    Команда форума Модератор

    С нами с:
    18 мар 2010
    Сообщения:
    32.408
    Симпатии:
    1.768
    у тебя не пашет js
    смотри в браузере что тебе отдалось
     
  15. Alex870

    Alex870 Новичок

    С нами с:
    8 дек 2013
    Сообщения:
    121
    Симпатии:
    2
    Хорошо, это, я понимаю, по п.1? Буду разбираться, здесь вряд ли кто подскажет без всего кода.
    А по п.2 и п.3? Тут я даже не знаю куда копать...
     
  16. denis01

    denis01 Суперстар
    Команда форума Модератор

    С нами с:
    9 дек 2014
    Сообщения:
    12.227
    Симпатии:
    1.714
    Адрес:
    Молдова, г.Кишинёв
    п.2 Убрать из программы вывод этого лишнего html кода, например выводить его только когда ты не отдаёшь файл на загрузку
    п.3 PHP_EOL https://secure.php.net/manual/ru/reserved.constants.php
     
  17. Alex870

    Alex870 Новичок

    С нами с:
    8 дек 2013
    Сообщения:
    121
    Симпатии:
    2
    Спасибо. Но у меня никакой html код не выводится, может я чего-то не понимаю. В функции формирования файла на отдачу я использую exit(). Если его убрать, то в файл на отдачу включается и код страницы, который следует за вызовом функции. Но от кода, который перед вызовом я не могу избавиться.
    По п.3. - PHP_EOL не помогает, вчера пробовал. Вот так:
    Код (Text):
    1. echo $arr[$n].PHP_EOL;
    Всё равно все строки выводятся подряд, без переносов.
     
  18. denis01

    denis01 Суперстар
    Команда форума Модератор

    С нами с:
    9 дек 2014
    Сообщения:
    12.227
    Симпатии:
    1.714
    Адрес:
    Молдова, г.Кишинёв
    п.1 вынеси тогда код формирования и отдачи файла в отдельный файл и перенаправляй на него, тут логика, если код попадает в файл, значит ты его туда добавил, ответ: не добавляй.

    п.2 а как ты проверил что переносов нет?
     
  19. igordata

    igordata Суперстар
    Команда форума Модератор

    С нами с:
    18 мар 2010
    Сообщения:
    32.408
    Симпатии:
    1.768
    не выводить ничего в браузер в случае, если ты файл отдаёшь. Это же очевидно.

    Добавлено спустя 26 секунд:
    "\n"
     
  20. Alex870

    Alex870 Новичок

    С нами с:
    8 дек 2013
    Сообщения:
    121
    Симпатии:
    2
    п.1. Это сделано. Функция в отдельном файле php. Как я его мог добавить? Код приведен здесь (выше). Я где-то здесь на форуме видел сообщение с подобной проблемой, но теперь найти не могу.
    п.2. Ну просто запустил проект и скачал файл. Он скачался, но все строки идут подряд. Формируется что-то типа бинарника. Т.е. непрерывный текст.
    Ну Вам может и очевидно :) а как это сделать?

    Добавлено спустя 26 секунд:
    "\n"[/quote]

    Не работает выводит в файл строки непрерывно, у каждой строки символ "\n" явно прописан в конце.
     
  21. igordata

    igordata Суперстар
    Команда форума Модератор

    С нами с:
    18 мар 2010
    Сообщения:
    32.408
    Симпатии:
    1.768
    в двойных кавычках
     
  22. Alex870

    Alex870 Новичок

    С нами с:
    8 дек 2013
    Сообщения:
    121
    Симпатии:
    2
    Т.е. так: echo $arr[$n]."\n";
     
  23. igordata

    igordata Суперстар
    Команда форума Модератор

    С нами с:
    18 мар 2010
    Сообщения:
    32.408
    Симпатии:
    1.768
    угу

    Добавлено спустя 48 секунд:
    file_put_contents('file.txt', implode("\n", $arr));
     
  24. Alex870

    Alex870 Новичок

    С нами с:
    8 дек 2013
    Сообщения:
    121
    Симпатии:
    2
    Ну снизойдите до моего уровня :)
    Так:
    Код (PHP):
    1. function DownloadFl()
    2. {
    3.  $sql = "SELECT `ID`,`Long`,`Lat`,`CamType`,`Speed`,`Direct`,`Azimut`,`CamName` FROM Radars WHERE 1 LIMIT 100000 OFFSET 0";
    4.                       $result = mysql_query($sql);
    5.                       $i=0;
    6.                       $cntbytes = 0;
    7.                       while ($row = mysql_fetch_assoc($result))
    8.                       {
    9.                           $arr[] = implode(',',$row);
    10.                           $cntbytes += strlen($arr[i]);
    11.                           $i += 1;
    12.                       };
    13.                       
    14.                       
    15.                       if(isset($_SERVER['HTTP_USER_AGENT']) and strpos($_SERVER['HTTP_USER_AGENT'],'MSIE')) 
    16.                         Header('Content-Type: application/force-download'); 
    17.                          else 
    18.                          Header('Content-Type: application/octet-stream'); 
    19.  
    20.                         Header('Accept-Ranges: bytes'); 
    21.                         Header('Content-Length: '.cntbytes); 
    22.                         Header('Content-disposition: attachment; filename="SpeedCam22.txt"'); 
    23.                         file_put_contents('SpeedCam22.txt', implode("\n", $arr));
    24.                         //for($n=0;$n < $i;$n++)
    25.                         //{
    26.                             
    27.                         //  echo $arr[$n].PHP_EOL;
    28.                         //};
    29.                         exit();
    30.                         //return 1;
    31. }; 
    Так ничего не выводит, загружается пустой файл.
     
  25. igordata

    igordata Суперстар
    Команда форума Модератор

    С нами с:
    18 мар 2010
    Сообщения:
    32.408
    Симпатии:
    1.768
    а, ну ты его ж не отдаёшь, а сохраняешь этой функцией.

    замени
    file_put_contents('SpeedCam22.txt', implode("\n", $arr));
    на
    echo implode("\n", $arr);