php发送请求上传文件(原始socket方式)

php curl工具能很方便的发送请求。

php使用socket方式也可以发送请求,虽然原始,但是能够体会到GET,POST,等请求的细节,对于理解HTTP协议有帮助。

<?php
/**
 * Created by PhpStorm.
 * User: zhaozhiliang
 * Date: 2018/6/25
 * Time: 下午4:59
 */

class HttpRequest
{
    private $_ip = '';
    private $_host = '';
    private $_url = '';
    private $_port = '';
    private $_errno = '';
    private $_errstr = '';
    private $_timeout = 15;
    private $_fp = null;

    private $_formdata = array();
    private $_filedata = array();

    //设置连接参数
    public function setConfig($config){
        $this->_ip = isset($config['ip'])? $config['ip'] : '';
        $this->_host = isset($config['host'])? $config['host'] : '';
        $this->_url = isset($config['url']) ? $config['url'] : '';
        $this->_port = isset($config['port']) ? $config['port'] : '';
        $this->_errno = isset($config['errno']) ? $config['errno'] : '';
        $this->_errstr = isset($config['errstr']) ? $config['errstr'] : '';
        $this->_timeout = isset($config['timeout']) ? $config['timeout'] : 15;

        //如果没有ip,则用host代替
        if($this->_ip==''){
            $this->_ip = $this->_host;
        }
    }

    //设置表单数据
    public function setFormData($formdata = array()){
        $this->_formdata = $formdata;
    }

    //设置文件数据
    public function setFileData($filedata = array()){
        $this->_filedata = $filedata;
    }

    public function send($type= 'get'){
        $type = strtolower($type);

        if(!in_array($type, array('get','post','multipart'))){
            return false;
        }

        if(! $this->connect()){
            return false;
        }

        switch ($type){
            case 'get' :
                $out = $this->sendGet();
                break;
            case 'post' :
                $out = $this->sendPost();
                break;
            case 'multipart' :
                $out = $this->sendMultipart();
                break;
        }

        if(!$out){
            return false;
        }

        //发送数据
        fputs($this->_fp, $out);

        //读取返回数据
        $response = '';
        while($row = fread($this->_fp, 4096)){
            $response .= $row;
        }

        //echo 'response:', $response;
        //断开连接
        $this->disconnect();
        $pos = strpos($response, "\r\n\r\n");
        $response  = substr($response, $pos+ 4);
        return $response;

    }

    //创建连接
    private function connect(){
        $this->_fp = fsockopen($this->_ip, $this->_port, $this->_errno,$this->_errstr,$this->_timeout);
        if(!$this->_fp){
            return false;
        }
        return true;
    }

    //断开连接
    private function disconnect(){
        if($this->_fp != null){
           fclose($this->_fp);
           $this->_fp = null;
        }
    }


    //GET 方式,
    private function sendGet(){
        //检查是否空数据
        if(!$this->_formdata){
            return false;
        }

       //处理url
        $url = $this->_url.'?'.http_build_query($this->_formdata);

        $out = "GET ".$url." HTTP/1.1\r\n";
        $out .= "host: ".$this->_host."\r\n";
        $out .= "connection: close\r\n\r\n";

        return $out;
    }

    //POST 方式,处理发送的数据
    private function sendPost(){
        //检查是否空数据
        if(!$this->_formdata && !$this->_filedata){
            return false;
        }

        //form data
        $data = $this->_formdata ? $this->_formdata : array();

//        //file data
//        if($this->_filedata){
//            foreach($this->_filedata as $file){
//                if(file_exists($file['path'])){
//                    $data[$file['name']] = file_get_contents($file['path']);
//                }
//            }
//        }

        if(!$data){
            return false;
        }

        $data = http_build_query($data);

        $out = "POST ".$this->_url." HTTP/1.1\r\n";
        $out .= "host: ".$this->_host."\r\n";
        $out .= "content-type: application/x-www-form-urlencoded\r\n";
        $out .= "content-length: ".strlen($data)."\r\n";
        $out .= "connection: close\r\n\r\n";
        $out .= $data;

        return $out;
    }

    //multipart 方式, 发送数据文件使用此方式
    private function sendMultipart(){
        //检查是否空数据
        if(!$this->_formdata && !$this->_filedata){
            return false;
        }

        //设置分割标识符
        $boundary = '---------------------------'.substr(md5(rand(0,32000)), 0, 10);
        $data = '--'.$boundary."\r\n";

        //form data
        $formdata = '';
        foreach($this->_formdata as $key=> $val){
            $formdata .= "content-disposition: form-data; name=\"".$key."\"\r\n";
            $formdata .= "content-type: text/plain\r\n\r\n";

            if(is_array($val)){
                $formdata .= json_encode($val)."\r\n";
            }else{
                $formdata .= rawurldecode($val)."\r\n";
            }
            $formdata .= '--'.$boundary."\r\n";
        }

        //file data
        $filedata = '';
        foreach($this->_filedata as $val){
            if(file_exists($val['path'])){
                $finfo    = finfo_open(FILEINFO_MIME_TYPE);
                $mimetype = finfo_file($finfo, $val['path']);
                finfo_close($finfo);

                $filedata .= "content-disposition: form-data; name=\"".$val['name']."\"; filename=\"".$val['filename']."\"\r\n";
                $filedata .= "content-type: ".$mimetype."\r\n\r\n";
                $filedata .= implode('', file($val['path']))."\r\n";
                $filedata .= "--".$boundary."\r\n";
            }
        }

        if(!$formdata && !$filedata){
            return false;
        }

        $data .= $formdata.$filedata."--\r\n\r\n";

        $out = "POST ".$this->_url." HTTP/1.1\r\n";
        $out .= "host: ".$this->_host."\r\n";
        $out .= "content-type: multipart/form-data; boundary=".$boundary."\r\n";
        $out .= "content-length: ".strlen($data)."\r\n";
        $out .= "connection: close\r\n\r\n";
        $out .= $data;

        return $out;

    }

}

/**
 * 以下为测试
 */
$config = array(
    'ip' => 'blog.liang.com',
    'host' => 'blog.liang.com',
    'port' => 80,
    'errno' => '',
    'errstr' => '',
    'timeout' => 30,
    'url' => '/test_multipart.php'
);

$formdata = array(
    'name'=>'zhangsan',
    'real_name' => '张三',
    'age' => 29 ,
    'sex'=> 1,
    'address'=> 'beijing'
);

$filedata = array(
    array(
        'name' => 'logo',
        'filename' => 'logo.png',
        'path' => './logo.png'
    )
);

$obj = new HttpRequest();
$obj-> setConfig($config);
$obj-> setFormdata($formdata);
$obj-> setFileData($filedata);
#$result = $obj->send('get');
$result = $obj->send('post');
#$result = $obj->send('multipart');

print_r($result);


说明:

1. fileinfo 扩展需要phpize 安装,不用重新下载包了,php5.5.7安装包 的 ext目录下有。


猜你喜欢

转载自blog.csdn.net/u013862108/article/details/80818031
今日推荐