Php 如果文件大于给定大小,则阻止从远程源加载
比方说,我希望从远程服务器加载最多10MB的XML文件 差不多Php 如果文件大于给定大小,则阻止从远程源加载,php,domdocument,filesize,Php,Domdocument,Filesize,比方说,我希望从远程服务器加载最多10MB的XML文件 差不多 $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 d
$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'*/);
var_dump(
curl_get_file_size(
"http://www.dailymotion.com/rss/user/dialhainaut/"
)
);
我得到字符串“未知”(长度=7)
当我尝试使用下面建议的get_headers
时,标题中缺少内容长度,因此这也无法可靠地工作
请告知如何确定
长度
,如果长度超过10MB,请避免将其发送到DOMDocument
,编辑:新答案有点变通方法:
您不能检查Dom元素的长度,但可以发出头请求并从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;
}
?>
10MB等于10485760 B。如果未指定内容长度,则将使用自php5起可用的卷曲。我从某处得到这个消息来源,但我记不起来了
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';
}
函数get_filesize($url){
$headers=get_headers($url,1);
if(isset($headers['Content-Length'])返回$headers['Content-Length'];
if(isset($headers['Content-length'])返回$headers['Content-length'];
$c=curl_init();
curl_setopt_数组($c,数组)(
CURLOPT_URL=>$URL,
CURLOPT_RETURNTRANSFER=>true,
CURLOPT_HTTPHEADER=>array('User-Agent:Mozilla/5.0
(麦金塔;美国;英特尔Mac OS X 10.5;欧洲;rv:1.9.1.3)
Gecko/20090824 Firefox/3.5.3',
));
首席执行官(c美元);
返回curl\u getinfo($c,CURLINFO\u SIZE\u下载);
}
}
$filesize=获取文件大小(“http://www.dailymotion.com/rss/user/dialhainaut/");
如果($filesizeOk,终于起作用了。headers解决方案显然不能广泛地起作用。在这个解决方案中,我们打开一个文件句柄,逐行读取XML,直到它达到$max_B的阈值。如果文件太大,我们仍然有读到10MB标记的开销,但它可以按预期工作。如果文件小于$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!';
}
$xml\u文件=”http://www.dailymotion.com/rss/user/dialhainaut/";
//$xml_文件=”http://www.cs.washington.edu/research/xmldatasets/data/pir/psd7003.xml";
$fh=fopen($xml_文件,“r”);
若有($fh){
$file_string='';
$total_B=0;
$max_B=10485760;
//遍历文件的行,将它们连接成字符串
而(!feof($fh)){
如果($line=fgets($fh)){
$total_B+=斯特伦(行);
如果($total_B<$max_B){
$file_string.=$line;
}否则{
打破
}
}
}
如果($total_B<$max_B){
echo“文件正常。总大小=”.$Total_B.“字节。正在进行…”;
//进行
$dom=新的DOMDocument();
$dom->loadXML($file_string);//注意方法的更改,因为我们是从字符串加载的
}否则{
//拒绝
echo“文件太大!最大大小=”.$Max_B.“字节”;
}
fclose($fh);
}否则{
echo“找不到404文件!”;
}
你看过函数了吗?@MawiaHL你能试试吗:var\u dump(filesize(“http://www.cs.washington.edu/research/xmldatasets/data/pir/psd7003.xml“”)
Page not found是结果。@MawiaHL--这将在浏览器中加载:……但不适用于var\u dump(filesize)中的filesize()
('https://www.w3.org/TR/2001/REC-xsl-20011015/xslspec.xml'))
@downvorters….请告知问题的症结所在。谢谢!结果:警告:第5行的C:\…\fileSize\u tst\index.php中的字符串偏移量'size'非法。
大小的值是什么?大小未知……可以是任何大小……但不能是>10MB
。文件来自远程服务器。。(请再读一题)我的意思是变量中有什么size@johannes--文件未被上载
它已上载到其他服务器的某个位置,我们只想使用DOMDocument
读取它,但我们想停止读取…或…**根本不读取**如果其大小超过10MB
…即:像:http://www.cs.washington.edu/research/xmldatasets/data/pir/psd7003.xmlhttp://www.cs.washington.edu/research/xmldatasets/data/SwissProt/SwissProt.xml
你太过分了large@MawaiHL--我们已经尝试过了,在它在这个XML上使用失败之前:$head=array\u change\u key\u case(get\u headers("http://www.dailymotion.com/rss/user/dialhainaut/“,TRUE”);
标题不包括内容长度
…请尝试通知。Thx@ErickBest, ut/不返回任何内容。它只返回页面未找到您要查找的页面受限制或不存在
。因此,当文件根本不存在时,如何知道文件的大小。--请在Web浏览器中尝试此操作:@Mawia HL…是的…已确认…,工作正常…(希望我能有两个可接受的答案)@ErickBest,使用我的答案比使用公认答案的优势在于,某些主机提供程序禁用了fopen()函数。在Windows Web服务器上,当使用fopen并将文件路径存储在变量中时,如果变量未以ASCII编码,PHP将返回错误。当使用SSL时,Microsoft IIS将违反协议,关闭连接而不发送close_notify指示符。因此Curl更好。使用:file_get_Content测试时会崩溃新界北http://www.cs.washington.edu/research/xmldatasets/data/pir/psd7003.xml");size//683MB
…善意地建议Script Hanged必须重新启动服务器…文件获取内容
试图在其正常工作之前将整个683MB
加载到内存中。是的,我们正在与单个变量的最大大小发生冲突。这是php.ini中的内存限制设置。我们需要一个更好的解决方案-一个这可以在不加载整个内容的情况下测试文件。太棒了!感谢您的挑战-这肯定是当今最有趣的问题。我仍然会检查标题是否在那里,因为如果在那里,这将为我们节省潜在的麻烦
$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!';
}