За последние 24 часа нас посетили 54207 программистов и 1724 робота. Сейчас ищут 815 программистов ...

загрузка файла через форму и сохранение в .ZIP

Тема в разделе "Прочие вопросы по PHP", создана пользователем Sleven, 24 мар 2007.

  1. Sleven

    Sleven Активный пользователь

    С нами с:
    18 июл 2006
    Сообщения:
    99
    Симпатии:
    0
    Адрес:
    Сургут
    Воспользовался классом zip.lib.php. Пользователь выбирает файл прайса со своего компа, отсылает на сервак, сервак получает файл, пакует его в ЗИП и сохраняет в специальной папке. Вот код:
    Код (Text):
    1. if(isset($price)) {
    2.  include_once("zip.php");
    3.  include_once("translit.php");
    4.  $zip=new zipfile();
    5.  $Price_file="price/";
    6.  $Price_file.=translit(basename($price));
    7.  if(copy($price, $Price_file)) {
    8.   $fp=fopen($Price_file,"rb");
    9.   $zip->addFile(fread($fp,filesize($Price_file)),$Price_file,time());
    10.   fclose($fp);
    11.   $price_href="price/".$_SESSION["id"]."-price".date("d.m.y").".zip";
    12.   $f=fopen("price/".$_SESSION["id"]."-price".date("d.m.y").".zip","w");
    13.   fwrite($f,$zip->file());
    14.   fclose($f);
    15.   unlink($Price_file);
    16.   $price_exists=true;
    17.  }
    18. }
    код у меня то работает (появляется нужный арххив с файлом), то нет (файл передается скрипту но при fwrite($f,$zip->file()); файл не создается, зато при echo($zip->file()) выдает в окно зип нормально (что мне не нужно). Испытваю на денвере.
    Кстати, у меня на денвере при указании в теге form атрибута enctype="multipart/form-data почему-то файлы не передаются скрипту, поэтому на локальной версии приходится отказываться от массива $_FILES и функций move_uploaded_file(), is_uploaded_file()
     
  2. Dagdamor

    Dagdamor Активный пользователь

    С нами с:
    4 фев 2006
    Сообщения:
    2.095
    Симпатии:
    1
    Адрес:
    Барнаул
    Sleven
    PHP:
    1. $f=fopen("price/".$_SESSION["id"]."-price".date("d.m.y").".zip","w");
    Убедись, что у тебя здесь генерируется корректное имя файла (и что папка существует, и все права есть), кроме того, для Windows нужно использовать режим записи "wb".

    *моргает* В смысле, а без атрибута enctype все работает?
     
  3. Sleven

    Sleven Активный пользователь

    С нами с:
    18 июл 2006
    Сообщения:
    99
    Симпатии:
    0
    Адрес:
    Сургут
    да, без атрибута enctype файлы нормально передаются, но доступны только из простых переменных, т.е. не достать их через $_FILES.
     
  4. Sleven

    Sleven Активный пользователь

    С нами с:
    18 июл 2006
    Сообщения:
    99
    Симпатии:
    0
    Адрес:
    Сургут
    папка существует, ОС - Windows, поставил wb, имя генерируется корректное (проверил)... не пашет...
    самое интерсное, что даже открыв файл:
    $f=fopen("price/".$_SESSION["id"]."-price".date("d.m.y").".zip","w");
    то даже если я добавляю строчку после этого наподобие такой:
    fwrite($f,"11111111111");
    - все равно файл не создается.
     
  5. Sleven

    Sleven Активный пользователь

    С нами с:
    18 июл 2006
    Сообщения:
    99
    Симпатии:
    0
    Адрес:
    Сургут
    уточню - копирование файла
    copy($price, $Price_file)
    срабатывает и этот самый файл появляется. А вот в архив не хочет
     
  6. Dagdamor

    Dagdamor Активный пользователь

    С нами с:
    4 фев 2006
    Сообщения:
    2.095
    Симпатии:
    1
    Адрес:
    Барнаул
    Sleven
    Что-то я все больше и больше начинаюсь склоняться к мысли, что Денвер - зло ;)
    Принимать файлы, отправленные на сервер "не по стандарту" неправильно, даже если у тебя это работает. Проверь значения настроек PHP upload_tmp_dir, upload_max_filesize и post_max_size. Попробуй закачивать файлы другим браузером. Поставь другую версию Денвера, если все так печально.
     
  7. Anonymous

    Anonymous Guest

    Dagdamor, в очередной раз не могу понять — откуда люди берут такие проблемы? У меню все работает...

    А ты fclose($f); точно делаешь??
     
  8. Sleven

    Sleven Активный пользователь

    С нами с:
    18 июл 2006
    Сообщения:
    99
    Симпатии:
    0
    Адрес:
    Сургут
    Форма:
    Код (Text):
    1.  
    2. ...
    3. <form action="edit_salon.php" method="POST">
    4. <input type="file" name="price">
    5. <input type="submit" value="Отправить"></form>
    6. ...
    edit_salon.php:
    Код (Text):
    1.  
    2. ...
    3. if(isset($price)) {  
    4.  include_once("zip.php");
    5.  include_once("translit.php"); // простейшая функция транслитерации, написанная мною
    6.  $zip=new zipfile();
    7.  $Price_file="price/"; // задаем папку, где хранятся все прайсы
    8.  $Price_file.=translit(basename($price)); // дополняем оттранслитерованным названием файла
    9.  if(copy($price, $Price_file)) {  // копируем в папку "price" полученный файл
    10.   $fp=fopen($Price_file,"rb"); // полученный файл открываем для чтения
    11.   $zip->addFile(fread($fp,filesize($Price_file)),$Price_file,time());  // считываем полученный файл и добавляем в $zip
    12.   fclose($fp);
    13.   $price_href="price/".$_SESSION["id"]."-price".date("d.m.y").".zip"; // папка и название нового файла-архива
    14.   $f=fopen($price_href,"wb");  // создаем новый файл-архив
    15.   fwrite($f,$zip->file()); // и записываем в него все сжатые даные
    16.   fclose($f);
    17.   unlink($Price_file);  // удаляем полученный ранее и скопированный файл, т.к. он больше не нужен (его копия добавлена в созданный архив)
    18.  }
    19. }
    20. ...
    результат выполнения - никакого архива и в помине. Проверял получен ли файл и существует ли - да, есть, названия файлов - тоже правильно. Теперь если вместо:
    Код (Text):
    1.  
    2. fwrite($f,$zip->file());
    поставить:
    Код (Text):
    1.  
    2. fwrite($f,"1111");
    - все равно никакого файла. Если же вместо:
    Код (Text):
    1.  
    2. $f=fopen($price_href,"wb");
    3. fwrite($f,$zip->file());
    4. fclose($f);
    поставить:
    Код (Text):
    1.  
    2. echo($zip->file());
    то тут же выскакивает окно сохранения файла.
     
  9. Sleven

    Sleven Активный пользователь

    С нами с:
    18 июл 2006
    Сообщения:
    99
    Симпатии:
    0
    Адрес:
    Сургут
    кстати, да, через Opera у меня вообще нигде денвер не получает файлы :( а в ИЕ все пашет...
    хотя нет, вру - Opera передает файлы, только если вернуть на место enctype и массив $_FILES, а IE - с точностью до наоборот
     
  10. Sleven

    Sleven Активный пользователь

    С нами с:
    18 июл 2006
    Сообщения:
    99
    Симпатии:
    0
    Адрес:
    Сургут
    только что проверил:
    1) При наличии enctype="multipart/form-data" и коде:
    Код (Text):
    1. ...
    2. if(isset($price)) {  
    3.  include_once("zip.php");
    4.  include_once("translit.php"); // простейшая функция транслитерации, написанная мною
    5.  $zip=new zipfile();
    6.  $Price_file="price/"; // задаем папку, где хранятся все прайсы
    7.  $Price_file.=translit(basename($_FILES["price"]["name"])); // дополняем оттранслитерованным названием файла
    8.  if(copy($_FILES["price"]["tmp_name"], $Price_file)) {  // копируем в папку "price" полученный файл
    9.   $fp=fopen($Price_file,"rb"); // полученный файл открываем для чтения
    10.   $zip->addFile(fread($fp,filesize($Price_file)),$Price_file,time());  // считываем полученный файл и добавляем в $zip
    11.   fclose($fp);
    12.   $price_href="price/".$_SESSION["id"]."-price".date("d.m.y").".zip"; // папка и название нового файла-архива
    13.   $f=fopen($price_href,"wb");  // создаем новый файл-архив
    14.   fwrite($f,$zip->file()); // и записываем в него все сжатые даные
    15.   fclose($f);
    16.   unlink($Price_file);  // удаляем полученный ранее и скопированный файл, т.к. он больше не нужен (его копия добавлена в созданный архив)
    17.  }
    18. }
    19. ...
    опера заругалась на функции copy() - no such file, IE выполнил скрипт, но архива не создал

    2) при отсутствии enctype и коде, указанным мною в предыдущих сообщениях - и Опера, и ИЕ выполнили скрипт, но архив не появился.
     
  11. Sleven

    Sleven Активный пользователь

    С нами с:
    18 июл 2006
    Сообщения:
    99
    Симпатии:
    0
    Адрес:
    Сургут
    пардон господа, моя забитая всякой xpенью башка всему виной... Дело оказалось вот в чем:
    1) Когда скрипт впервые получал файл с прайсом, он добавлял его в архив и оставлял путь в базе данных.
    2) Когда выбиралось редактирование и закачка нового прайса, то скрипт первым делом создавал этот новый архив, с текущей датой в названии, а потом уже только смотрел в базе ссылу на старый прайс и удалял его, соответственно, если редактировать больше одного раза в день - тогда скрипт как только создавал новый архив, тут же удалял его (т.к. в базе был аналогичный путь к старому файлу). Проблема была решена перемещением этой части кода. Вот рабочий вариант:
    Код (Text):
    1.  
    2. if(isset($price)) {  // если переменная файла существует
    3.  if(!strstr(basename($price),".rar") && !strstr(basename($price),".zip")) {  
    4.  // в "правильном" варианте $price надо заменить на $_FILES["price"]["name"]
    5.  // если закачиваемый файл уже является архивом, то ZIP не потребуется
    6.   include_once("translit.php");
    7.   include_once("zip.php");
    8.   $zip=new zipfile();
    9.   $Price_file=translit(basename($price));
    10.   // в "правильном" варианте $price надо заменить на $_FILES["price"]["name"]
    11.   // транслитерируем русские буквы в названии файла
    12.   if(copy($price, $Price_file)) {
    13.   // в "правильном" варианте $price надо заменить на $_FILES["price"]["tmp_name"],
    14.   // а функцию copy() лучше заменить на move_uploaded_file
    15.   // копируем полученный файл в текущую директорию, с новым именем
    16.    $fp=fopen($Price_file,"rb"); // открываем полученный (скопированный) файл для чтения
    17.    $zip->addFile(fread($fp,filesize($Price_file)),$Price_file,time());  // добавляем данные файла в архив
    18.    fclose($fp);
    19.    $price_href=$_SESSION["id"]."-price".date("d.m.y").".zip"; // задаем имя создаваемого архива
    20.    $f=fopen("price/".$price_href,"wb"); // создаем архив в нужной нам папке
    21.    fwrite($f,$zip->file()); // записываем архив
    22.    fclose($f);
    23.    unlink($Price_file); // удаляем скопированный ранее файл, который теперь не нужен
    24.   }
    25.  } else {
    26.  // если полученный файл уже является архивом, то второй раз сжимать не будем, а просто
    27.  // скопируем его в нужную папку, задав новое имя
    28.   $price_href=$_SESSION["id"]."-price".date("d.m.y").substr(basename($price),-4);
    29.   // в "правильном" варианте $price надо заменить на $_FILES["price"]["name"]
    30.   // задаем новое имя
    31.   copy($price, "price/".$price_href); // копируем в нужную нам папку
    32.   // в "правильном" варианте $price надо заменить на $_FILES["price"]["tmp_name"]
    33.  }
    34. }
    Кстати, я использовал транслитерацию при добавлении файлов в архив, потому как не знаю в какую кодировку надо конвертить символы в данном случае. Пробовал в ЮТФ-8 - все равно иероглифы.