Pomoc - Szukaj - Użytkownicy - Kalendarz
Pełna wersja: [PHP]Wyświetlenie strumienia dłuższego niż 8192 bajtów
Forum PHP.pl > Forum > Przedszkole
Barton
Witam,

Staram się napisać webowy interfejs do obsługi poczty e-mail. Napotkałem taki problem:

  1. function listuj () {
  2. $this->wyslijKomende("LIST");
  3. $stan = $this->cmd();
  4.  
  5. while($this->answer != NULL {
  6. $this->answer = fread($this->socket, 8192);
  7. echo $this->answer;
  8. }
  9.  
  10. }


Polecenie LIST zwraca strumień danych (numer wiadomości i jej długość). Strumień odczytuję funkcją fread, ale ma on ograniczenie do 8192 bajtów, w związku z czym muszę zapętlić wyświetlanie aż do końca strumienia. I tutaj pojawia się pytanie: co wpisać w warunku pętli, aby w momencie kiedy strumień się skończy, skrypt przestał wyświetlać zmienną?

Pozdrawiam.
Crozin
feof?
Barton
Próbowałem, wstawienie warunku:

  1. !feof($this->answer)


sprawia że strona nie ładuje się, pewnie pętla robi się nieskończona lub coś w tym stylu.

Z kolei warunek

  1. $this->answer !== NULL


Również ładuje w nieskończoność, a na koniec pokazuje rzeczywiście cały strumień a pod spodem błąd:

Fatal error: Maximum execution time of 30 seconds exceeded in C:\wamp\www\pop32.php
Crozin
A teraz sprawdź czego oczekuje feof w swoim pierwszym argumencie. Podpowiedź: Nie jest to wartość tekstowa (string).
Barton
  1. function listuj () {
  2. $this->wyslijKomende("LIST");
  3. $state = $this->cmd();
  4.  
  5. while(!feof($this->socket)) {
  6. $this->answer = fread($this->socket, 8192);
  7. echo $this->answer;
  8. }
  9.  
  10. fclose($this->socket);
  11. }


Nawet zamknąłem połączenie. Efekt taki sam jak wspominałem:

Ładuje dosyć długo a na koniec pokazuje rzeczywiście cały strumień ale pod spodem znajduje się błąd:

Fatal error: Maximum execution time of 30 seconds exceeded in C:\wamp\www\pop32.php
Crozin
Stawiałbym na to, że po prostu skrypt nie jest w stanie się wyrobić z odczytaniem tych danych w ciągu 30 sekund (na co wskazuje treść błędu).

1. Jeżeli powodem może być wielkość pobieranych danych wyłącz/zwiększ limit czasu wykonywania.
2. Możesz zwiększyć limit jednorazowo pobieranej porcji, albo w ogóle użyć stream_get_contents skoro i tak operujesz na całości danych.
3. Według manuala w sumie wystarczyłoby sprawdzanie w pętli czy fread nie zwróciło false (przy wykorzystania operatora identyczności, tj. ===).
Barton
  1. function listuj () {
  2. $this->wyslijKomende("LIST");
  3. $state = $this->cmd();
  4.  
  5. while(fread($this->socket, 8192) === TRUE) {
  6. $this->answer = fread($this->socket, 8192);
  7. echo $this->answer;
  8. }
  9.  
  10. fclose($this->socket);
  11. }


Taka pętla zwraca... "+OK Mailbox scan listing follows".

Jeśli chodzi o wielkość pobieranych danych to nie jest ona aż tak duża. Ręczne ustawienie pętli na 15 powtórzeń zwraca wszystkie dane które powinien (wydaje mi się że cały strumień) i zajmuje to ułamek sekundy. sad.gif
Crozin
Mógłbyś w końcu spojrzeć do manuala? Jak fread może Ci zwrócić true (do którego teraz przyrównujesz) jak masz jak byk napisane:
Cytat
Returns the read string or FALSE on failure.
Więc nigdy nie zwróci Ci true. Musisz użyć operatora zaprzeczenia identyczności (!==) i przyrównać do false.
Barton
Ok, wszystkie sposoby są prawidłowe. Przy ściąganiu samych wiadomości zaobserwowałem co jest przyczyną. Mianowicie po sciągnięciu wiadomości bufer jest zapełniany dalej, losowymi znakami... całkowicie tego nie rozumiem.

Funkcja odczytywania maili wygląda tak:

  1. function odczytaj($mailno) {
  2. fputs($this->socket, trim("retr $mailno") . "\n");
  3. while (($buffer = fgets($this->socket, 4096)) !== false) {
  4. echo $buffer;
  5. }
  6.  
  7. }


Cała reszta kodu nie ma nic do rzeczy gdyż jedynie otwiera połączenie i loguje co idzie sprawnie, ale na życzenie mogę wstawić. Wynik powyższej funkcji wygląda mniejwięcej tak:

[treść ściągniętej wiadomości e-mail][ciąg całkowicie losowych znaków wypisywanych aż do timeout'u]

Ma ktoś jakiś pomysł skąd się one biorą?
To jest wersja lo-fi głównej zawartości. Aby zobaczyć pełną wersję z większą zawartością, obrazkami i formatowaniem proszę kliknij tutaj.
Invision Power Board © 2001-2025 Invision Power Services, Inc.