• PHP


         一、fsocketopen,使用这个的过程看起来更像别的语言的socket编程

    public function send($request) {
                                                                  
                                                        
            /* 请求数据 */
            $post_data = $request;
            $lenght = strlen($post_data);
            $headers  = "{$this->type} /{$this->url} HTTP/1.1
    ";
            $headers .= "Accept: * /*
    ";
            $headers .= "Content-Type: application/x-www-form-urlencoded
    ";
            $headers .= "User-Agent: Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 5.1; Trident/4.0; GTB6; CIBA; .NET CLR 4.0.20506)
    ";
                                                        
            //如果存在$session
            if($session != "" )
                 $headers .= "Cookie:JSESSIONID={$this->session}
    ";
                                                                
            $headers .= "Host: {$this->host}:{$this->port}
    ";
            $headers .= "Content-Length: {$lenght}
    ";
            $headers .= "Connection: Close
    
    ";
            $headers .= $post_data;
            if( $fp = fsockopen( $this->host, $this->port, $errno, $errstr, 100) ) {
                fwrite($fp, $headers);       
                $header   = fread($fp, 1024);
                $content  = fread($fp, 1024);   
                $content .= fread($fp, 1024);
                $content .= fread($fp, 1024);
                $content .= fread($fp, 1024);
                fclose($fp);
            }//end of if

    如上图所示,只要链接到相应的主机和端口,然后我们就已经tcp上了主机,然后写工作在tcp之上的http协议头部,就$header里面的内容,当然有很多是不必要的 ,只用写Content_Length,和Content_Type;

    关于TCP的细节还是参照RFC文档,头部换行再空一行之后就是内容去,也就是$requst,响应的协调好两边传输的内容比如用json来,应该来说已经比较方便了,要不最多自己解析自己写的字符串也可以。这样写好头部之后我们的请求就可以被apache或者ngix之类的服务器识别了然后调到相应的php 文件。非常容易.

    二,fopen函数。

               这个貌似我只在打开本地文件的时候用过了,在php manual里面是这样描述的 fopen — Opens file or URL。显然我们可以用过url来标识定位远程的PHP文件,当我们定位到的时候同样取得请求会被apache获取然后被php引擎执行,然后返回结果。但是我还是觉得这个函数好神奇。有一点要注意的就是:url前面必须写上http://

               这样之后还不够,还要依赖另外一个函数steam_content_create() ,实例代码如下:

    <?php      
           $opts = array ('http' => array (
                                'method'  => 'POST',
                                'header'  => 'Content-type: application/json',
                                'content' => $request
                                ));
            $context  = stream_context_create($opts);
            if ($fp = fopen($this->url, 'r', false, $context)) {
                $response = '';
                while($row = fgets($fp)) {
                    $response.= trim($row)."
    ";
                }
                $this->debug && $this->debug.='***** Server response *****'."
    ".$response.'***** End of server response *****'."
    ";
                $response = json_decode($response,true);
            } else {
                throw new Exception('Unable to connect to '.$this->url);
            }

               最后也是最重要的一点就是我在解析RPC的时候遇到了一个巨大的坑。

               redirect这种东西经常遇到,例如你访问网站默认访问index.html index.php 等等文件。或者你会在php里面给他个header('location:***')。一开始的时候我把服务器文件放在一个叫rpc的目录下面,然后客户端的url我就写的http://***.***.com/rpc 这下就悲剧了,各种情况都说明了我已经定位到那个文件的,而且文件的代码已经执行了,但是永远不是POST过去的,而且携带的数据也全部丢失了。搞得我非常难过。。我在服务器

    var_dump $_SERVER 和 $_REQUEST  请求方法永远是GET 永远没有数据,后来我突然发现是重定向的问题,一旦重定向之后服务器就会给你导向一个新的URL,并且已GET的方式,不携带任何数据.

               更加详细的见下面代码

    <?php
    function runRequest($verb, $uri, $data)
         $params = array(
                'http' => array(
                    'method' => $verb,
                    'ignore_errors' => true,
                    'header' => "Accept: application/json
    "
                                . "Cache-Control: no-cache
    "
                                . "Pragma: no-cache
    "
                )
            );
        
            if ($verb == 'POST') {
                if (is_array($data)) {
                    $str = http_build_query($data);
                } else {
                    $str = $data;
                }
        
                $params['http']['header'] .= "Content-type: application/x-www-form-urlencoded
    "
                                            . 'Content-Length: '.strlen($str)."
    ";
                $params['http']['content'] = $str;
            }
        
            $ctx = stream_context_create($params);
        
            $fp = @fopen($uri, 'rb', false, $ctx);
            if (!$fp) {
                print "runReq.fail:$verb-$uri";
    //            throw new Exception('Problem with '.$verb.' '.$uri);
            }
        
            $output = @stream_get_contents($fp);
            $headers = @stream_get_meta_data($fp);
        
            fclose($fp);
        
            unset($fp);
            unset($ctx);
            unset($str);
            unset($params);
    //        unset($verb);
        
            var_dump($headers);
        
            var_dump($output);
    }
    ?>
        
    a.php (does the redirect)
    ============
        
    <?php
    header('Location: /b.php', true, 302);
    ?>
        
    b.php
    =================
    <?php
    var_dump($_REQUEST);
    var_dump($_SERVER);
    ?>
        
    When I run client.php, this is the response:
        
     ...truncated ...
        
      ["SERVER_ADMIN"]=>
      string(15) "you@example.com"
      ["SCRIPT_FILENAME"]=>
      string(26) "/Users/moz/Sites/exp/b.php"
      ["REMOTE_PORT"]=>
      string(5) "56070"
      ["GATEWAY_INTERFACE"]=>
      string(7) "CGI/1.1"
      ["SERVER_PROTOCOL"]=>
      string(8) "HTTP/1.0"
      ["REQUEST_METHOD"]=>
      string(3) "GET"
      ["QUERY_STRING"]=>
      string(0) ""
      ["REQUEST_URI"]=>
      string(6) "/b.php"
      ["SCRIPT_NAME"]=>
      string(6) "/b.php"
      ["PHP_SELF"]=>
      string(6) "/b.php"
      ["REQUEST_TIME"]=>
      int(1334249770)
    }
    array(0) {
    }
    array(5) {
      ["Host"]=>
      string(8) "expo.dev"
      ["Accept"]=>
      string(16) "application/json"
      ["Cache-Control"]=>
      string(8) "no-cache"
      ["Pragma"]=>
      string(8) "no-cache"
      ["Content-type"]=>
      string(33) "application/x-www-form-urlencoded"
    }
    "
  • 相关阅读:
    use other gpio pins as i2c
    systemd详解详解
    Python ctype sizeof incorrect!
    libvirt 安装篇
    Django Restful Framework (二): ModelSerializer
    Django Restful Framework (一): Serializer
    libvirt 网络手册(二):桥接网络
    KVM 虚拟机联网方式:NAT 和 Bridge
    libvirt 网络手册(一)
    CentOS 7 环境配置
  • 原文地址:https://www.cnblogs.com/maxmys/p/3327184.html
Copyright © 2020-2023  润新知