Предположим, я хочу, чтобы XML-файлы загружались только с до 10 МБ с удаленного сервера.
Что-то вроде
$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'*/);
Как это может быть достигнуто? …. Любая идея или альтернатива? или наилучший подход к достижению этой цели будет высоко оценен.
Я проверил PHP: Удаленный размер файла без загрузки файла, но когда я пытаюсь с чем-то вроде
var_dump( curl_get_file_size( "http://www.dailymotion.com/rss/user/dialhainaut/" ) );
Я получаю string 'unknown' (length=7)
Когда я пытаюсь использовать get_headers
как предлагается ниже, Content-Length отсутствует в заголовках, так что это не будет работать надежно.
Пожалуйста, сообщите, как определить length
и не отправлять ее в DOMDocument
если она превышает 10MB
Хорошо, наконец, работаем. Решение заголовков, очевидно, не будет работать в целом. В этом решении мы открываем дескриптор файла и читаем XML по строкам, пока не достигнем порога $ max_B. Если файл слишком большой, у нас все еще есть накладные расходы на его чтение до отметки 10 МБ, но он работает так, как ожидалось. Если файл меньше $ max_B, он продолжается …
$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!'; }
10MB равно 10485760 B. Если длина контента не указана, она будет использовать завиток, доступный с php5. Я получил этот источник откуда-то в SO, но не мог его запомнить.
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'; }
,
Проверьте демо здесь
Изменить: Новый Ответ немного обход:
Вы не можете проверить Dom Elements Length, НО, вы можете сделать запрос заголовка и получить размер файла из URL:
<?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; } ?>
Теперь вы можете получить каждый размер файла по URL-адресу только с помощью
$file_size = i_hope_this_works('yourURLasString')