Форум: Форум PHPФорум ApacheФорум Регулярные ВыраженияФорум MySQLHTML+CSS+JavaScriptФорум FlashРазное
Новые темы: 0000000
Самоучитель MySQL 5. Авторы: Кузнецов М.В., Симдянов И.В. PHP. Практика создания Web-сайтов (второе издание). Авторы: Кузнецов М.В., Симдянов И.В. PHP 5/6. В подлиннике. Авторы: Кузнецов М.В., Симдянов И.В. PHP Puzzles. Авторы: Кузнецов М.В., Симдянов И.В. Объектно-ориентированное программирование на PHP. Авторы: Кузнецов М.В., Симдянов И.В.
ВСЕ НАШИ КНИГИ
Консультационный центр SoftTime

Форум PHP

Выбрать другой форум

 

Здравствуйте, Посетитель!

вид форума:
Линейный форум Структурный форум

тема: Выдача файла скриптом
 
 автор: tAleks   (06.05.2009 в 12:33)   письмо автору
 
 

Нужно выдавать файлы только авторизованным пользователям.

делаю так:

<?php

$id_file 
= intval($_GET['id_file']);
if(!
$id_file) exit;

// Зпрашиваем данные файла
$file = files::select($id_file);
if(!
$file) exit;

// Имя файла для выдачи
$filename = (!empty($file['filename'])) ? $file['filename'] : basename($file['path']);


// Путь к файлу от корня
$file = $_SERVER['DOCUMENT_ROOT'].$file['path'];
if(!
is_file($file)) exit;


$handle = fopen($file, 'rb'); 
fseek($handle, 0, SEEK_END);
$size = ftell($handle); 


// Если передан RANGE (запрос части)
// Вычисляем с какого по какой кусок файла недо передать
if(isset($_SERVER['HTTP_RANGE']))
{
    
$range = explode('=', $_SERVER['HTTP_RANGE']);
    
$range = explode('-', $range[1]);
    
    if(!
$range[0]) $range[0] = 0;
    if(
$range[1]) ++$range[1];
    else 
$range[1] = $size;
}
else 
$range = array(0, $size);

if(
$range[0] < 0)         $range[0] = 0; 
if(
$range[1] > $size) $range[1] = $size; 

// Размер части и старт части
$part_size = $range[1]-$range[0]; 
$range_start = $range[0];


// Если передан запрос на часть файла
if($range[0] > 0 || $range[1] < $size) 
{
    
// Стоп части
    
$range_stop = $range[1]-1;
    
    
header("206 HTTP/1.0 Partial content");
    
header("Content-Length: $part_size");
    
header("Content-Range: bytes $range_start-$range_stop/$size");
}
else
{ 
    
header("Content-Length: $size");
}

header('Accept-Ranges: bytes');
header('Content-Type: application/octet-stream; name="'.$filename.'"');
header('Content-Disposition: attachment; filename="'.$filename.'"');


// Устанавливаем указатель на позицию Старт
fseek($handle, $range_start, SEEK_SET);

if(
$range[1] == $size)
{
    
fpassthru($handle);
}
else
{
    for(
$blklen = 16384, $pos = $range_start; $pos < $range[1]; $pos += $buflen) 
    { 
        if(
$range[1]-$pos < $blklen) 
                
$blklen = intval($range[1]-$pos); 
        
        
$buffer = fread($handle, $blklen); 
        
$buflen = strlen($buffer); 
        echo 
$buffer; 
    } 
}
?>


Как-то странно работает.
При обращении первый раз по адресу: www.site.ru/get.php?id_file=1 ругается так:

IE не удается загрузить get.php из site.ru
Не удается открыть этот узел Интернета. Узел недоступен или не найден. Повторите попытку позднее.


Тут же, вэтом же окне обращаюсь по этому же адресу второй раз - выдает файл.

Подскажите, где искать ошибку.

  Ответить  
 
 автор: tAleks   (06.05.2009 в 12:40)   письмо автору
 
   для: tAleks   (06.05.2009 в 12:33)
 

К стати, а может есть вариант по проще, выдавать файлы авторизованным пользователям?
Слышал про какие-то символические ссылки. Это подойдет? Как они работатют, где мжно про них почитать?

  Ответить  
 
 автор: tAleks   (06.05.2009 в 12:57)   письмо автору
 
   для: tAleks   (06.05.2009 в 12:40)
 

Только что в инете нашел другой вариант:


<?php
function downloadFile($filename, $mimetype='application/octet-stream') {
        if (!
file_exists($filename)) die('Файл не найден');

        
$from=$to=0; $cr=NULL;

        if (isset(
$_SERVER['HTTP_RANGE'])) {
                
$range=substr($_SERVER['HTTP_RANGE'], strpos($_SERVER['HTTP_RANGE'], '=')+1);
                
$from=strtok($range, '-');
                
$to=strtok('/'); if ($to>0) $to++;
                if (
$to) $to-=$from;
                
header('HTTP/1.1 206 Partial Content');
                
$cr='Content-Range: bytes ' . $from . '-' . (($to)?($to . '/' . $to+1):filesize($filename));
        } else  
header('HTTP/1.1 200 Ok');

        
$etag=md5($filename);
        
$etag=substr($etag, 0, 8) . '-' . substr($etag, 8, 7) . '-' . substr($etag, 15, 8);
        
header('ETag: "' . $etag . '"');

        
header('Accept-Ranges: bytes');
        
header('Content-Length: ' . (filesize($filename)-$to+$from));
        if (
$cr) header($cr);

        
header('Connection: close');
        
header('Content-Type: ' . $mimetype);
        
header('Last-Modified: ' . gmdate('r', filemtime($filename)));
        
$f=fopen($filename, 'r');
        
header('Content-Disposition: attachment; filename="' . basename($filename) . '";');
        if (
$from) fseek($f, $from, SEEK_SET);
        if (!isset(
$to) or empty($to)) {
                
$size=filesize($filename)-$from;
        } else {
                
$size=$to;
        }
        
$downloaded=0;
        while(!
feof($f) and !connection_status() and ($downloaded<$size)) {
                echo 
fread($f, 512000);
                
$downloaded+=512000;
                
flush();
        }
        
fclose($f);
}
?>


Такая же ошибка. Может дело не в скрипте, а в IE8, например?

  Ответить  
 
 автор: tAleks   (06.05.2009 в 13:03)   письмо автору
 
   для: tAleks   (06.05.2009 в 12:57)
 

Блин, правда, Опера и ФФ, не выдают такую ошибку.

Тогда вопрос. Что делать с ИЕ? Как его победить?

  Ответить  
Rambler's Top100
вверх

Rambler's Top100 Яндекс.Метрика Яндекс цитирования