Dlaczego fseek ignoruje zmienną, a przyjmuje wartość podaną "na sztywno"?

0

Cześć.

Z PHP jak może wiecie jestem lama, ale coś tam próbuje wymodzić sam. Kiedyś pytałem o to jak zapisywać pliki z danego urla pod inną nazwą niż istnieje na serwerze źródlowym. Wtedy @dzek69 pisał, że to zabija serwer. I że trzeba korzystać raczej z taga html, który obsługują tylko bardzo nowe przeglądarki. Niemniej jednak serwera mi nie zamulilo raczej, a googlując jakoś to ogarnąłem. Pobieranie pliku od 0% do 100% - działa ok.

Jednak jest problem z wznawianiem i funkcją fseek. Logowałem sobie co jest zwracane do pliku i $res zwraca 0. Czyli jak rozumiem się powiodło. To dlaczego jakby "ignoruje mi" zmienna $aoffset?

Plik na dysku w momencie przerwania pobierania ma na przykład dokładnie 34565600 bajtów. Wznawiam pobieranie Operą pod Windows. W pliku log.txt zapisuje się Offset = 34565600. Poimo tego pobrany plik w miejscu wznowienia jest zapełniony danymi z jego początku. Tak jakbym nie zrobil fseek w ogóle lub kazał wznawiać od zerowego bajtu. Kiedy jako drugi parametr fseek podam jakąś liczbę całkowitą. Czy to dziesiętnie czy jako hex z 0x, to wtedy plik wznawiany będzie od tego miejsca. Jendak wiadomo wpływa to ponownie na poprawność całości pliku. Na przykład mp4 się nie przewinie do końca trwania materiału itd. W nagłowkach mam między innymi raczej w porządku Content-Type: application/octet-stream.

Serwer źródłowy wznawianie wspiera. Co robię nie tak? Reszty kodu nie wklejam. Bo skoro podałem jako drugi parametr dla fseek na przykład 16. I mi wznowilo od tego offsetu, to kod jest raczej ok. Tylko nie mogę dojść dlaczego fseek "olewa zmienne". Coś pewnie robię nie tak. I jest to banał, ale coż - o PHP mam malutkie pojęcie. Testuje wszystko póki co na Apache 2.4 i PHP 5.5.13. Pod Windows. Z góry dziękuję za pomoc i przykładowy kod z rozwiązaniem problemu. Przepraszam za tradycyjne rozpisanie się :)

// ...
function logz($text)
{
  $loghandle = fopen("log.txt", "w");
  fwrite($loghandle, $text);
  fclose($loghandle);
}

//...

    $chunksize = 4096;
    $bytes_send = 0;
    ob_clean();
    flush();
    if ($file = fopen($url, 'r'))
    {
      if(isset($_SERVER['HTTP_RANGE'])) {
        $aoffset = intval($aoffset);
        $res = fseek($file, $aoffset);
        logz("Offset = " . $aoffset);
      }
      while (!feof($file)) {
         $buffer = fread($file, $chunksize);
         echo $buffer;
         flush();
         $bytes_send += strlen($buffer);
      }
    fclose($file);

//...
1

Rozwiązałem problem. Jednak kodzenie po omacku w PHP, późno w nocy lub nad ranem, daje jakieś efekty ;) Pomogło to co poniżej - dopisanie "magicznego" SEEK_CUR.

fseek($file, $aoffset, SEEK_CUR);

Nie wnikałem w manual fseek dokładnie. Ale doczytałem, że tego się używa. Widocznie ma to znaczenie przy fopen z adresów zdalnych. Zatwierdzam tę własną odpowiedź jako rozwiązanie i pora iść trochę pospać :) Najważniejsze, że skrypt śmiga, tak jak tego chcę.

0

Nie wiem o co chodzi, ale cieszę się, że już rozwiązane ;)

Nie każde rozwiązanie zabija serwer, ale te, które wczytują cały plik do pamięci, przed podaniem go użytkownikowi - na pewno ;)

1 użytkowników online, w tym zalogowanych: 0, gości: 1