2016-04-21 3 views
2

Angenommen, ich möchte XML-Dateien nur mit bis zu 10 MB von einem Remote-Server geladen werden.Verhindern Laden von Remote-Quelle, wenn Datei größer als eine gegebene Größe ist

So etwas wie

$xml_file = "http://example.com/largeXML.xml";// size= 500MB 

//PRACTICAL EXAMPLE: $xml_file = "http://www.cs.washington.edu/research/xmldatasets/data/pir/psd7003.xml";// size= 683MB 

/*GOAL: Do anything that can be done to hinder this large file from being loaded by the DOMDocument without having to load the File n check*/ 

$dom = new DOMDocument(); 

$dom->load($xml_file /*LOAD only IF the file_size is <= 10MB....else...echo 'File is too large'*/); 

Wie kann das möglicherweise? Erreicht werden .... Jede Idee oder Alternative? oder der beste Ansatz, um dies zu erreichen, würde sehr geschätzt werden.

checkte ich PHP: Remote file size without downloading file aber wenn ich mit etwas versuchen, wie

var_dump(
    curl_get_file_size(
     "http://www.dailymotion.com/rss/user/dialhainaut/" 
    ) 
); 

ich string 'unknown' (length=7)

Wenn ich mit get_headers versuchen, wie unten vorgeschlagen, der Content-Length im Header fehlt, so dass dieser Wille funktioniert auch nicht zuverlässig.

Bitte raten Sie freundlich, wie die length zu bestimmen und vermeiden, dass es zu dem DOMDocument senden, wenn es 10MB überschreitet

+0

Haben Sie sich die Funktion [filesize()] (http://php.net/manual/en/function.filesize.php) angesehen? –

+0

@MawiaHL Können Sie versuchen: 'var_dump (filesize (" http://www.cs.washington.edu/research/xmldatasets/data/pir/psd7003.xml "))' – ErickBest

+0

Seite nicht gefunden ist das Ergebnis. –

Antwort

2

Ok, schließlich arbeiten. Die Header-Lösung würde offensichtlich nicht funktionieren. In dieser Lösung öffnen wir ein Datei-Handle und lesen das XML Zeile für Zeile, bis es den Grenzwert von $ max_B erreicht. Wenn die Datei zu groß ist, haben wir immer noch den Aufwand, sie bis zur 10-MB-Marke zu lesen, aber sie funktioniert wie erwartet. Wenn die Datei kleiner als $ max_B ist, wird fortgefahren ...

$xml_file = "http://www.dailymotion.com/rss/user/dialhainaut/"; 
//$xml_file = "http://www.cs.washington.edu/research/xmldatasets/data/pir/psd7003.xml"; 

$fh = fopen($xml_file, "r"); 

if($fh){ 
    $file_string = ''; 
    $total_B = 0; 
    $max_B = 10485760; 
    //run through lines of the file, concatenating them into a string 
    while (!feof($fh)){ 
     if($line = fgets($fh)){ 
      $total_B += strlen($line); 
      if($total_B < $max_B){ 
       $file_string .= $line; 
      } else { 
       break; 
      } 
     } 
    } 

    if($total_B < $max_B){ 
     echo 'File ok. Total size = '.$total_B.' bytes. Proceeding...'; 
     //proceed 
     $dom = new DOMDocument(); 
     $dom->loadXML($file_string); //NOTE the method change because we're loading from a string 

    } else { 
     //reject 
     echo 'File too big! Max size = '.$max_B.' bytes.'; 
    } 

    fclose($fh); 

} else { 
    echo '404 file not found!'; 
} 
+0

Dieser Absturz beim Test mit: 'file_get_contents (" http://www.cs.washington.edu/research/xmldatasets/data/pir/psd7003.xml "); Größe // 683MB '... Bitte geben Sie – ErickBest

+0

einen Timeout-Absturz an? – larsAnders

+0

Script Hanged musste den Server neustarten ... 'file_get_contents' versucht die gesamte' 683 MB' in den Speicher zu laden, bevor sie bearbeitet wurde – ErickBest

-1

Edit: Neue Antwort ein bisschen workaroundish:
Sie nicht den Dom Elements Länge überprüfen, aber Sie kann einen Kopf Antrag stellen und die Dateigröße aus der URL erhalten:

<?php 

function i_hope_this_works($XmlUrl) { 
    //lets assume we fk up so we set size to -1 
    $size = -1; 

     $request = curl_init($XmlUrl); 

     // Go for a head request, so the body of a 1 gb file will take the same as 1 kb 
     curl_setopt($request, CURLOPT_NOBODY, true); 
     curl_setopt($request, CURLOPT_HEADER, true); 
     curl_setopt($request, CURLOPT_RETURNTRANSFER, true); 
     curl_setopt($request, CURLOPT_FOLLOWLOCATION, true); 
     curl_setopt($request, CURLOPT_USERAGENT, get_user_agent_string()); 

     $requesteddata = curl_exec($request); 
     curl_close($request); 

     if($requesteddata) { 
     $content_length = "unknown"; 
     $status = "unknown"; 

     if(preg_match("/^HTTP\/1\.[01] (\d\d\d)/", $requesteddata, $matches)) { 
      $status = (int)$matches[1]; 
     } 

     if(preg_match("/Content-Length: (\d+)/", $requesteddata, $matches)) { 
      $content_length = (int)$matches[1]; 
     } 

     // you can google status qoutes 200 is Ok for example 
     if($status == 200 || ($status > 300 && $status <= 308)) { 
      $result = $content_length; 
     } 
     } 

     return $result; 
    } 
    ?> 

Sie sollten jetzt alle Dateigröße Sie wollen von URL Lage sein, nur mit

$file_size = i_hope_this_works('yourURLasString') 
+0

ERGEBNIS: 'Warnung: Illegale String-Offset 'Größe' in C: \ ..... \ fileSize_tst \ index.php auf Zeile 5 ' – ErickBest

+0

Was ist der Wert der Größe? –

+0

Die Größe ist unbekannt .... kann jede Größe sein .... aber muss nicht '> 10MB' sein ... die Datei kommt von einem Remote-Server ..(Bitte lesen Sie die Frage mehr) – ErickBest

1

10MB ist gleich 10485760 B. Wenn content-length nicht angegeben ist, wird curl verwendet, das seit php5 verfügbar ist. Ich habe diese Quelle von irgendwo in SO aber konnte mich nicht erinnern:

function get_filesize($url) { 
    $headers = get_headers($url, 1); 
    if (isset($headers['Content-Length'])) return $headers['Content-Length']; 
    if (isset($headers['Content-length'])) return $headers['Content-length']; 
    $c = curl_init(); 
    curl_setopt_array($c, array(
     CURLOPT_URL => $url, 
     CURLOPT_RETURNTRANSFER => true, 
     CURLOPT_HTTPHEADER => array('User-Agent: Mozilla/5.0 
     (Macintosh; U; Intel Mac OS X 10.5; en-US; rv:1.9.1.3) 
      Gecko/20090824 Firefox/3.5.3'), 
     )); 
    curl_exec($c); 
    return curl_getinfo($c, CURLINFO_SIZE_DOWNLOAD); 
    } 
} 
    $filesize = get_filesize("http://www.dailymotion.com/rss/user/dialhainaut/"); 
    if($filesize<=10485760){ 
     echo 'Fine'; 
    }else{ 
     echo $filesize.'File is too big'; 
    }  

.

Check demo here

+0

@Mawai HL --- Wir haben das versucht, bevor es fehlschlägt, wenn verwendet für dieses XML: '$ head = array_change_key_case (get_headers (" http://www.dailymotion.com/rss/user/dialhainaut/ ", TRUE));' Die Header enthalten keine 'Content-Length' ... Bitte versuchen Sie es nicht. Thx – ErickBest

+0

@ErickBest, http://www.dailymotion.com/rss/user/dialhaina ut/gibt nichts zurück. Es gibt nur 'Seite nicht gefunden Die gesuchte Seite ist entweder eingeschränkt oder existiert nicht '. Wie kann jemand die Größe der Datei wissen, wenn sie überhaupt nicht existiert? –

+0

- Bitte versuchen Sie dies im Web-Browser: http://www.dailymotion.com/rss/user/dialhainaut/ – ErickBest

Verwandte Themen