2012-05-04 27 views
7

Oto kod, który używam:odczytu danych z fsockopen użyciu fgets/fread wisi

if (!($fp = fsockopen('ssl://imap.gmail.com', '993', $errno, $errstr, 15))) 
    echo "Could not connect to host"; 
$server_response = fread($fp, 256); 
echo $server_response; 

fwrite($fp, "C01 CAPABILITY"."\r\n"); 
while (!feof($fp)) { 
    echo fgets($fp, 256); 
} 

dostanę pierwszą odpowiedź:

OK Gimap ready for requests from xx.xx.xx.xx v3if9968808ibd.15 

ale wtedy czasy stronę wyjścia. Przeszukałem przez stream_set_blocking, stream_set_timeout, stream_select, fread, itp., Ale nie mogłem go uruchomić. Muszę przeczytać wszystkie dane, które wysyła serwer, a następnie wykonać inne polecenia (chciałbym pobierać wiadomości e-mail przy użyciu imap).

Dzięki

+0

Czy na pewno odpowiedź jest tylko 256 długo zwlekać? Czy jesteś pewien, że gniazdo można zapisać? Możliwe, że Twój skrypt zawiesza się na 'fwrite()', ponieważ gniazdo nie jest możliwe do zapisu ... – shadyyx

+0

Tak. Testowałem to, zastępując pętlę while prostym pisaniem fgetów ($ fp, 256) dwa razy. I to jest odpowiedź, którą otrzymuję: * MOŻLIWOŚĆ IMAP4rev1 UNSELECT IDLE NAMESPACE QUOTA ID XLIST DZIECI X-GM-EXT-1 XYZZY SASL-IR AUTH = XOAUTH C01 OK –

Odpowiedz

8

Twój skrypt wisi w pętli while na końcu. Wynika to z faktu, że jako warunek dla pętli użyto !feof(), a serwer nie zamyka połączenia. Oznacza to, że feof() zawsze zwróci false, a pętla będzie kontynuowana na zawsze.

Nie będzie to problemem, gdy zapis pełne wdrożenie, jak będzie patrząc na kody odpowiedzi i może wyrwać się z pętli odpowiednio, na przykład:

<?php 

    // Open a socket 
    if (!($fp = fsockopen('ssl://imap.gmail.com', 993, $errno, $errstr, 15))) { 
     die("Could not connect to host"); 
    } 

    // Set timout to 1 second 
    if (!stream_set_timeout($fp, 1)) die("Could not set timeout"); 

    // Fetch first line of response and echo it 
    echo fgets($fp); 

    // Send data to server 
    echo "Writing data..."; 
    fwrite($fp, "C01 CAPABILITY\r\n"); 
    echo " Done\r\n"; 

    // Keep fetching lines until response code is correct 
    while ($line = fgets($fp)) { 
    echo $line; 
    $line = preg_split('/\s+/', $line, 0, PREG_SPLIT_NO_EMPTY); 
    $code = $line[0]; 
    if (strtoupper($code) == 'C01') { 
     break; 
    } 
    } 

    echo "I've finished!"; 
+0

Dzięki. Teraz po prostu muszę znaleźć kody odpowiedzi dla innych poleceń ... –

+1

[RFC to twoi przyjaciele] (http://tools.ietf.org/html/rfc3501) ;-) (Nie zapomnij obsłużyć odpowiedzi o błędach również, lub skrypt będzie wisiał na zawsze czekając na odpowiedź 'C01', której nigdy nie otrzyma) – DaveRandom

+0

Tak. Przejmuję te polecenia od jakiegoś czasu. Dzięki jeszcze raz. –

1

Twój skrypt powinien działać. W rzeczywistości działa.

Zobacz wyniki poniżej na moim komputerze, kiedy prowadził swój kod:

* OK Gimap ready for requests from xx.xx.xx.xx l5if4585958ebb.20 
* CAPABILITY IMAP4rev1 UNSELECT IDLE NAMESPACE QUOTA ID XLIST CHILDREN X-GM-EXT-1 XYZZY SASL-IR AUTH=XOAUTH 
C01 OK Thats all she wrote! l5if4585958ebb.20 

Ponieważ Gmail nie zostanie odłączony. Brak końca pliku. A ładowanie strony po prostu wygasa.

Innymi słowy: Twój skrypt będzie po prostu czekał i czeka, aż Gmail się rozłączy, co niestety ma miejsce po upływie czasu ładowania strony.

+0

Czy otrzymałeś wynik natychmiast, lub zajęło to trochę czasu (1-2min) do przekroczenia limitu czasu ?? –

+0

Problem polega prawdopodobnie na tym, że próbujesz uruchomić go ze strony internetowej, czy mam rację? Strona przekroczy limit czasu, zanim Gmail się rozłączy (więc feof() nigdy nie zwróci true). Prawdopodobnie traci część bufora w procesie ograniczania czasu. – Woutifier

+0

Tak. Mam stronę .php, która ma ten kod. Jaki jest problem? –