PHP文件与图片防盗链处理类

 更新时间:2016年11月25日 15:42  点击:1888
防盗链就是对一些文件资源进行包装了,这样对方是看不到我们文件源地址了,下载是也是php文件打开了,下载成功之后就成了要下载的文件了,下面我来给各位分享一站长写的类。

悲剧,刚提交的既然服务器挂了没成功,又得重写....

这几天在写一个PHP防盗链外部资源下载处理函数,昨天晚上刚完成编写,中间遇到了些问题,这里就不详述了;

以下是自写的简单的PHP防盗链处理类(重新整理编写成类文件,以便后期改进);

 代码如下 复制代码

<?php 

002 /** 

003  * 

004  * 防盗链外部资源下载处理类 

005  *  

006  * @author 清风 <xrcc_bk@126.com> 

007  * @link   http://blog.emtalk.net 

008  *  

009  */

010 class BurglarDow{ 

011     /** 

012      * 初始许可下载状态 

013      * @var    allow 

014      * @access private 

015      */

016     private $allow      =  false; 

017     /** 

018      * 初始下载地址 

019      * @var    dowUrl 

020      * @access private 

021      */

022     private $dowUrl     =  null; 

023     /** 

024      * 初始来路域名 

025      * @var    RemoteUrl 

026      * @access private 

027      */

028     private $RemoteUrl  =  null; 

029     /** 

030      * 初始许可资源取用域名列表 

031      * @var    allowUrl 

032      * @access private 

033      */

034     private $allowUrl   =  array(); 

035     /** 

036      * 初始转跳地址 

037      * @var    Location 

038      * @access private 

039      */

040     private $Location   =  null; 

041   

042     public function __construct($dowUrl,$Location,array $allowUrl){ 

043         // 初始下载地址 

044         $this->dowUrl   = $dowUrl; 

045         // 初始许可资源取用域名列表 

046         $this->allowUrl = $allowUrl; 

047         // 初始转跳地址 

048         $this->Location = $Location; 

049   

050         $this->RemoteUrl = @parse_url($_SERVER['HTTP_REFERER']);                                                      // 获取来路域名 

051         if(!is_array($this->RemoteUrl)) 

052             header("HTTP/1.1 301 Moved Permanently"); 

053             header("Location: ".$this->Location); 

054   

055         if(isset($this->RemoteUrl['host'])){ 

056             if(in_array($this->RemoteUrl['host'],$this->allowUrl)){                                                   // 判断是否来至许可域名 

057                 $this->allow  = true;                                                                                 // 下载许可状态为:真 

058             } 

059         } 

060         unset($this->allowUrl,$this->RemoteUrl);                                                                      // 释放内存变量 

061     } 

062   

063     /** 

064      * 防盗链资源下载 

065      * @access public 

066      * @return mixed 

067      */

068     public function dow(){ 

069         $FileInfo = get_headers($this->dowUrl,1);                                                                     // 获取远程文件头部信息 

070   

071         if(true === $this->allow){                                                                                    // 判断是否许可下载资源 

072             //判断配置文件是否存在 

073             if(is_file('Config.ini')){ 

074                 $FileCon = parse_ini_file('Config.ini'); 

075             }else{ 

076                 $FileName   =  basename($FileInfo['Content-Location']); 

077                 $FileConStr = "FileName  = {$FileName}rnFileUrl   = {$FileInfo['Content-Location']}rnFileSize   = {$FileInfo['Content-Length']}"; 

078                 $handle = fopen ('Config.ini', "wb");                                                                 // Config.ini文件不存在则创建文件 

079                 if (fwrite ($handle, $FileConStr) == FALSE) {                                                         // 数据写入文件  

080                     echo "File creation failed ...";  

081                 } 

082                 fclose ($handle);                                                                                     // 关闭一个已打开的文件指针 

083                 $FileCon = parse_ini_file('Config.ini'); 

084             } 

085             if(!empty($$this->dowUrl)){ 

086                 $fp = @fopen($$this->dowUrl, "rb");                                                                   // 二进制模式读取文件 

087                 if (!$fp) 

088                      exit("Download a mistake.nn"); 

089   

090                 // 输出远程资源 

091                 header("Content-type:text/html;charset=utf-8"); 

092                 header('Content-Description: File Transfer'); 

093                 header('Content-Type: application/octet-stream'); 

094                 header('Content-Disposition: attachment; filename='.$FileCon['FileName']); 

095                 header("Accept-Ranges: bytes"); 

096                 header('Content-Transfer-Encoding: binary'); 

097                 header('Expires: 0'); 

098                 header('Cache-Control:must-revalidate,post-check=0,pre-check=0'); 

099                 header('Pragma: public'); 

100                 header('Content-Length: '.$FileCon['FileSize']); 

101                 while (!feof($fp)){ 

102                     set_time_limit(0);                                                                                 // 设置文件最长执行时间 

103                     echo fread($fp, 1024);                                                                             // 输出文件 

104                     flush();                                                                                           // 输出缓冲 

105                     ob_flush();                                                                                        // 输出缓冲区中的内容 

106                 } 

107                 fclose($fp); 

108             }else{ 

109                 header("HTTP/1.1 404 Not Found"); 

110             } 

111         }else{ 

112             header("HTTP/1.1 301 Moved Permanently"); 

113             header("Location: ".$this->Location); 

114         } 

115     } 

116 } 

117 // 远程资源地址 

118 $dowUrl = '/qq/QQ5.1/10055/QQ5.1.exe'; 

119 // 转跳地址 

120 $Location = 'http://www.111cn.net'; 

121 // 许可来路域名列表 

122 $allowUrl = array( 

123     'blog.emtalk.net', 

124 ); 

125 $BurglarDow = new BurglarDow($dowUrl,$Location,$allowUrl); 

126 $BurglarDow -> dow();


有何不足之处,还望访友们多指点指点;

表单可以把自己定义成数组形式,这样我们就能利用post接收用户多选过来的值了,下面一聚教程小编给各位整理了几个例子。

今天写php的时候发现$_POST["arr"]无法获取参数arr的数组,记录一下。

例如有以下表单需要提交:

 代码如下 复制代码

  <input type="checkbox" name="arr" value="" />
  <input type="checkbox" name="arr" value="" />
  <input type="checkbox" name="arr" value="" />
  <input type="checkbox" name="arr" value="" />

使用$_POST["arr"]只能获得最后选择的复选框的值,要获得全部选中的复选框的值需要把表单修改成下面:

 代码如下 复制代码

  <input type="checkbox" name="arr[]" value="" />
  <input type="checkbox" name="arr[]" value="" />
  <input type="checkbox" name="arr[]" value="" />
  <input type="checkbox" name="arr[]" value="" />

这样就可以使用$_POST["arr"]获得全部选中的checkbox的值,那这样获取值了我们要怎么解析出来呢。

第一中方法

 代码如下 复制代码

<form action="test1.php" method="post">
<?
for($i=0;$i<10;$i++){
?>
<input type="checkbox" name="interests[](不能去掉[])" value="<?=$i?>">test<?=$i?><br>
<?
}
?>
<input type="submit">
</form>

test1.php

<?php
foreach($_POST as $key => $val){
if(is_array($val)){
   foreach($val as $v2){
    echo "$v2<br>";
   }
}
}

?>

第二种用法

test3.php

 代码如下 复制代码

<?php

if(isset($_POST['submit'])){
$users = $_POST['user'];
foreach($users as $key=>$val){
   echo 'user ',$key,' = ',$val,'<br />';
}
}
?>
<form method="post">
zhangsan <input type="text" name="user[zhangsan]" value="0" /><br />
lisi <input type="text" name="user[lisi]" value="1" /><br />
wangwu <input type="text" name="user[wangwu]" value="2" /><br />
zhaoliu <input type="text" name="user[zhaoliu]" value="3" /><br />
<input type="submit" name="submit" value="提交" />
</form>

session我们多半是保存在服务器中呀,但是今天有一个功能就是需要把session保存在数据库中,这样可以实现同ie多浏览了,下面我们一起来看具体实现例子。

php中session默认的存储方式是硬盘,php也可以改变默认的存储方式。
主要使用到session_set_save_handler方法,下面分享下如何将session保存到MySql数据库中的具体代码。

1.建session表

 代码如下 复制代码
CREATE TABLE `session` (
  `sessionid` varchar(128) NOT NULL,
  `uid` int(11) NOT NULL,
  `data` mediumblob NOT NULL,
  `timestamp` int(11) NOT NULL,
  `ip` varchar(15) NOT NULL,
  PRIMARY KEY  (`sessionid`),
  KEY `time_session` (`timestamp`,`sessionid`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8;

uid 是保留字段

2.自定义session类

 代码如下 复制代码

<?php
class CustomSession{
 private static $db_host="localhost";
 private static $db_user="root";
 private static $db_password="";
 private static $database="session";

 private $conn;

 public static function getInstance(){
  static $instance=null;
  if($instance==null){
   $instance=new CustomSession();
  }

  return $instance;
 }

 public function __construct(){
  session_set_save_handler(
  array($this,"open"),
  array($this,"close"),
  array($this,"read"),
  array($this,"write"),
  array($this,"destroy"),
  array($this,"gc")
  );
 }

 public function __destruct(){
  session_write_close();
 }

 public function open(){
  $this->conn=mysql_connect(CustomSession::$db_host,CustomSession::$db_user,CustomSession::$db_password);
  mysql_select_db(CustomSession::$database,$this->conn);
 }

 public function close(){

  mysql_close($this->conn);
 }

 public function read($id){
  $escaped_id=mysql_escape_string($id);
  $res=$this->query("select * from `session` where `sessionid`='$escaped_id'");
  if($row=mysql_fetch_assoc($res)){
   $this->query("update `session` set `timetamp`=UTC_TIMESTAMP() where `sessionid`='$escaped_id'");
   return $row['data'];
  }
  return "";
 }

 public function write($id,$data){
  $query="replace into `session` (`sessionid`,`data`,`ip`,`timestamp`) values ('%s','%s','%s',UNIX_TIMESTAMP(UTC_TIMESTAMP()))";
  $this->query(sprintf($query,mysql_escape_string($id),mysql_escape_string($data),$_SERVER["REMOTE_ADDR"]));//www.111cn.net
 }

 public function destroy($id){
  $escaped_id=mysql_escape_string($id);
  $res=$this->query("delete from `session` where `id`='$escaped_id'");
  return (mysql_affected_rows($res)==1);
 }

 public function gc($lifetime){
  $this->query("delete from `session` where UNIX_TIMESTAMP(UTC_TIMESTAMP())-`timestamp` > $lifetime");
 }

 public function query($query){
  $res=mysql_query($query,$this->conn);
  return $res;
 }
}

?>

3.测试程序

 代码如下 复制代码

<?php
include('./CustomSession.class.php');

CustomSession::getInstance();

session_start();

$_SESSION['username']='feng';

print_r($_SESSION);

?>

运行测试程序后,查看数据库可以发现session表中已经增加了session记录

在这里我们利用curl实现把本地服务器的文件通过curl发送请求给远程服务器的php文件接受就实现了上传,还一个是利用ftp来上传方法也是php中的curl操作ftp服务器进行上传。

我这里写的是用curl的代码

本地代码如下:

 代码如下 复制代码

<?php
    header('content-type:text/html;charset=utf8');
    $curl = curl_init();
    $data = array('img'=>'@'. dirname(__FILE__).'/img/login.gif');
    curl_setopt($curl, CURLOPT_URL, "http://www.demo.com/uploadimg.php");
    curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
    curl_setopt($curl, CURLOPT_POST, true);
    curl_setopt($curl, CURLOPT_POSTFIELDS, $data);
    $result = curl_exec($curl);
    curl_close($curl);
    echo json_decode($result);
?>

远程服务器接受端代码:

 代码如下 复制代码

<?php
    if($_FILES)
    {
        $filename = $_FILES['img']['name'];
        $tmpname = $_FILES['img']['tmp_name'];
        if(move_uploaded_file($tmpname, dirname(__FILE__).'/img/'.$filename))
        {
            echo json_encode('上传成功');
        }
        else
        {
            $data = json_encode($_FILES);
            echo $data;
        }
    }
?>

例子,同样是利用curl不过这是利用ftp

 代码如下 复制代码

<?php
$localfile = "php_homepage.txt";
$fp = fopen ($localfile, "r");
$arr_ip = gethostbyname(www.111cn.net);
echo $arr_ip;
$ftp = "ftp://".$arr_ip."/public_html/".$localfile; 
$ch = curl_init();
curl_setopt($ch, CURLOPT_VERBOSE, 1);
curl_setopt($ch, CURLOPT_USERPWD, '***:****');
curl_setopt($ch, CURLOPT_URL, $ftp);
curl_setopt($ch, CURLOPT_PUT, 1);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_INFILE, $fp);
curl_setopt($ch, CURLOPT_INFILESIZE, filesize($localfile));
$http_result = curl_exec($ch);
$error = curl_error($ch);
echo $error."<br>";
$http_code = curl_getinfo($ch ,CURLINFO_HTTP_CODE);curl_close($ch);
fclose($fp);
?>

在这里本文章重点来给大家介绍利用google提供的的二维码生成API生成的二维码名片,这个是所有二维码生成插件中最好的一个,好了不多说,直接上代码:


二维条码/二维码可以分为堆叠式/行排式二维条码和矩阵式二维条码。堆叠式/行排式二维条码形态上是由多行短截的一维条码堆叠而成;矩阵式二维条码以矩阵的形式组成,在矩阵相应元素位置上用“点”表示二进制“1”,用“空”表示二进制“0”,“点”和“空”的排列组成代码。

堆叠式/行排式二维条码,如,Code 16K、Code 49、PDF417等。

矩阵式二维码,最流行莫过于QR CODE。

矩阵式二维码存储的数据量更大;可以包含数字、字符,及中文文本等混合内容;有一定的容错性(在部分损坏以后可以正常读取);空间利用率高等。

 代码如下 复制代码

 

<?php
$vname = 'test'; 
$vtel = '13800000000'; 
generateQRfromGoogle($vname,$vtel);

function generateQRfromGoogle($vname,$vtel,$widhtHeight ='150',$EC_level='L',$margin='0')
{
    if($vname&&$vtel){ 
       $chl = "BEGIN:VCARDnVERSION:3.0". //vcard头信息 
       "nFN:$vname". 
       "nTEL:$vtel". 
       "nEND:VCARD"; //vcard尾信息 
       echo '<img src="http://chart.apis.google.com/chart?chs='.$widhtHeight.'x'.$widhtHeight.'&cht=qr&chld='.$EC_level.'|'.$margin.'&chl='.urlencode($chl).'" alt="QR code" widhtHeight="'.$size.'" widhtHeight="'.$size.'"/>';
    }
}
?>

 

php生成网址二维码:

 代码如下 复制代码

<?php
$url = "http://www.google.com.hk";
generateQRfromGoogle($url);

function generateQRfromGoogle($chl,$widhtHeight ='150',$EC_level='L',$margin='0')
{
       echo '<img src="http://chart.apis.google.com/chart?chs='.$widhtHeight.'x'.$widhtHeight.'&cht=qr&chld='.$EC_level.'|'.$margin.'&chl='.urlencode($chl).'" alt="QR code" widhtHeight="'.$size.'" widhtHeight="'.$size.'"/>';
}
?>

例子

 代码如下 复制代码
<?php
/*
* php 生成二维码名片
* api Google
* google api 二维码生成【QRcode可以存储最多4296个字母数字类型的任意文本,具体可以查看二维码数据格式】
* @param string $chl 二维码包含的信息,可以是数字、字符、二进制信息、汉字。不能混合数据类型,数据必须经过UTF-8 URL-encoded.如果需要传递的信息超过2K个字节,请使用POST方式
* @param int $widhtHeight 生成二维码的尺寸设置
* @param string $EC_level 可选纠错级别,QR码支持四个等级纠错,用来恢复丢失的、读错的、模糊的、数据。
*                         L-默认:可以识别已损失的7%的数据
*                         M-可以识别已损失15%的数据
*                         Q-可以识别已损失25%的数据
*                         H-可以识别已损失30%的数据
* @param int $margin 生成的二维码离图片边框的距离
* 二维码名片的格式---vcard
* 格式参考如下:
 BEGIN:VCARD
 VERSION:3.0
 FN:用户名
 TEL;CELL;VOICE:0571-00000000
 TEL;WORK;VOICE:0571-00000000
 TEL;WORK;FAX:0571-00000000
 EMAIL;PREF;INTERNET:361way
 URL:http://www.111cn.net
 orG:361way运维之路
 ROLE:研发部
 TITLE:CTO
 ADR;WORK;POSTAL:杭州市西湖区XXX号;310000
 REV:2014-2-26T08:30:02Z
 END:VCARD
 如果你想更详细的定制所需要的格式,则需要详细的了解vcard的格式标准。
*/
$vcard = array(
 'vname' => '用户名',
 'vtel' => '13800000000',
 'vemail' => 'aaaaa@163.com',
 'vaddress' => '杭州市西湖区',
);
generateQRfromGoogle($vcard);
function generateQRfromGoogle($vcard,$widhtHeight ='150',$EC_level='L',$margin='0')
{
    if($vcard){
       $chl = "BEGIN:VCARDnVERSION:3.0". //vcard头信息
       "nFN:".$vcard['vname'].
       "nTEL:".$vcard['vtel'].
    "nEMAIL:".$vcard['vemail'].
    "nADR:".$vcard['vaddress'].
       "nEND:VCARD"; //vcard尾信息
       echo '<img src="http://chart.apis.google.com/chart?chs='.$widhtHeight.'x'.$widhtHeight.'&cht=qr&chld='.$EC_level.'|'.$margin.'&chl='.urlencode($chl).'" alt="QR code" widhtHeight="'.$size.'" widhtHeight="'.$size.'"/>';
    }
}
?>

如果想实现中间有logo的效果,需要通过另外一个logo小图进行拼接即可。这里只提供一种实现方法,也可以通过QRcode的方式进行生成。

vcode的标准信息可以参看维基百科 。

注:有些生成的图片经扫描没有的数据的原因是编码导致的,该问题在windows下较常见,由于很多编辑器默认提供的是ANSI编码,更改成utf8就OK了。

[!--infotagslink--]

相关文章

  • 使用PHP+JavaScript将HTML页面转换为图片的实例分享

    这篇文章主要介绍了使用PHP+JavaScript将HTML元素转换为图片的实例分享,文后结果的截图只能体现出替换的字体,也不能说将静态页面转为图片可以加快加载,只是这种做法比较interesting XD需要的朋友可以参考下...2016-04-19
  • C#从数据库读取图片并保存的两种方法

    这篇文章主要介绍了C#从数据库读取图片并保存的方法,帮助大家更好的理解和使用c#,感兴趣的朋友可以了解下...2021-01-16
  • Photoshop古装美女图片转为工笔画效果制作教程

    今天小编在这里就来给各位Photoshop的这一款软件的使用者们来说说把古装美女图片转为细腻的工笔画效果的制作教程,各位想知道方法的使用者们,那么下面就快来跟着小编一...2016-09-14
  • Python 图片转数组,二进制互转操作

    这篇文章主要介绍了Python 图片转数组,二进制互转操作,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧...2021-03-09
  • php抓取网站图片并保存的实现方法

    php如何实现抓取网页图片,相较于手动的粘贴复制,使用小程序要方便快捷多了,喜欢编程的人总会喜欢制作一些简单有用的小软件,最近就参考了网上一个php抓取图片代码,封装了一个php远程抓取图片的类,测试了一下,效果还不错分享...2015-10-30
  • jquery左右滚动焦点图banner图片鼠标经过显示上下页按钮

    jquery左右滚动焦点图banner图片鼠标经过显示上下页按钮...2013-10-13
  • 利用JS实现点击按钮后图片自动切换的简单方法

    下面小编就为大家带来一篇利用JS实现点击按钮后图片自动切换的简单方法。小编觉得挺不错的,现在就分享给大家,也给大家做个参考。一起跟随小编过来看看吧...2016-10-25
  • Photoshop枪战电影海报图片制作教程

    Photoshop的这一款软件小编相信很多的人都已经是使用过了吧,那么今天小编在这里就给大家带来了用Photoshop软件制作枪战电影海报的教程,想知道制作步骤的玩家们,那么下面...2016-09-14
  • js实现上传图片及时预览

    这篇文章主要为大家详细介绍了js实现上传图片及时预览的相关资料,具有一定的参考价值,感兴趣的朋友可以参考一下...2016-05-09
  • python opencv通过4坐标剪裁图片

    图片剪裁是常用的方法,那么如何通过4坐标剪裁图片,本文就详细的来介绍一下,感兴趣的小伙伴们可以参考一下...2021-06-04
  • 使用PHP下载CSS文件中的图片的代码

    共享一段使用PHP下载CSS文件中的图片的代码 复制代码 代码如下: <?php //note 设置PHP超时时间 set_time_limit(0); //note 取得样式文件内容 $styleFileContent = file_get_contents('images/style.css'); //not...2013-10-04
  • PHP swfupload图片上传的实例代码

    PHP代码如下:复制代码 代码如下:if (isset($_FILES["Filedata"]) || !is_uploaded_file($_FILES["Filedata"]["tmp_name"]) || $_FILES["Filedata"]["error"] != 0) { $upload_file = $_FILES['Filedata']; $fil...2013-10-04
  • 微信小程序如何获取图片宽度与高度

    这篇文章主要给大家介绍了关于微信小程序如何获取图片宽度与高度的相关资料,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧...2021-03-10
  • C#中图片旋转和翻转(RotateFlipType)用法分析

    这篇文章主要介绍了C#中图片旋转和翻转(RotateFlipType)用法,实例分析了C#图片旋转及翻转Image.RotateFlip方法属性的常用设置技巧,需要的朋友可以参考下...2020-06-25
  • ps怎么制作图片阴影效果

    ps软件是现在很多人比较喜欢的,有着非常不错的使用效果,这次文章就给大家介绍下ps怎么制作图片阴影效果,还不知道制作方法的赶紧来看看。 ps图片阴影效果怎么做方法/...2017-07-06
  • OpenCV如何去除图片中的阴影的实现

    这篇文章主要介绍了OpenCV如何去除图片中的阴影的实现,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧...2021-03-29
  • C#将图片和字节流互相转换并显示到页面上

    本文主要介绍用C#实现图片转换成字节流,字节流转换成图片,并根据图片路径返回图片的字节流,有需要的朋友可以参考下...2020-06-25
  • JavaScript 如何禁止用户保存图片

    这篇文章主要介绍了JavaScript 如何禁止用户保存图片,帮助大家完成需求,更好的理解和使用JavaScript,感兴趣的朋友可以了解下...2020-11-19
  • php上传图片学习笔记与心得

    我们在php中上传文件就必须使用#_FILE变量了,这个自动全局变量 $_FILES 从 PHP 4.1.0 版本开始被支持。在这之前,从 4.0.0 版本开始,PHP 支持 $HTTP_POST_FILES 数组。这...2016-11-25
  • SwiftUI图片缩放、拼图等处理教程

    SwiftUI是一种使用Swift语言在苹果设备上构建用户界面的创新且简单的方式,下面这篇文章主要给大家介绍了关于SwiftUI图片缩放、拼图等处理的相关资料,需要的朋友可以参考下...2021-08-23