Как заставить curl отдавать файл недокаченным ?

Тема в разделе "PHP", создана пользователем tarantas, 4 авг 2009.

Статус темы:
Закрыта.
Модераторы: latteo
  1. tarantas

    tarantas Постоялец

    Регистр.:
    22 мар 2008
    Сообщения:
    75
    Симпатии:
    14
    Добрый вечер.

    В общем есть скрипт :

    PHP:
            $ch curl_init();

            
    curl_setopt($chCURLOPT_URL$url);
            
    curl_setopt($chCURLOPT_HEADER0);
            
    curl_setopt($chCURLOPT_RETURNTRANSFER1);
            
    curl_setopt($chCURLOPT_TIMEOUT90);

            if ( isset(
    $ipsclass->proxy) ) curl_setopt($chCURLOPT_PROXY$ipsclass->proxy);
            if ( isset(
    $ipsclass->proxy) && isset($ipsclass->proxytype) ) curl_setopt($chCURLOPT_PROXYTYPE$ipsclass->proxytype);
            if ( isset(
    $ipsclass->proxy) && isset($ipsclass->proxyuserpwd) ) curl_setopt($chCURLOPT_PROXYUSERPWD$ipsclass->proxyuserpwd);

            
    $x curl_exec($ch) or die( curl_error($ch) );

            
    $filesize curl_getinfo($chCURLINFO_CONTENT_LENGTH_DOWNLOAD);

            if ( 
    curl_getinfo($chCURLINFO_HTTP_CODE) == 404 || curl_getinfo($chCURLINFO_HTTP_CODE) == 403 header("HTTP/1.0 404 Not Found");

            
            
    curl_close($ch);
    Где $url - ссылка на файл.
    Работает он след. образом : коннектится к серверу через прокси, закачивает к себе на сервер нужный файл и уже потом отдает его юзеру.

    Так вот последнее время прокси стал работать медленно ( либо на конечном сервере срезали отдачу ), поэтому файл закачаться не успевает и происходит таймаут.
    ( Таймаут не курла, а видимо апача ).

    Так вот вопрос : можно ли сделать так : курл скачивает "кусочек", и сразу же отдает его юзеру ?
    То есть не ждать пока скачается файл целиком, а сразу отдавать скачанное юзеру ?

    Вроде у СОКЕТОВ так, но сокеты нет возможности использовать ( т.к. прокси-сервер, да и не люблю я их ).

    Спасибо.
     
  2. lena berkova

    lena berkova

    Регистр.:
    14 янв 2009
    Сообщения:
    441
    Симпатии:
    19
    а что мешает сразу же отдавать байты юзеру а не писать в файл на сервер?
    прочитал 1 килобайт и отдал в потом юзеру и так далее
     
  3. tarantas

    tarantas Постоялец

    Регистр.:
    22 мар 2008
    Сообщения:
    75
    Симпатии:
    14
    Ну а как это сделать ?

    PHP:
    $x curl_exec($ch) or die( curl_error($ch) );
    Эта операция качает файл целиком, и до тех пор пока не скачает, не отдает управление дальше.
     
  4. D@nil

    D@nil

    Регистр.:
    1 окт 2006
    Сообщения:
    338
    Симпатии:
    122
    Конечно можно.

    Идем по посылочке, находим пареметр отвечаюший какой сегмент нам скачать, и используем
    http://ru.php.net/manual/en/function.curl-setopt.php
     
  5. tarantas

    tarantas Постоялец

    Регистр.:
    22 мар 2008
    Сообщения:
    75
    Симпатии:
    14
    Ну это понятно, curlopt_range.

    А как сделать чтобы он взятые кусочки сразу же слал в вывод, по циклу ?
    Чтото типа while ( !feof($x) ) ?
     
  6. D@nil

    D@nil

    Регистр.:
    1 окт 2006
    Сообщения:
    338
    Симпатии:
    122
    видимо надо циклом работать, загружаешь курлом кусок к примеры 1 МБ отдаешь через echo с правильными заголовками. и так пока файл посностью не скачается.
     
  7. tarantas

    tarantas Постоялец

    Регистр.:
    22 мар 2008
    Сообщения:
    75
    Симпатии:
    14
    В принципе вариант нашел :

    PHP:
    function vivod()
    {
    global 
    $x;

    print 
    $x;

    return 
    $x;
    }

    ...

    curl_setopt($chCURLOPT_BUFFERSIZE51200);
    curl_setopt($chCURLOPT_WRITEFUNCTION"vivod");

    ...

    $x curl_exec($ch) or die( curl_error($ch) );
    Но не работает он, пишет 0Failed writing body

    Что делатьто ?

    Добавлено через 50 минут
    Короче сделал.

    PHP:
    function vivod($x1$x2)
    {

        if ( 
    $GLOBALS['counter'] == )
        {
        
    $name "site.net_".$GLOBALS['v'].".mp3";

        
    header"Content-Type: audio/mpeg" );
        
    header"Content-Disposition: attachment; filename=$name);
        
    header"Accept-Ranges: bytes" );
        
    header"Content-Length: ".$GLOBALS['filesize'] );
        }

    echo 
    $x2;

    $GLOBALS['counter']++;

    return 
    mb_strlen($x2);
    }
    PHP:
            curl_setopt($chCURLOPT_BUFFERSIZE51200);
            
    curl_setopt($chCURLOPT_WRITEFUNCTION"vivod");
    Сейчас осталось придумать чтонибудь с content-length ( не определяется ), чтобы у плеера была перемотка.

    PHP:
            $GLOBALS['filesize'] = curl_getinfo($chCURLINFO_CONTENT_LENGTH_DOWNLOAD);
    Идет после curl_exec и понятно что в vivod не передается.


    Может есть у кого какие мысли ?
     
  8. baddan

    baddan

    Регистр.:
    14 мар 2008
    Сообщения:
    354
    Симпатии:
    42
    не curl виноват, а ограничение на время выполнение PHP скрипта, если curl вываливается по тайма ауту он сбрасывает в буфер все что успел получить. а вот если система завершила скрипт то соответственно у тебя ничего и не сохранилось. правь php.ini либо добавляей set_time_limit
     
Статус темы:
Закрыта.