2016-07-26 17 views
3

Was ich versuche zu erreichen: zu einer API Endpoint
Get-Anfrage, eine XML-Abrufen und anschließend die Ergebnisse zu analysieren.
Ich sende eine file_get_contents Anfrage, um dies zu erreichen.file_get_contents nicht über php, funktioniert über Browser

Probleme:

`file_get_Contents` fails, error: 

Warning: file_get_contents(https://api.twitter.com/1.1/statuses/mentions_timeline.json): 
failed to open stream: 
     A connection attempt failed because the connected party did not properly 
respond after a period of time, or established connection failed because 
connected host has failed to respond. 

aktualisieren 17/08

Um mein gegenwärtiges Verständnis zu konsolidieren:
1. PHP VERFEHLT:
1.a es nicht über PHP (Timeout)
1.b es über die Befehlszeile fehlschlägt (curl -G http://api.eve-central.com/api/quicklook?typeid=34)
1.c file_get_contents
1.d file_get_contents w/create_stream_context

2. Was funktioniert:
2.a Einfügen der URL in einem Chrom-Tab
2.b über Postbote

Was wurde versucht: - Header in Postman überprüfen und versuchen, sie über php

Postman Headers sent back by eve-central: 
Access-Control-Allow-Origin → * 
Connection → Keep-Alive 
Content-Encoding → gzip 
Content-Type → text/xml; charset=UTF-8 
Date → Wed, 17 Aug 2016 10:40:24 GMT 
Proxy-Connection → Keep-Alive 
Server → nginx 
Transfer-Encoding → chunked 
Vary → Accept-Encoding 
Via → HTTP/1.1 proxy10014 
zu replizieren

Entsprechender Code:

$headers = array(  
'method' => 'GET',   
'header' => 'Connection: Keep-Alive', 
'header' => 'Content-Encoding: gzip', 
'header' => 'Content-Type: text/xml', 
'header' => 'Proxy-Connection: Keep-Alive', 
'header' => 'Server: nginx', 
'header' => 'Transfer-Encoding: chunked', 
'header' => 'Vary: Accept-Encoding', 
'header' => 'Via: HTTP/1.1 proxy10014'); 
curl_setopt($curl, CURLOPT_HTTPHEADER, $headers); 
curl_setopt($curl, CURLOPT_RETURNTRANSFER, true); 
curl_setopt($curl, CURLOPT_PORT , 8080); // Attempt at changing port in the event it was blocked. 
curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, false); 
curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, false); 
curl_setopt($curl, CURLOPT_POST,   false);    
curl_setopt($curl, CURLOPT_URL,   $url); 

$resp = curl_exec($curl); 
if(curl_error($curl)) 
{ 
echo 'error:' . curl_error($curl); 
} 
  • Verwenden Wireshark die GET-Anforderung zu erfassen, wenn die Änderung der Port half
  • Run cUrl über die Kommandozeile
    ich aus Ideen und Option bin zu sehen. So sind die Fragen:
    1. Wenn es in einem Browser funktioniert, und in Postman, warum funktioniert es nicht über PHP?
    2. Wie kann ich meinen Code so ändern, dass er nachahmt, was Postman macht? ?

Vorherige Versuche Was ich versucht habe: Verschiedene cURL Optionen von anderen Threads, wie

function curl_get_contents($url) { 
$ch = curl_init(); 
if (!$ch) 
{ 
die("Couldn't initialize a cURL handle"); 
} else 
echo "Curl Handle initialized "; 
curl_setopt($ch, CURLOPT_URL, $url); 
curl_setopt($ch, CURLOPT_USERAGENT, 'Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; .NET CLR 1.1.4322)'); 
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); 
curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 5); 
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false); 
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 0); 
curl_setopt($ch, CURLOPT_TIMEOUT, 5); 
$data = curl_exec($ch); 
// Check if any error occurred 
if (!curl_errno($ch)) 
{ 
$info = curl_getinfo($ch); 
echo 'Took ', $info['total_time'], ' seconds to send a request to ', $info['url'], ""; 
displayData($info); 
} else 
echo "Failed Curl, reason: ".curl_error($ch)." "; 
curl_close($ch); 
return $data; 
} 

Ergebnis: nichts, keine Daten zurückgegeben.
- Überprüft php.ini-Optionen:
- allow_fopen ist an
- allow_url_include = auf
- relevant ssl Erweiterungen aktiviert sind
- das Timeout Fenster Raised
- sowohl über php.ini
- auch über explizite Deklaration innerhalb der PHP-Datei.
- mit einer anderen URL Versuchte
- gleicher Fehler, es tut, hängt also nicht wirklich auf meinem bestimmten Endpunkt
- zum Beispiel, beide twitter/wikipedia/google den spezifischen Fehler zurück - mit versucht:
- file_get_contents auf einer lokalen xML-Datei (https://msdn.microsoft.com/en-us/library/ms762271(v=vs.85).aspx) ->arbeitet
- file_get_contents auf einer Remote-xML-Datei (http://www.xmlfiles.com/examples/note.xml) ->nicht gleiche Fehler
- Insgesamt ist das folgende wahr, so weit:
- Curl-Ausfall Timeout
- file_get_contents ausfällt, Timeout
- Open XML Datei-URL in einem Browser funktioniert
- Machen Sie eine GET-Anfrage über Postman, arbeitet

Offensichtlich, in allen Fällen, in denen die file_get_contents über PHP fehlschlägt, kann ich einfach über jeden Browser auf die Datei zugreifen.

Versucht, das Problem zu umgehen.
Versuch 1:
Verwenden Sie nitrous.io, erstellen Sie einen LAMP-Stapel, führen Sie die Tat über die Plattform Ergebnisse: file_get_contents funktioniert jedoch aufgrund der großen Anzahl von XML-Dateien abgerufen werden, die Operation-Time-Out. Vorläufiger Lösung:
- Download-XML-Dateien von der Quelle
- Zip sie
- Herunterladen xml_datei
- lokal Parse die XML-Dateien
Später, ein kleines PHP-Skripte schreiben, die, wenn sie aufgerufen, über die Bits durchführt, sendet die Daten an das lokale Verzeichnis, das sie dann entpackt und zusätzliche Arbeit daran ausführt.
Ein weiterer Versuch wäre, Google Tabellen zu verwenden, mit einer Benutzerfunktion, die die Daten in das Blatt zieht und einfach die Excel-Datei/Werte in mysql ablegt.
Für meine Zwecke, während eine schrecklich unwissende Lösung, tut es den Trick.

-Code zur Vermeidung von Timeout-Problem auf Shared Host verwendet:

function downloadUrlToFile2($url, $outFileName) 
{ 
    //file_put_contents($xmlFileName, fopen($link, 'r')); 
    //copy($link, $xmlFileName); // download xml file 
    ; 
    echo "Passing $url into $outFileName "; 
    // $outFileName = touch(); 
    $fp = fopen($outFileName, "w"); 
    if(is_file($url)) 
    { 
     copy($url, $outFileName); // download xml file 
    } else 
     { 
      $ch = curl_init(); 
      $options = array(
      CURLOPT_TIMEOUT => 28800, // set this to 8 hours so we dont timeout on big files 
      CURLOPT_URL  => $url 
     ); 

      curl_setopt($ch, CURLOPT_FILE, $fp); 
      curl_setopt_array($ch, $options); 
      $contents = curl_exec($ch); 
      fwrite($fp, $contents); 
      curl_close($ch); 
     } 
} 

ich auch diese auf dem ini Skript hinzugefügt haben:

ignore_user_abort(true); 
set_time_limit(0); 
ini_set('memory_limit', '2048M'); 
+0

Sie versuchen, Daten abzurufen, ohne eine Authentifizierung zu tun Icing-Mechanismus. Warum versuchst du nicht einen der PHP Wrapper für Twitter? https: //dev.twitter.com/overview/api/twitter-libraries – Nikhil

+0

danke für deine antwort. Twitter URL war nur eine der zufälligen URLs, die verwendet wurden, um verschiedene Optionen auszuprobieren. Die Ergebnisse ändern sich nicht, wenn Sie eine Datei_Get_Contents ($ url) erstellen, wobei $ URL wie folgt lautet: http://www.xmlfiles.com/examples/note.xml. Also, wie Sie von dieser URL sehen können, ist es ein einfaches xml, mit keine Authentifizierung erforderlich, noch immer mit dem Timeout-Fehler fehlschlägt. – user3375601

+0

Wo läuft der Code? Haben Sie gehackt, dass die Maschine, auf der Sie diese Maschine betreiben, eine direkte Internetverbindung hat? (Ein Server sitzt möglicherweise hinter einem Preverse-Proxy) Dass er Namen auflösen kann? Dass es keine Firewall gibt, die diesen Zugriff verhindert? Dass es nicht durch einen anderen Sicherheitsmechanismus eingeschränkt wird? Hast du die Protokolle überprüft? Es ist üblich, Webserver-Hosts zu konfigurieren, um zu verhindern, dass sie aus Sicherheitsgründen ausgehende Verbindungen über das Internet herstellen (und dies ist der Standard mit der SELinux-Richtlinie von Redhat). – symcbean

Antwort

3

Ich sehe einige Problem mit der HTTPS-URL Anfrage, Problem behoben, dass Sie unter Zeilen in Ihrer CURL-Anfrage hinzufügen müssen

function curl_get_contents($url) { 
    $ch = curl_init(); 
    $header[0] = "Accept: text/xml,application/xml,application/xhtml+xml,"; 
    $header[0] .= "text/html;q=0.9,text/plain;q=0.8,image/png,*/*;q=0.5"; 
    $header[] = "Cache-Control: max-age=0"; 
    $header[] = "Connection: keep-alive"; 
    $header[] = "Keep-Alive: 300"; 
    $header[] = "Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.7"; 
    $header[] = "Accept-Language: en-us,en;q=0.5"; 
    $header[] = "Pragma: "; 
    curl_setopt($ch, CURLOPT_HTTPHEADER, $header); 

    curl_setopt($ch, CURLOPT_HEADER, 0); 
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); 
    curl_setopt($ch, CURLOPT_URL, $url); 

    // I have added below two lines 
    curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false); 
    curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 0); 

    $data = curl_exec($ch); 
    curl_close($ch); 

    return $data; 
} 
+1

Danke dafür. Ich habe Ihr Feedback aufgenommen und einige weitere Fehler eingefügt: Fügt den Code zum ursprünglichen Block hinzu. Was interessant ist, ist, dass die Locke auch Timeouts: Erste Inhalte von http://www.xmlfiles.com/examples/note.xml Locken Griff Fehlgeschlagen Curl Grund initialisiert: Verbindung nach 5008 Millisekunden Zeitüberschreitung – user3375601