• Das Erstellen neuer Accounts wurde ausgesetzt. Bei berechtigtem Interesse bitte Kontaktaufnahme über die üblichen Wege. Beste Grüße der Admin

Verständnisfrage (PHP): Unterschied von curl_init und file_get_contents.

PeterM

New member
Guten Tag,

ich möchte von einer externen Website sowohl einen Feed, als auch den Inhalt einer normalen Webseite auslesen. Dies funktioniert auch schon alles.

Allerdings habe ich dies nicht alleine geschafft, sondern hatte viel Hilfe. ^^
Ich habe von PHP leider erst Grundkenntnisse.

Aber da ich die Skripte die auf meinem Webspace laufen zumindest verstehen will, hätte ich dazu mal eine Frage.

Der Feed wird einfach mit file_get_contents ausgelesen.
Die andere Seite jedoch mit curl_init.

Ich habe mir zwar die Beschreibung von curl_init durchgelesen, die Funktionsweise aber noch nicht so wirklich verstanden.
So wie ich das bis jetzt verstehe ist curl_init eigens dazu gedacht URLs auszulesen.
Da man dort mit CURLOPT_HTTPHEADER die Sprache, Zeichensatz,... festlegen kann.

Dazu hier meine Fragen:

1. Was sieht denn der "Ziel"-Webserver, wenn durch mein Skript mittels file_get_contents auf den Feed zugegriffen wird?
Denn dort gibt es ja kein CURLOPT_HTTPHEADER.
Bzw. sollte ich file_get_contents überhaupt dazu verwenden?

2.
2a. Was ist denn der Unterschied zwischen curl_init und file_get_contents?
2b. Was ist besser geeignet um eine andere Webseite auszulesen?
2c. Funktionieren die beiden nach dem gleichen Prinzip?
2d. Gibt es irgendwo eine, auch für Anfänger, geeignete Beschreibung von curl_init?
2e. Was liefert denn curl_init überhaupt zurück? (Bei file_get_contents bekomme ich die Seite ja einfach als String zurück.)

Bei 2. habe ich mal alle Fragen aufgeschrieben, die mir so spontan dazu eingefallen sind.
Am wichtigsten sind mir die Fragen 1, 2d und 2e.
Ich hoffe ihr könnt mir helfen.

Vielen Dank für eure Mühe.
 
Zuletzt bearbeitet:
Zu 1.: wenn du in cURL keine speziellen Einstellungen machst ist der Unterschied zu file_get_contents nicht besonders groß. Der größe Unterschied ist, dass fgc HTTP/1.0 verwendet. Und standartmäßig wird bei cURL ein Accept-Header mitgesendet. ABER mit cURL kannst du hald alle Request-Header beeinflussen und kannst deswegen dem anderen Server z.B. vorgaukeln, dass ein "normaler" Browser die Anfrage gestellt hat. file_get_contents ist viel praktischer als cURL - ist aber nicht so mächtig... also eigentlich deine Entscheidung, was du verwendest.
Zu 2.: a: s.o.
b: kommt auf die andere Websetie an.
c: Was meinst du mit "Prinzip"?
d: PHP-Manual (übrigens ist curl_init nur eine der cURL-Funktionen).
e: siehe d.
 
Ein großer Vorteil von curl ist dass man timeouts behandeln kann.
Wenn die Seite die du auslesen willst gerade offline ist oder lange braucht um zu antworten bist du mit file_get_contents() ausgeliefert, die funktion blockt tot bis die gegenstelle antwortet.
Mit curl kannst du einen timeout festlegen und wenn von der anderen Seite nix kommt kannst du das behandeln.
Das ist aber nur ein Beispiel, wenn du mal durch die Liste aller curl-optionen schaust siehst du wie flexibel das ist.

file_get_contents() abstrahiert das alles weg und wie das mit Abstraktionen halt so ist tauscht man ein großes Level an Flexibilität gegen komfort.
 
Vielen Dank.

Mit Prinzip hatte ich gemeint, ob er sich einfach als Webbrowser ausgibt, und die Daten abfragt, oder ob es evtl. eine "eigene Schnittstelle" ist, wo die Daten bereitgestellt werden.
Aber dies wurde durch eure Antworten schon geklärt.

Das mit dem timeout ist natürlich gut zu wissen.
Deshalb habe ich mich nun entschlossen den curl Befehl für beides zu verwenden.
Allerdings bin ich jetzt auf ein Problem gestoßen, und hänge da nun schon seit fast 2 Stunden, ohne zu wissen, warum es nicht funktioniert.

Das alte Skript sah wie folgt aus:
PHP:
<?
header("Content-Type: application/rss+xml");
$feed = file_get_contents("http://xxx.rss");

$feed = str_replace("content:encoded", "description", $feed);
$feed = preg_replace("/<dc(.*?)<\/dc(.*?)>/im", "", $feed);
//... weitere Anweisungen gekürzt.

echo $feed;
?>

Das neue wollte ich nun so schreiben:
PHP:
<?
header("Content-type: application/rss+xml; charset=utf-8");

function GetSource($url)
	{
		$options = array(
            CURLOPT_RETURNTRANSFER => true,        
            CURLOPT_HEADER         => false,         
            CURLOPT_FOLLOWLOCATION => true,        
            CURLOPT_ENCODING       => "",       	
            CURLOPT_USERAGENT      => "Mozilla/5.0 (Sage)",  
            CURLOPT_AUTOREFERER    => true,        
            CURLOPT_CONNECTTIMEOUT => 60,           
            CURLOPT_TIMEOUT        => 60,         
            CURLOPT_MAXREDIRS      => 5,        
            CURLOPT_HTTPHEADER     => array('Content-type: text/html; charset=utf-8', 'Accept-Language: de')
			);

		$ch      = curl_init( $url );
		curl_setopt_array( $ch, $options );
		$content = curl_exec( $ch );
		$err     = curl_errno( $ch );
		$errmsg  = curl_error( $ch );
		$header  = curl_getinfo( $ch );
		curl_close( $ch );

		$header['errno']   = $err;
		$header['errmsg']  = $errmsg;
		$header['content'] = $content;
		return htmlentities($header['content']);
	}


$url = " http://xxx.rss ";
$feed = GetSource($url);

$feed = str_replace("content:encoded", "description", $feed);
$feed = preg_replace("/<dc(.*?)<\/dc(.*?)>/im", "", $feed);
//... weitere Anweisungen gekürzt.

echo $feed;
?>

Wenn ich aber nun den Code als rss.php auf meinen Webspace speichere und aufrufe, dann zeigt er nicht wie gewünscht den Feed, sondern bietet mir einen Dateidownload an.
Wenn ich die Datei herunterlade und anschaue, dann fängt die wie folgt an:
<?xml version="1.0" encoding="UTF-8"?>
Eigentlich sollte es doch aber so ausschauen: <?xml version="1.0" encoding="UTF-8"?>

Ich verstehe nicht, warum der Webbrowser den neuen Code nicht richtig interpretiert.
Denn mit der Zeile header("Content-type: application/rss+xml; charset=utf-8"); müsste der Webbrowser das ganze doch richtig interpretieren. Dies hat ja beim alten Code auch funktioniert.

Das einzige was mir noch einfallen würde wäre, mit
$feed = str_replace("<", "<", $feed);
alles wieder in html Code umzuschreiben.
Aber dann müsste ich dies für alle möglichen html Codes machen.
Mal abgesehen davon, dass das php Skript dann mehr arbeiten muss, würde es dadurch auch wieder größer und unleserlicher.

Der Code, so wie er oben steht, war jetzt für heute mein letzter Versuch.
Ich habe schon alles Mögliche ausprobiert, aber wie schon gesagt, ich weiß einfach nicht wo mein Denkfehler ist. :confused:
Das Problem ist immer das gleiche.
Irgendwie bzw. irgendwo wandelt er die HMTL Befehle in reinen Text um. Und ich weiß nicht wo, bzw. warum.

Ich würde mich sehr freuen, wenn mir jemand helfen könnte.

Vielen Dank schon mal.
 
Super. Vielen Dank.
Ohne htmlentities funktioniert es.
Danke schön. :D

Ohne header("Content-type: application/rss+xml; charset=utf-8"); funktioniert es zwar ebenfalls, aber der W3C Feed Validator bringt dann folgende "Fehlermeldungen":
#Feeds should not be served with the "text/html" media type
#Your feed appears to be encoded as "UTF-8", but your server is reporting "US-ASCII"

Nur das Wörtchen htmlentities löschen, und schon funktioniert es.
Und ich war da 2 Stunden davor gesessen, und habs einfach nicht geschafft.

Vielen Dank für eure Hilfe.
Jetzt ist mein Abend doch noch gerettet. ^^
 
Zurück
Oben