ホームページ >バックエンド開発 >PHPチュートリアル >PHP がソケットを使用して HTTP リクエストを送信する方法の詳細な説明
PHP プログラマーとして、http プロトコルを深く理解することによってのみ、プログラミング レベルを向上させることができます。最近、PHP での HTTP プログラミングについて学習しており、多くのことが突然明らかになり、多くの恩恵を受けました。皆さんと共有できれば幸いです。この記事は、特定の http 基盤を持つ開発者が読む必要があります。お役に立てれば幸いです。
今日紹介するのは、ソケットを使用して GET リクエストと POST リクエストを送信する方法です。
日常のプログラミングでは、私と同じように、ほとんどの場合ブラウザを使用してサーバーに GET および POST リクエストを行うと思います。では、他の方法を使用して GET および POST リクエストを行うことはできますか?答えは「はい」でなければなりません。 HTTP プロトコルを知っている人なら誰でも、ブラウザがリクエストを送信する本質は、リクエスト情報をサーバーに送信することであることを知っています。このリクエスト情報は、リクエスト行、リクエスト ヘッダー、およびリクエスト本文 (オプション) で構成されます。サーバーはリクエスト情報に基づいてレスポンス情報を返します。接続を解除します。
HTTP リクエストのフォーマットは次のとおりです:
<request-line> <headers> <blank line> [<request-body>]
HTTP レスポンスのフォーマットはリクエストのフォーマットと非常によく似ています:
<status-line> <headers> <blank line> [<response-body>]
HTTP の原理を使用してリクエストを送信でき、ソケットを使用してリクエストを送信することを再考できます。 HTTPリクエストを送信します。
Socketの本来の英語の意味は「穴」または「ソケット」です。一般に「ソケット」とも呼ばれ、IP アドレスとポートを記述するために使用され、通信チェーンへのハンドルであり、異なる仮想マシンまたは異なるコンピューター間の通信を実装するために使用できます。インターネット上のホストは通常、複数のサービス ソフトウェアを実行し、複数のサービスを同時に提供します。各サービスはソケットを開き、異なるポートに異なるサービスにバインドされます。この観点から見ると、ソケットを使用してリモート ファイルを操作することは、ローカル ファイルを読み書きするのと同じくらい簡単です。ローカル ファイルはハードウェアを介して送信され、リモート ファイルはネットワーク ケーブルを介して送信されると考えてください。
したがって、リクエストの送信は、接続の確立 -> ソケット インターフェイスを開く (fsockopen()) -> リクエストの書き込み (fwrite()) -> レスポンスの読み取り (fread() -> Close) とみなすことができます。ファイル ( fclose()) をそのまま使用して、コードに進みましょう:
<?php interface Proto { // 连接url function conn($url); //发送get查询 function get(); // 发送post查询 function post(); // 关闭连接 function close(); } class Http implements Proto { const CRLF = "\r\n"; protected $errno = -1; protected $errstr = ''; protected $response = ''; protected $url = null; protected $version = 'HTTP/1.1'; protected $fh = null; protected $line = array(); protected $header = array(); protected $body = array(); public function __construct($url) { $this->conn($url); $this->setHeader('Host: ' . $this->url['host']); } // 此方法负责写请求行 protected function setLine($method) { $this->line[0] = $method . ' ' . $this->url['path'] . '?' .$this->url['query'] . ' '. $this->version; } // 此方法负责写头信息 public function setHeader($headerline) { $this->header[] = $headerline; } // 此方法负责写主体信息 protected function setBody($body) { $this->body[] = http_build_query($body); } // 连接url public function conn($url) { $this->url = parse_url($url); // 判断端口 if(!isset($this->url['port'])) { $this->url['port'] = 80; } // 判断query if(!isset($this->url['query'])) { $this->url['query'] = ''; } $this->fh = fsockopen($this->url['host'],$this->url['port'],$this->errno,$this->errstr,3); } //构造get请求的数据 public function get() { $this->setLine('GET'); $this->request(); return $this->response; } // 构造post查询的数据 public function post($body = array()) { $this->setLine('POST'); // 设计content-type $this->setHeader('Content-type: application/x-www-form-urlencoded'); // 设计主体信息,比GET不一样的地方 $this->setBody($body); // 计算content-length $this->setHeader('Content-length: ' . strlen($this->body[0])); $this->request(); return $this->response; } // 真正请求 public function request() { // 把请求行,头信息,实体信息 放在一个数组里,便于拼接 $req = array_merge($this->line,$this->header,array(''),$this->body,array('')); //print_r($req); $req = implode(self::CRLF,$req); //echo $req; exit; fwrite($this->fh,$req); while(!feof($this->fh)) { $this->response .= fread($this->fh,1024); } $this->close(); // 关闭连接 } // 关闭连接 public function close() { fclose($this->fh); } }
このクラスを使用して、単純な GET リクエストを送信します:
<?php //记得引用Http类 $url="http://home.***.net/u/DeanChopper/"; $http=new Http($url); $response=$http->get(); print_r($response);
戻り値は情報であり、応答情報をさらに処理することができます。必要なコンテンツを取得します
<?php /** * 使用PHP Socket 编程模拟Http post和get请求 * @author koma */ class Http{ private $sp = "\r\n"; //这里必须要写成双引号 private $protocol = 'HTTP/1.1'; private $requestLine = ""; private $requestHeader = ""; private $requestBody = ""; private $requestInfo = ""; private $fp = null; private $urlinfo = null; private $header = array(); private $body = ""; private $responseInfo = ""; private static $http = null; //Http对象单例 private function __construct() {} public static function create() { if ( self::$http === null ) { self::$http = new Http(); } return self::$http; } public function init($url) { $this->parseurl($url); $this->header['Host'] = $this->urlinfo['host']; return $this; } public function get($header = array()) { $this->header = array_merge($this->header, $header); return $this->request('GET'); } public function post($header = array(), $body = array()) { $this->header = array_merge($this->header, $header); if ( !empty($body) ) { $this->body = http_build_query($body); $this->header['Content-Type'] = 'application/x-www-form-urlencoded'; $this->header['Content-Length'] = strlen($this->body); } return $this->request('POST'); } private function request($method) { $header = ""; $this->requestLine = $method.' '.$this->urlinfo['path'].'?'.$this->urlinfo['query'].' '.$this->protocol; foreach ( $this->header as $key => $value ) { $header .= $header == "" ? $key.':'.$value : $this->sp.$key.':'.$value; } $this->requestHeader = $header.$this->sp.$this->sp; $this->requestInfo = $this->requestLine.$this->sp.$this->requestHeader; if ( $this->body != "" ) { $this->requestInfo .= $this->body; } /* * 注意:这里的fsockopen中的url参数形式为"www.xxx.com" * 不能够带"http://"这种 */ $port = isset($this->urlinfo['port']) ? isset($this->urlinfo['port']) : '80'; $this->fp = fsockopen($this->urlinfo['host'], $port, $errno, $errstr); if ( !$this->fp ) { echo $errstr.'('.$errno.')'; return false; } if ( fwrite($this->fp, $this->requestInfo) ) { $str = ""; while ( !feof($this->fp) ) { $str .= fread($this->fp, 1024); } $this->responseInfo = $str; } fclose($this->fp); return $this->responseInfo; } private function parseurl($url) { $this->urlinfo = parse_url($url); } } // $url = "http://news.***.com/14/1102/01/AA0PFA7Q00014AED.html"; $url = "http://localhost/httppro/post.php"; $http = Http::create()->init($url); /* 发送get请求 echo $http->get(array( 'User-Agent' => 'Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/35.0.1916.153 Safari/537.36', )); */ /* 发送post请求 */ echo $http->post(array( 'User-Agent' => 'Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/35.0.1916.153 Safari/537.36', ), array('username'=>'发一个中文', 'age'=>22));
関連する推奨事項:
PHP がどのように実装するかについての詳細な説明フックの仕組み
詳細 PHP の使い方を理解する 2 つの文字列の最も長い共通部分文字列を見つける
以上がPHP がソケットを使用して HTTP リクエストを送信する方法の詳細な説明の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。