摘自织梦CMS的HTTP文件下载类


Posted in PHP onAugust 08, 2015

本文实例讲述了摘自织梦CMS的HTTP文件下载类。分享给大家供大家参考。具体如下:

<?php if(!defined('DEDEINC')) exit("Request Error!");
/**
 * 织梦HTTP下载类
 *
 * @version  $Id: dedehttpdown.class.php 1 11:42 2010年7月6日Z tianya $
 * @package  DedeCMS.Libraries
 * @copyright  Copyright (c) 2007 - 2010, DesDev, Inc.
 * @license  http://help.dedecms.com/usersguide/license.html
 * @link   http://www.dedecms.com
 */
@set_time_limit(0);
class DedeHttpDown
{
 var $m_url = '';
 var $m_urlpath = '';
 var $m_scheme = 'http';
 var $m_host = '';
 var $m_port = '80';
 var $m_user = '';
 var $m_pass = '';
 var $m_path = '/';
 var $m_query = '';
 var $m_fp = '';
 var $m_error = '';
 var $m_httphead = '';
 var $m_html = '';
 var $m_puthead = '';
 var $BaseUrlPath = '';
 var $HomeUrl = '';
 var $reTry = 0;
 var $JumpCount = 0;
 /**
  * 初始化系统
  *
  * @access public
  * @param  string $url 需要下载的地址
  * @return string
  */
 function PrivateInit($url)
 {
  if($url=='') {
   return ;
  }
  $urls = '';
  $urls = @parse_url($url);
  $this->m_url = $url;
  if(is_array($urls))
  {
   $this->m_host = $urls["host"];
   if(!empty($urls["scheme"]))
   {
    $this->m_scheme = $urls["scheme"];
   }
   if(!empty($urls["user"]))
   {
    $this->m_user = $urls["user"];
   }
   if(!empty($urls["pass"]))
   {
    $this->m_pass = $urls["pass"];
   }
   if(!empty($urls["port"]))
   {
    $this->m_port = $urls["port"];
   }
   if(!empty($urls["path"]))
   {
    $this->m_path = $urls["path"];
   }
   $this->m_urlpath = $this->m_path;
   if(!empty($urls["query"]))
   {
    $this->m_query = $urls["query"];
    $this->m_urlpath .= "?".$this->m_query;
   }
   $this->HomeUrl = $urls["host"];
   $this->BaseUrlPath = $this->HomeUrl.$urls["path"];
   $this->BaseUrlPath = preg_replace("/\/([^\/]*)\.(.*)$/","/",$this->BaseUrlPath);
   $this->BaseUrlPath = preg_replace("/\/$/","",$this->BaseUrlPath);
  }
 }
 /**
  * 重设各参数
  *
  * @access public
  * @return void
  */
 function ResetAny()
 {
  $this->m_url = "";
  $this->m_urlpath = "";
  $this->m_scheme = "http";
  $this->m_host = "";
  $this->m_port = "80";
  $this->m_user = "";
  $this->m_pass = "";
  $this->m_path = "/";
  $this->m_query = "";
  $this->m_error = "";
 }
 /**
  * 打开指定网址
  *
  * @access public
  * @param  string $url 地址
  * @param  string $requestType 请求类型
  * @return string
  */
 function OpenUrl($url,$requestType="GET")
 {
  $this->ResetAny();
  $this->JumpCount = 0;
  $this->m_httphead = Array() ;
  $this->m_html = '';
  $this->reTry = 0;
  $this->Close();
  //初始化系统
  $this->PrivateInit($url);
  $this->PrivateStartSession($requestType);
 }
 /**
  * 转到303重定向网址
  *
  * @access public
  * @param  string $url 地址
  * @return string
  */
 function JumpOpenUrl($url)
 {
  $this->ResetAny();
  $this->JumpCount++;
  $this->m_httphead = Array() ;
  $this->m_html = "";
  $this->Close();
  //初始化系统
  $this->PrivateInit($url);
  $this->PrivateStartSession('GET');
 }
 /**
  * 获得某操作错误的原因
  *
  * @access public
  * @return void
  */
 function printError()
 {
  echo "错误信息:".$this->m_error;
  echo "<br/>具体返回头:<br/>";
  foreach($this->m_httphead as $k=>$v){ echo "$k => $v <br/>\r\n"; }
 }
 /**
  * 判别用Get方法发送的头的应答结果是否正确
  *
  * @access public
  * @return bool
  */
 function IsGetOK()
 {
  if( preg_match("/^2/",$this->GetHead("http-state")) )
  {
   return TRUE;
  }
  else
  {
   $this->m_error .= $this->GetHead("http-state")." - ".$this->GetHead("http-describe")."<br/>";
   return FALSE;
  }
 }
 /**
  * 看看返回的网页是否是text类型
  *
  * @access public
  * @return bool
  */
 function IsText()
 {
  if( preg_match("/^2/",$this->GetHead("http-state")) && preg_match("/text|xml/i",$this->GetHead("content-type")) )
  {
   return TRUE;
  }
  else
  {
   $this->m_error .= "内容为非文本类型或网址重定向<br/>";
   return FALSE;
  }
 }
 /**
  * 判断返回的网页是否是特定的类型
  *
  * @access public
  * @param  string $ctype 内容类型
  * @return string
  */
 function IsContentType($ctype)
 {
  if(preg_match("/^2/",$this->GetHead("http-state"))
  && $this->GetHead("content-type")==strtolower($ctype))
  { return TRUE; }
  else
  {
   $this->m_error .= "类型不对 ".$this->GetHead("content-type")."<br/>";
   return FALSE;
  }
 }
 /**
  * 用Http协议下载文件
  *
  * @access public
  * @param  string $savefilename 保存文件名称
  * @return string
  */
 function SaveToBin($savefilename)
 {
  if(!$this->IsGetOK())
  {
   return FALSE;
  }
  if(@feof($this->m_fp))
  {
   $this->m_error = "连接已经关闭!"; return FALSE;
  }
  $fp = fopen($savefilename,"w");
  while(!feof($this->m_fp))
  {
   fwrite($fp, fread($this->m_fp, 1024));
  }
  fclose($this->m_fp);
  fclose($fp);
  return TRUE;
 }
 /**
  * 保存网页内容为Text文件
  *
  * @access public
  * @param  string $savefilename 保存文件名称
  * @return string
  */
 function SaveToText($savefilename)
 {
  if($this->IsText())
  {
   $this->SaveBinFile($savefilename);
  }
  else
  {
   return "";
  }
 }
 /**
  * 用Http协议获得一个网页的内容
  *
  * @access public
  * @return string
  */
 function GetHtml()
 {
  if(!$this->IsText())
  {
   return '';
  }
  if($this->m_html!='')
  {
   return $this->m_html;
  }
  if(!$this->m_fp||@feof($this->m_fp))
  {
   return '';
  }
  while(!feof($this->m_fp))
  {
   $this->m_html .= fgets($this->m_fp,256);
  }
  @fclose($this->m_fp);
  return $this->m_html;
 }
 /**
  * 开始HTTP会话
  *
  * @access public
  * @param  string $requestType 请求类型
  * @return string
  */
 function PrivateStartSession($requestType="GET")
 {
  if(!$this->PrivateOpenHost())
  {
   $this->m_error .= "打开远程主机出错!";
   return FALSE;
  }
  $this->reTry++;
  if($this->GetHead("http-edition")=="HTTP/1.1")
  {
   $httpv = "HTTP/1.1";
  }
  else
  {
   $httpv = "HTTP/1.0";
  }
  $ps = explode('?',$this->m_urlpath);
  $headString = '';
  //发送固定的起始请求头GET、Host信息
  if($requestType=="GET")
  {
   $headString .= "GET ".$this->m_urlpath." $httpv\r\n";
  }
  else
  {
   $headString .= "POST ".$ps[0]." $httpv\r\n";
  }
  $this->m_puthead["Host"] = $this->m_host;
  //发送用户自定义的请求头
  if(!isset($this->m_puthead["Accept"]))
  {
   $this->m_puthead["Accept"] = "*/*";
  }
  if(!isset($this->m_puthead["User-Agent"]))
  {
   $this->m_puthead["User-Agent"] = "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.2)";
  }
  if(!isset($this->m_puthead["Refer"]))
  {
   $this->m_puthead["Refer"] = "http://".$this->m_puthead["Host"];
  }
  foreach($this->m_puthead as $k=>$v)
  {
   $k = trim($k);
   $v = trim($v);
   if($k!=""&&$v!="")
   {
    $headString .= "$k: $v\r\n";
   }
  }
  fputs($this->m_fp, $headString);
  if($requestType=="POST")
  {
   $postdata = "";
   if(count($ps)>1)
   {
    for($i=1;$i<count($ps);$i++)
    {
     $postdata .= $ps[$i];
    }
   }
   else
   {
    $postdata = "OK";
   }
   $plen = strlen($postdata);
   fputs($this->m_fp,"Content-Type: application/x-www-form-urlencoded\r\n");
   fputs($this->m_fp,"Content-Length: $plen\r\n");
  }
  //发送固定的结束请求头
  //HTTP1.1协议必须指定文档结束后关闭链接,否则读取文档时无法使用feof判断结束
  if($httpv=="HTTP/1.1")
  {
   fputs($this->m_fp,"Connection: Close\r\n\r\n");
  }
  else
  {
   fputs($this->m_fp,"\r\n");
  }
  if($requestType=="POST")
  {
   fputs($this->m_fp,$postdata);
  }
  //获取应答头状态信息
  $httpstas = explode(" ",fgets($this->m_fp,256));
  $this->m_httphead["http-edition"] = trim($httpstas[0]);
  $this->m_httphead["http-state"] = trim($httpstas[1]);
  $this->m_httphead["http-describe"] = "";
  for($i=2;$i<count($httpstas);$i++)
  {
   $this->m_httphead["http-describe"] .= " ".trim($httpstas[$i]);
  }
  //获取详细应答头
  while(!feof($this->m_fp))
  {
   $line = trim(fgets($this->m_fp,256));
   if($line == "")
   {
    break;
   }
   $hkey = "";
   $hvalue = "";
   $v = 0;
   for($i=0;$i<strlen($line);$i++)
   {
    if($v==1)
    {
     $hvalue .= $line[$i];
    }
    if($line[$i]==":")
    {
     $v = 1;
    }
    if($v==0)
    {
     $hkey .= $line[$i];
    }
   }
   $hkey = trim($hkey);
   if($hkey!="")
   {
    $this->m_httphead[strtolower($hkey)] = trim($hvalue);
   }
  }
  //如果连接被不正常关闭,重试
  if(feof($this->m_fp))
  {
   if($this->reTry > 10)
   {
    return FALSE;
   }
   $this->PrivateStartSession($requestType);
  }
  //判断是否是3xx开头的应答
  if(preg_match("/^3/",$this->m_httphead["http-state"]))
  {
   if($this->JumpCount > 3)
   {
    return;
   }
   if(isset($this->m_httphead["location"]))
   {
    $newurl = $this->m_httphead["location"];
    if(preg_match("/^http/i",$newurl))
    {
     $this->JumpOpenUrl($newurl);
    }
    else
    {
     $newurl = $this->FillUrl($newurl);
     $this->JumpOpenUrl($newurl);
    }
   }
   else
   {
    $this->m_error = "无法识别的答复!";
   }
  }
 }
 /**
  * 获得一个Http头的值
  *
  * @access public
  * @param  string $headname 头文件名称
  * @return string
  */
 function GetHead($headname)
 {
  $headname = strtolower($headname);
  return isset($this->m_httphead[$headname]) ? $this->m_httphead[$headname] : '';
 }
 /**
  * 设置Http头的值
  *
  * @access public
  * @param  string $skey 键
  * @param  string $svalue 值
  * @return string
  */
 function SetHead($skey,$svalue)
 {
  $this->m_puthead[$skey] = $svalue;
 }
 /**
  * 打开连接
  *
  * @access public
  * @return bool
  */
 function PrivateOpenHost()
 {
  if($this->m_host=="")
  {
   return FALSE;
  }
  $errno = "";
  $errstr = "";
  $this->m_fp = @fsockopen($this->m_host, $this->m_port, $errno, $errstr,10);
  if(!$this->m_fp)
  {
   $this->m_error = $errstr;
   return FALSE;
  }
  else
  {
   return TRUE;
  }
 }
 /**
  * 关闭连接
  *
  * @access public
  * @return void
  */
 function Close()
 {
  @fclose($this->m_fp);
 }
 /**
  * 补全相对网址
  *
  * @access public
  * @param  string $surl 需要不全的地址
  * @return string
  */
 function FillUrl($surl)
 {
  $i = 0;
  $dstr = "";
  $pstr = "";
  $okurl = "";
  $pathStep = 0;
  $surl = trim($surl);
  if($surl=="")
  {
   return "";
  }
  $pos = strpos($surl,"#");
  if($pos>0)
  {
   $surl = substr($surl,0,$pos);
  }
  if($surl[0]=="/")
  {
   $okurl = "http://".$this->HomeUrl.$surl;
  }
  else if($surl[0]==".")
  {
   if(strlen($surl)<=1)
   {
    return "";
   }
   else if($surl[1]=="/")
   {
    $okurl = "http://".$this->BaseUrlPath."/".substr($surl,2,strlen($surl)-2);
   }
   else
   {
    $urls = explode("/",$surl);
    foreach($urls as $u)
    {
     if($u=="..")
     {
      $pathStep++;
     }
     else if($i<count($urls)-1)
     {
      $dstr .= $urls[$i]."/";
     }
     else
     {
      $dstr .= $urls[$i];
     }
     $i++;
    }
    $urls = explode("/",$this->BaseUrlPath);
    if(count($urls) <= $pathStep)
    {
     return "";
    }
    else
    {
     $pstr = "http://";
     for($i=0;$i<count($urls)-$pathStep;$i++)
     {
      $pstr .= $urls[$i]."/";
     }
     $okurl = $pstr.$dstr;
    }
   }
  }
  else
  {
   if(strlen($surl)<7)
   {
    $okurl = "http://".$this->BaseUrlPath."/".$surl;
   }
   else if(strtolower(substr($surl,0,7))=="http://")
   {
    $okurl = $surl;
   }
   else
   {
    $okurl = "http://".$this->BaseUrlPath."/".$surl;
   }
  }
  $okurl = preg_replace("/^(http:\/\/)/i","",$okurl);
  $okurl = preg_replace("/\/{1,}/", "/", $okurl);
  return "http://".$okurl;
 }
}//End Class

希望本文所述对大家的php程序设计有所帮助。

PHP 相关文章推荐
通过html表格发电子邮件
Oct 09 PHP
如何在PHP中进行身份认证
Oct 09 PHP
修改php.ini实现Mysql导入数据库文件最大限制的修改方法
Dec 11 PHP
Ajax+PHP边学边练 之五 图片处理
Dec 03 PHP
腾讯QQ php程序员面试题目整理
Jun 08 PHP
php自定义函数之递归删除文件及目录
Aug 08 PHP
php下通过IP获取地理位置的代码(小偷程序)
Jun 09 PHP
变量在 PHP7 内部的实现(二)
Dec 21 PHP
PHP使用mkdir创建多级目录的方法
Dec 22 PHP
ZendFramework框架实现连接两个或多个数据库的方法
Dec 08 PHP
PHP 传输会话curl函数的实例详解
Sep 12 PHP
php探针不显示内存解决方法
Sep 17 PHP
摘自织梦CMS中的图片处理类
Aug 08 #PHP
PHP模拟asp.net的StringBuilder类实现方法
Aug 08 #PHP
php自动识别文字编码并转换为目标编码的方法
Aug 08 #PHP
PHP模拟asp中response类实现方法
Aug 08 #PHP
PHP实现根据图片色界在不同位置加水印的方法
Aug 08 #PHP
PHP中使用curl伪造IP的简单方法
Aug 07 #PHP
smarty中常用方法实例总结
Aug 07 #PHP
You might like
天使彦史上最神还原,性别曝光的那一刻,百万网友恋爱了
2020/03/02 国漫
深入了解php4(1)--回到未来
2006/10/09 PHP
PHP计划任务之关闭浏览器后仍然继续执行的函数
2010/07/22 PHP
ThinkPHP 3.2 数据分页代码分享
2014/10/14 PHP
Zend Framework连接Mysql数据库实例分析
2016/03/19 PHP
十个优秀的Ajax/Javascript实例网站收集
2010/03/31 Javascript
基于jQuery捕获超链接事件进行局部刷新代码
2012/05/10 Javascript
js判读浏览器是否支持html5的canvas的代码
2013/11/18 Javascript
js简单的弹出框有关闭按钮
2014/05/05 Javascript
Javascript实现的SHA-256加密算法完整实例
2016/02/02 Javascript
老生常谈遮罩层 滚动条的问题
2016/04/29 Javascript
全面了解构造函数继承关键apply call
2016/07/26 Javascript
Angularjs中使用轮播图指令swiper
2017/05/30 Javascript
Jquery+Ajax+xml实现中国地区选择三级联动菜单效果(推荐)
2017/06/09 jQuery
jQuery实现菜单栏导航效果
2017/08/15 jQuery
jQuery中元素选择器(element)简单用法示例
2018/05/14 jQuery
vue表单自定义校验规则介绍
2018/08/28 Javascript
使用nodejs分离html文件里的js和css详解
2019/04/12 NodeJs
使用vue-cli3+typescript的项目模板创建工程的教程
2020/02/28 Javascript
[01:33:14]LGD vs VP Supermajor 败者组决赛 BO3 第二场 6.10
2018/07/04 DOTA
Python 执行字符串表达式函数(eval exec execfile)
2014/08/11 Python
python装饰器初探(推荐)
2016/07/21 Python
Python实现字符串反转的常用方法分析【4种方法】
2017/09/30 Python
Python探索之Metaclass初步了解
2017/10/28 Python
Python使用matplotlib绘图无法显示中文问题的解决方法
2018/03/14 Python
python破解zip加密文件的方法
2018/05/31 Python
想学python 这5本书籍你必看!
2018/12/11 Python
pytorch 在sequential中使用view来reshape的例子
2019/08/20 Python
Python 批量刷博客园访问量脚本过程解析
2019/08/30 Python
python GUI库图形界面开发之PyQt5美化窗体与控件(异形窗体)实例
2020/02/25 Python
新闻专业个人求职信
2013/12/19 职场文书
英语教师个人工作总结
2015/02/09 职场文书
廉洁自律个人总结
2015/02/14 职场文书
社区公民道德宣传日活动总结
2015/03/23 职场文书
2019年入党思想汇报
2019/03/25 职场文书
PyTorch dropout设置训练和测试模式的实现
2021/05/27 Python