problem mit fgets

jogisarge

Grünschnabel
Hallo zusammen,

ich schicke Daten an einen Webserver und möchte die Antwort verarbeiten.
Den Script läuft auf meinem rechner unter Apache und PHP5.2 .
Anbindung ist DSL6000.

PHP:
$fp = fsockopen("ssl://server.com",443,$errstr,$errno);
if(!$fp)
{
    die();
}
else
{ 
    $file = addslashes($file);
    $data = $file;
    fputs($fp, "POST /webservice/XMLServlet HTTP/1.0\r\n");
    fputs($fp, "Host: server.com\r\n");
    fputs($fp, "Authorization: Basic ".$kennung." \r\n");
    fputs($fp, "Content-length: ". strlen($data) ."\r\n");
    fputs($fp, "Content-type: application/x-www-form-urlencoded\r\n");
    fputs($fp, "Connection: close\r\n\r\n");
    fputs($fp, $data);
}
$xxx = 1;
while(!feof($fp))
{ 
    echo "Step ".$xxx." : ".date("d.m.Y - H:i:s")."<br>\n";
    $data .= fgets($fp, 2048);
    $xxx++;
}

da das script beim ersten Aufruf sehr lahm ist, habe ich eine Art Debug mit Zeitmarken gemacht.
Dabei fiel auf, dass die meiste Zeit für die While Schleife drauf geht.
Wie man in den Auszügen sieht, wird das Script immer schneller :-)

Ich rufe das Script in einer Minute 4 mal auf.
Beim letzten mal ist das Script sehr schnell.

Code:
1 : 06.06.2008 - 11:29:45<br>
2 : 06.06.2008 - 11:30:08<br>
3 : 06.06.2008 - 11:30:08<br>
4 : 06.06.2008 - 11:30:08<br>
5 : 06.06.2008 - 11:30:08<br>
6 : 06.06.2008 - 11:30:08<br>
7 : 06.06.2008 - 11:30:08<br>
8 : 06.06.2008 - 11:30:08<br>
9 : 06.06.2008 - 11:30:08<br>

15 seconds later again

Code:
1 : 06.06.2008 - 11:30:58<br>
2 : 06.06.2008 - 11:31:22<br>
3 : 06.06.2008 - 11:31:22<br>
4 : 06.06.2008 - 11:31:22<br>
5 : 06.06.2008 - 11:31:22<br>
6 : 06.06.2008 - 11:31:22<br>
7 : 06.06.2008 - 11:31:22<br>
8 : 06.06.2008 - 11:31:22<br>
9 : 06.06.2008 - 11:31:22<br>

another 15 seconds later
Code:
1 : 06.06.2008 - 11:33:01<br>
2 : 06.06.2008 - 11:33:05<br>
3 : 06.06.2008 - 11:33:05<br>
4 : 06.06.2008 - 11:33:05<br>
5 : 06.06.2008 - 11:33:05<br>
6 : 06.06.2008 - 11:33:05<br>
7 : 06.06.2008 - 11:33:05<br>
8 : 06.06.2008 - 11:33:05<br>
9 : 06.06.2008 - 11:33:05<br>

another 15 seconds later
Code:
1 : 06.06.2008 - 11:33:28<br>
2 : 06.06.2008 - 11:33:31<br>
3 : 06.06.2008 - 11:33:31<br>
4 : 06.06.2008 - 11:33:31<br>
5 : 06.06.2008 - 11:33:31<br>
6 : 06.06.2008 - 11:33:31<br>
7 : 06.06.2008 - 11:33:31<br>
8 : 06.06.2008 - 11:33:31<br>
9 : 06.06.2008 - 11:33:31<br>
10 : 06.06.2008 - 11:33:31<br>
11 : 06.06.2008 - 11:33:31<br>
12 : 06.06.2008 - 11:33:31<br>
13 : 06.06.2008 - 11:33:31<br>
14 : 06.06.2008 - 11:33:31<br>
15 : 06.06.2008 - 11:33:31<br>
16 : 06.06.2008 - 11:33:31<br>

Man sieht, dass beim ersten fgets am meisten Zeit drauf geht.
Hat jemand ne Idee, warum das so ist ?
Kann ich daran etwas ändern?

bye jogi
 
Da du PHP5 hast, teste mal die Funktionen file_get_contents und file_put_contents.
Zum Beispiel (ungetestet):
PHP:
    $file = 'datei.endung';
    $content = 'POST /webservice/XMLServlet HTTP/1.0'. "\r\n";
    $content .= 'Host: server.com'. "\r\n";
    $content .= 'Authorization: Basic ' .$kennung. ' '. "\r\n";
    $content .= 'Content-length: ' .strlen($data). "\r\n";
    $content .= 'Content-type: application/x-www-form-urlencoded'. "\r\n";
    $content .= 'Connection: close'. "\r\n\r\n";
    file_put_contents( $file, $content );
    
    //...
    file_get_contents( $file );
 
Hast du das nur bei SSL Verbindungen gemerkt oder nur bei dem einen Server?
Es könnte sein, das der SSL Wrapper die Ursache ist, aber warum? Bei etlichen anderen Leuten scheint es schneller zu gehen, zumindest habe ich noch nichts gegenteiliges gehört.

Wie gross ist denn die Ausgabe der Daten? Eventuell rechnet die Gegenseite ("server.com") etwas länger an der Aufbereitung der XML Daten. Das würde dann auch die Wartezeit immer nur bei 1. Durchlauf der While Schleife möglicherweise erklären.

Ich würde hier versuchen Teile erstmal rauszunehmen (SSL, Authentication) oder einen anderen Server testen.
Tritt das Problem auch bei z.B. normalen HTTP Request auf? Beispiel

PHP:
<?php

$fp = fsockopen("tutorials.de",80,$errstr,$errno);
if(!$fp)
{
    die();
}
else
{
    $file = addslashes($file);
    $data = $file;
    fputs($fp, "GET /forum/php/315383-problem-mit-fgets.html HTTP/1.0\r\n");
    fputs($fp, "Host: www.tutorials.de\r\n");
    fputs($fp, "Content-Type: text/html\r\n");
    fputs($fp, "Connection: close\r\n\r\n");
    fputs($fp, $data);
}
$xxx = 1;
while(!feof($fp))
{
    echo "Step ".$xxx." : ".date("d.m.Y - H:i:s")." . ".microtime(TRUE)."<br>\n";
    $data .= fgets($fp, 2048);
    $xxx++;
}

?>


zu file_get_contents(): benötigt allow-url-fopen, was nicht auf jedem Server möglich ist.

Gruss
 
Hallo nochmal,

Die Daten an den Server sind zwischen 1KB und 20 KB groß.
Zurück ebenfalls.

Ich habe mal den Testcode ausgeführt:
Code:
Start : 06.06.2008 - 13:18:46 . 1212758326.0233<br>
Step 1 : 06.06.2008 - 13:18:46 . 1212758326.3122<br>
Step 2 : 06.06.2008 - 13:18:46 . 1212758326.7199<br>
Step 3 : 06.06.2008 - 13:18:46 . 1212758326.7264<br>
Step 4 : 06.06.2008 - 13:18:46 . 1212758326.7332<br>
Step 5 : 06.06.2008 - 13:18:46 . 1212758326.7393<br>
Step 6 : 06.06.2008 - 13:18:46 . 1212758326.7457<br>
Step 7 : 06.06.2008 - 13:18:46 . 1212758326.753<br>
...
Step 2610 : 06.06.2008 - 13:19:03 . 1212758343.9505<br>
Step 2611 : 06.06.2008 - 13:19:03 . 1212758343.9564<br>
Step 2612 : 06.06.2008 - 13:19:03 . 1212758343.9622<br>
Step 2613 : 06.06.2008 - 13:19:03 . 1212758343.9679<br>
Step 2614 : 06.06.2008 - 13:19:03 . 1212758343.9737<br>
Step 2615 : 06.06.2008 - 13:19:03 . 1212758343.9795<br>
Step 2616 : 06.06.2008 - 13:19:03 . 1212758343.9852<br>
Step 2617 : 06.06.2008 - 13:19:03 . 1212758343.991<br>
Ende : 06.06.2008 - 13:19:03 . 1212758343.997<br>

Wenn ich mein Programm von einem Webserver aus starte, ist die Antwort viel schneller !!

@Loomes
Wie muss ich das mit file_put_contents/file_get_contents genau machen ?

Gruß jogi
 
Hmm, dann würde ich mal sagen, es liegt an dem Webserver von dem du es aus startest :)
Habe es mal mit einem XAMPP von meinem Windows Rechner ausprobiert und es läuft auch alles sehr schnell ab.

Eventuell könntest du noch mit der stream_set_blocking() Funktion spielen.

Vielleicht eine Firewall auf deinem Rechner (Betriebsystem nehme ich jetzt mal Windows XP an) die du mal deaktivieren kannst zum testen?

Mir gehen die spontanen Ideen aus...

Zu den file_[put|get]_contents Funktionen gibts bei den Kommentaren zu file_get_contents() eine simple Beispielanwendung:
http://de2.php.net/manual/de/function.file-get-contents.php#82527
Genauso funktioniert es eigentlich beim put.

Als weitere Alternative bleibt CURL
http://de2.php.net/manual/de/book.curl.php

Gruss
 
Zurück