В общем по рекомендации создаю эту тему. Есть модуль для скачивания файлов с сайта. В файле модуля index.php, есть функция function view_file() функция формирует и показывает информацию об определенном файле, также в ней происходит действие на скачивание в форме Код (Text): <form method=\"POST\" action=\"modules.php?name=".$module_name."\"> <input type=\"hidden\" name=\"lid\" value=\"".$lid."\"> <input type=\"hidden\" name=\"path\" value=\"".$path."\"> <input type=\"hidden\" name=\"title\" value=\"".$title."\"> <input type=\"hidden\" name=\"file\" value=\"getit\"> <input type=\"submit\" value=\""._FILES_DOWNLFILE."\"> </form> Где $lid = id файла в БД $path = путь_к_файлу $title = Название файла под которым его увидит пользователь getit = getit.php (аналог download.php) где происходит непосредственно отдача файла В файл getit.php вставляю класс Код (Text): class download { var $properties = array( 'old_name' => '', 'new_name' => '', 'type' => '', 'size' => '', 'resume' => '', 'max_speed' => '' ); var $range = 0; function download($path, $name='', $type='application/force-download', $resume=0, $max_speed=0) { $name = ($name == '') ? substr(strrchr("/".$path,"/"),1) : $name; $file_size = @filesize($path); $this->properties = array( 'old_name' => $path, 'new_name' => $name, 'type'=> $type, 'size' => $file_size, 'resume' => $resume, 'max_speed' => $max_speed ); if ($this->properties['resume']) { if(isset($_SERVER['HTTP_RANGE'])) { $this->range = $_SERVER['HTTP_RANGE']; $this->range = str_replace('bytes=', '', $this->range); $this->range = str_replace('-', '', $this->range); } else { $this->range = 0; } if ($this->range > $this->properties['size']) $this->range = 0; } else { $this->range = 0; } } function download_file() { if ($this->range) { header($_SERVER['SERVER_PROTOCOL'].' 206 Partial Content'); } else { header($_SERVER['SERVER_PROTOCOL'].' 200 OK'); } header('Pragma: public'); header('Expires: 0'); header('Cache-Control:'); header('Cache-Control: public'); header('Content-Description: File Transfer'); header('Content-Type: '.$this->properties["type"]); header('Content-Disposition: attachment; filename="'.$this->properties['new_name'].'";'); header('Content-Transfer-Encoding: binary'); if ($this->properties['resume']) header('Accept-Ranges: bytes'); if ($this->range) { header("Content-Range: bytes {$this->range}-".($this->properties['size']-1)."/".$this->properties['size']); header("Content-Length: ".($this->properties['size']-$this->range)); } else { header("Content-Length: ".$this->properties['size']); } @ini_set('max_execution_time', 0); @set_time_limit(); return $this->_download($this->properties['old_name'], $this->range); } function _download ($filename, $range=0) { @ob_end_clean(); if (($speed = $this->properties['max_speed']) > 0) $sleep_time = (8 / $speed) * 1e6; else $sleep_time = 0; $handle = fopen($filename, 'rb'); fseek($handle,$range); if ($handle === false) { return false; } //ob_flush(); while (!feof($handle)) { print (fread($handle, 1024*8)); flush(); usleep($sleep_time); } fclose($handle); return true; } } $a = new download($path, $title, 'application/force-download', true); В результате белая страница. Показ ошибок включен, в логах сервера ничего необычного.
Ой блин, точно. Спаисбо.Теперь файл пытается отдать, но при сохранении выдает ошибку Код (Text): Файл С:\TEMP\ddufisFD.mp3.part не может быть сохранен, так как исходный файл не может быть прочтен. Подождите некоторое время и попробуйте снова или обратитесь к администратору сервера. Вот такая фишка когда указан абсолютный путь к файлу. И вот такая ошибка когда указан относительный путь Код (Text): Warning: fopen(../../files/pub_dir/koroleva_vdohnoveniya_.mp3) [function.fopen]: failed to open stream: Нет такого файла или каталога in /home/moya_papka/modules/Files/getit.php on line 198 Сами файлы находятся /home/moya_papka/files/pub_dir
Да пути правильные, как я только их не пытался прописать. В конечном результате, абсолютный путь на 100% правильный. Кстати, а как fopen работает со слешами??? Кстати положил файл непосредственно в modules/Files/ и все равно Варнинг, вернее скачивается страница размером 4 Кб, ну а в исходнике страницы Варнинг И еще я не понял как может работать функция Код (Text): <?php function _download ($filename, $range=0) { @ob_end_clean(); if (($speed = $this->properties['max_speed']) > 0) { $sleep_time = (8 / $speed) * 1e6; }else{ $sleep_time = 0; } $handle = fopen($filename, 'rb'); fseek($handle,$range); if ($handle === false) { return false; } //ob_flush(); while (!feof($handle)) { print (fread($handle, 1024*8)); flush(); usleep($sleep_time); } fclose($handle); return true; } Если переменно $filename нету при вызове
В общем дело немного сдвинулось, раскомментировал //ob_flush();, но работает только при указании абсолютного пути, при относительном не хочет. А вот теперь проблема файл скачивается на 97% и потом получаю затык на приблизительно на секунд 50, после чего загрузка завершается - это в Лисе В Опере - не определяется размер файла, время до окончания загрузки, количество скаченной информации. И в результате статус загрузки "Ошибка" хотя файл оказывается скаченным, также с затыком. Гугл хром. Также нету статуса файла времени и общего размера, а показывает только фактически загруженные Кб. В конце также 40 сек затык. В Эксплорере та же ситуация что и в хроме
есть у меня мысль, что надо как-то послать недозабитый буфер. как - я не шарю =) надо спросить у гуру. у меня у самого тоже хоть файл и загружается, но все равно висит как бы закачка.
А сюда гуру заглядывают? Вот вопросы подвисли в воздухе. 1. Почему не передается весь размер файла браузеру? 2. Почему на 97% подвисает загрузка до 1 минуты?
видимо сервер ждет от пхп ответа, пока он не отвалится =) а вот почему он не отваливается - нипанятна
Кстати, как тут сделать проверку, что файл загружен полностью, чтобы увеличить счетчик? Код (Text): $db->sql_query("UPDATE ".$prefix."_files SET hits=hits+1 WHERE lid=".$lid);
Flint2010, лучше не использовать класс download в том виде, в котором он существует сейчас. Он содержит не менее 5 ошибок (которые видны на первый взгляд) - и синтаксические, и семантические, и логические. Попробуйте сначала исправить их, а потом уже двигаться дальше. Я укажу на пару из них: set_time_limit() - вызов без параметра. $this->range = str_replace('-', '', $this->range); - это будет работать только в одном случае, когда в HTTP_RANGE будет -[число], что означает последний блок из [число] байт. А как насчет того, что HTTP_RANGE может содержать [число]-[число]? К тому же код этот читаем, но с большим трудом. Я бы сказал, что он "некрасивый". Не в обиду будет сказано разработчику, как говорится: Москва не сразу строилась. Если мне и приходится спользовать чужой код, то сперва я разбираюсь, как это все работает, а потом его привожу к тому виду, который нравится мне . Речь, конечно же, не о целых движках. Да, и я не профессионал, учусь также как и Вы. Поэтому привыкайте сразу к чистому коду и кому будете помогать - тоже рекомендуйте это. Вот, приношу извинения за флуд.
странно. возможно пхп отрабатывает и отдает это какомунть нгинксу и считает что отработал хорошо. хз как там.