• 技术文章 >后端开发 >php教程

    用php实现proxy功能的示范[已升级至v0.0.2]_PHP

    2016-06-01 12:40:47原创288
    Proxy

    刚刚写的练手的作品。感觉还是有些实用价值的。。放出来给大家试试。
    功能:通过php实现代理功能
    适用用户:在家下载较慢。且懒得找proxy。且有高速主机,且主机有php,且主机支持socket。
    使用方法:
    1。把本程序传到主机上
    2。通过浏览器浏览主机上的此文件
    3。在url中填入欲下载的文件地址(如果有必要,可以填入referer)
    4。点击get proxy url
    5。新打开的页面中的链接即为通过proxy下载的链接

    注意:
    1。支持多线程下载,断点续传
    2。仅支持http协议
    3。不支持服务器端header重定向
    4。不支持http auth
    5。下载较大的文件时,可以修改程序中set_time_limit的值,以减少断线的现象(默认为180,即3分钟)


    PHP代码:--------------------------------------------------------------------------------

    /***************************************/
    /* */
    /* Php Http Proxy */
    /* version: 0.0.2 */
    /* last modify: 2005.1.12 */
    /* author: q3boy */
    /* */
    /***************************************/
    set_time_limit(180);

    define('PP_ERROR_CODE',1);
    define('PP_ERROR_MESSAGE',2);
    define('PP_ERROR_ALL',3);
    define('PP_RETURN_STRING',1);
    define('PP_RETURN_ARRAY',2);
    define('PP_RETURN_ALL',3);

    class CPhpProxy {

    var $_strUrl;
    var $_arrArgv;
    var $_strRef;
    var $_arrUrl;
    var $_resSocket;
    var $_intError;
    var $_strError;
    var $_arrDefaultArrayUrl;
    var $_arrDefaultPort;

    function CPhpProxy($strUrl = null, $arrArgv = array()) {
    $this->init();
    is_null($strUrl)?':$this->setUrl($strUrl);
    is_null($arrArgv['refer'])?':$this->setRef($arrArgv['refer']);
    $this->proxy($strUrl,$arrArgv);
    }
    function setError($intError,$mixArgv=null) {
    $this->_intError = $intError;
    if($intError==1001) {
    $this->_strError = "调用 $mixArgv 方法时参数传递出错, 枚举值不存在";
    }elseif($intError==1) {
    $this->_strError = "url 错误, url 格式不正确.\n".$mixArgvs;
    }elseif($intError == 2) {
    $this->_strError = "url 错误, 目前尚未支持此协议.\n".$mixArgvs;
    }elseif($intError == 3) {
    $this->_strError = "无法打开 ".$this->_arrUrl['host'].':'.$this->_arrUrl['port']."\n".$mixArgv[0].': '.$mixArgv[1];
    }

    Return false;
    }

    function getError($enumReturnType=PP_ERROR_CODE) {
    if($enumReturnType==PP_ERROR_ALL) {
    Return array(str_pad($this->_intError,5,'0',STR_PAD_LEFT),$this->_strError);
    }elseif($enumReturnType==PP_ERROR_MESSAGE) {
    Return $this->_strError;
    }elseif($enumReturnType==PP_ERROR_CODE) {
    Return $this->_intError;
    }else {
    Return false;
    }
    }

    function init() {
    $this->_strUrl = null;
    $this->_arrArgv = array();
    $this->_strRef = null;
    $this->_arrUrl = array();
    $this->_resSocket = null;
    $this->_intError = 0;
    $this->_strError = 'there is no error';
    //arrurl 默认值
    $this->_arrDefaultArrayUrl = array('protocol'=>'http','file'=>'index.htm');
    //默认端口
    $this->_arrDefaultPort =array('http'=>'80');
    Return true;
    }
    function setUrl($strUrl) {
    $strUrl = trim($strUrl);
    //正则
    $reg = "/^(([\w]+):\/\/)?([^:|\/|@]*:)?([^:|\/|@]*@)?([\w|\-|\.]+)(:\d+)?(\/[^\?|#]*)?(\?[^#]*)?(#.*)?$/is";
    if(!preg_match($reg,$strUrl,$arrUrl)) {
    Return $this->setError(1,$strUrl);
    }else {
    //拆解匹配数组
    list($tmp, $tmp, $arr['protocol'], $arr['user'], $arr['pass'], $arr['host'], $arr['port'], $arr['path'], $arr['query'], $arr['anchor']) = $arrUrl;
    //默认协议
    if(!$arr['protocol']) {
    $arrUrl[1] = $this->_arrDefaultArrayUrl['protocol'].'://';
    }
    //设 filename
    $arr['file'] = basename($arr['path']);
    //默认值
    foreach($this->_arrDefaultArrayUrl as $key=>$val) {
    if($arr[$key] == ') {
    $arr[$key] = $val;
    }
    }
    //默认端口
    if(is_null($this->_arrDefaultPort[$arr['protocol']])) {
    Return $this->setError(2,$arr['protocol']);
    }elseif(!$arr['port']) {
    $arr['port'] = $this->_arrDefaultPort[$arr['protocol']];
    }

    //设 uri
    $arr['uri'] = ($arr['path']?$arr['path']:'//m.sbmmt.com/m/') . ($arr['query']?'?'.$arr['query']:') . ($arr['anchor']?'#'.$arr['anchor']:');
    //设 url
    unset($arrUrl[0]);
    unset($arrUrl[2]);
    $this->_strUrl = implode(',$arrUrl);
    //设 arrurl
    $this->_arrUrl = $arr;
    Return true;
    }
    }
    function getUrl($enumReturnType = PP_RETURN_ARRAY) {
    if($enumReturnType==PP_RETURN_STRING) {
    Return $this->_strUrl;
    }elseif($enumReturnType==PP_RETURN_ARRAY) {
    Return $this->_arrUrl;
    }if($enumReturnType==PP_RETURN_ALL) {
    Return array($this->_strUrl,$this->_arrUrl);
    }else {
    Return $this->setError(1001);
    }

    }
    function setRefer($strRef) {
    $this->_strRef = trim($strRef);
    Return true;
    }
    function getRefer() {
    Return $this->_strRef;
    }

    function getProxyUrl() {
    global $_SERVER;
    list($strProcotol) = explode('//m.sbmmt.com/m/',strtolower(trim($_SERVER['SERVER_PROTOCOL'])));
    $str = $strProcotol.'://'.$_SERVER['HTTP_HOST'].$_SERVER['PHP_SELF'].
    '?u='.urlencode($this->getUrl(PP_RETURN_STRING)).
    ($this->getRefer()?('&r='.urlencode($this->getRefer())):');
    Return $str;
    }
    function openSocket() {
    $arr = $this->getUrl();
    $this->_resSocket = @fsockopen($arr['host'],$arr['port'],$intError, $strError, 30);
    if(!$this->_resSocket) {
    $this->_resSocket = null;
    Return $this->setError(3,array($intError, $strError));
    }else {
    Return true;
    }
    }
    function getRequest() {
    Return $this->{'get'.ucfirst($this->_arrUrl['protocol']).'Request'}();
    }
    function sendRequest() {
    Return fwrite($this->_resSocket,$this->getRequest());
    }
    function flushResponse() {
    Return $this->{'flush'.ucfirst($this->_arrUrl['protocol']).'Response'}();
    }
    function getHttpRequest() {
    $arr = $this->getUrl();
    $arrRequest = getallheaders();
    $arrRequest['Host'] = $arr['host'];
    $strRequest = "GET ".$arr['uri']." HTTP/1.1\r\n";
    foreach($arrRequest as $key=>$val) {
    $strRequest .="$key: $val\r\n";
    }
    $strRequest .="\r\n";
    Return $strRequest;
    }
    function flushHttpResponse() {
    $bolHeader=true;
    while (!feof($this->_resSocket)) {
    $str = fgets($this->_resSocket, 4096);
    if($bolHeader) {
    @header($str);
    }else {
    echo($str);
    }
    if($bolHeader && $str=="\r\n") {
    $bolHeader=false;
    @header("Content-type: application/gzip");
    @header('Content-Disposition: attachment; filename="'.$this->_arrUrl['file'].'"');
    }
    }
    Return true;
    }
    function close() {
    fclose($this->_resSocket);
    $this->_resSocket = null;
    Return true;
    }
    function proxy($strUrl = null,$arrArgv = array()) {
    if(!is_null($this->getUrl(PP_RETURN_STRING)) && $this->openSocket() && $this->sendRequest() && $this->flushResponse()) {
    echo(123);
    $this->close();
    }else {
    Return false;
    }
    }
    }
    if(sizeof($_GET)) {
    $strGetArrayName = '_GET';
    }elseif(sizeof($HTTP_GET_VARS)) {
    $strGetArrayName = 'HTTP_GET_VARS';
    }else {
    die('



    PhpProxy



















    PhpProxy
    URL:
    REFERER:





    ');
    }
    $strUrl = trim(${$strGetArrayName}['u']);
    if($strUrl==') {
    die('请输入 url 地址.');
    }
    //get referer
    $strRefTmp = trim(${$strGetArrayName}['r']);
    //初始化 proxy 类
    $objProxy = new CPhpProxy();
    //设置 url 和 refer
    $objProxy->setUrl($strUrl);
    $objProxy->setRefer($strRef);
    //错误输出
    if($objProxy->getError()) {
    die($objProxy->getError(PP_ERROR_MESSAGE));
    }

    //echo url for download
    if(${$strGetArrayName}['act']=='make') {
    die("

    点击此处通过 PhpProxy 下载文件

    ");
    }
    //取文件
    $objProxy->proxy();
    //错误处理
    if($objProxy->getError()) {
    die($objProxy->getError(PP_ERROR_MESSAGE));
    }
    ?>
    声明:本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn核实处理。
    上一篇:MVCwithPHP(二)_PHP 下一篇:mysql数据库优化_PHP
    PHP编程就业班

    相关文章推荐

    • 怎么解决PHP高并发(商品秒杀)问题?两种解决方案分享• 生手数据库求指教• 关于phpexcel有关问题• 不区分大小写,查寻数组,有这样的函数么• 关于memcache 今天刚开始学习遇到个有关问题

    全部评论我要评论

  • 取消发布评论发送
  • 1/1

    PHP中文网