PHP写的资源下载防盗链类分享
这几天在写一个php防盗链外部资源下载处理函数,昨天晚上刚完成编写,中间遇到了些问题,这里就不详述了;
以下是自写的简单的php防盗链处理类(重新整理编写成类文件,以便后期改进);
<?php
/**
*
* 防盗链外部资源下载处理类
*
* @link http://jb51.net
*
*/
class burglardow{
/**
* 初始许可下载状态
* @var allow
* @access private
*/
private $allow = false;
/**
* 初始下载地址
* @var dowurl
* @access private
*/
private $dowurl = null;
/**
* 初始来路域名
* @var remoteurl
* @access private
*/
private $remoteurl = null;
/**
* 初始许可资源取用域名列表
* @var allowurl
* @access private
*/
private $allowurl = array();
/**
* 初始转跳地址
* @var location
* @access private
*/
private $location = null;
public function __construct($dowurl,$location,array $allowurl){
// 初始下载地址
$this->dowurl = $dowurl;
// 初始许可资源取用域名列表
$this->allowurl = $allowurl;
// 初始转跳地址
$this->location = $location;
$this->remoteurl = @parse_url($_server['http_referer']); // 获取来路域名
if(!is_array($this->remoteurl))
header("http/1.1 301 moved permanently");
header("location: ".$this->location);
if(isset($this->remoteurl['host'])){
if(in_array($this->remoteurl['host'],$this->allowurl)){ // 判断是否来至许可域名
$this->allow = true; // 下载许可状态为:真
}
}
unset($this->allowurl,$this->remoteurl); // 释放内存变量
}
/**
* 防盗链资源下载
* @access public
* @return mixed
*/
public function dow(){
$fileinfo = get_headers($this->dowurl,1); // 获取远程文件头部信息
if(true === $this->allow){ // 判断是否许可下载资源
//判断配置文件是否存在
if(is_file('config.ini')){
$filecon = parse_ini_file('config.ini');
}else{
$filename = basename($fileinfo['content-location']);
$fileconstr = "filename = {$filename}\r\nfileurl = {$fileinfo['content-location']}\r\nfilesize = {$fileinfo['content-length']}";
$handle = fopen ('config.ini', "wb"); // config.ini文件不存在则创建文件
if (fwrite ($handle, $fileconstr) == false) { // 数据写入文件
echo "file creation failed ...";
}
fclose ($handle); // 关闭一个已打开的文件指针
$filecon = parse_ini_file('config.ini');
}
if(!empty($$this->dowurl)){
$fp = @fopen($$this->dowurl, "rb"); // 二进制模式读取文件
if (!$fp)
exit("download a mistake.\n\n");
// 输出远程资源
header("content-type:text/html;charset=utf-8");
header('content-description: file transfer');
header('content-type: application/octet-stream');
header('content-disposition: attachment; filename='.$filecon['filename']);
header("accept-ranges: bytes");
header('content-transfer-encoding: binary');
header('expires: 0');
header('cache-control:must-revalidate,post-check=0,pre-check=0');
header('pragma: public');
header('content-length: '.$filecon['filesize']);
while (!feof($fp)){
set_time_limit(0); // 设置文件最长执行时间
echo fread($fp, 1024); // 输出文件
flush(); // 输出缓冲
ob_flush(); // 输出缓冲区中的内容
}
fclose($fp);
}else{
header("http/1.1 404 not found");
}
}else{
header("http/1.1 301 moved permanently");
header("location: ".$this->location);
}
}
}
// 远程资源地址
$dowurl = 'http://dldir1.qq.com/qqfile/qq/qq5.1/10055/qq5.1.exe';
// 转跳地址
$location = 'http://jb51.net';
// 许可来路域名列表
$allowurl = array(
'jb51.net',
);
$burglardow = new burglardow($dowurl,$location,$allowurl);
$burglardow -> dow();