PHP fsockopen は比較的強力な関数です。この記事では、この機能について詳しく紹介しますので、皆様のお役に立てれば幸いです。以前のB2C Webサイトではこの機能を利用してフロントと注文処理システムのやりとりを実現していたと記憶しています。
PHP fsockopen 関数の説明:
構文:
resource fsockopen ( string $hostname [, int KaTeX 解析エラー: 'EOF' が予期されましたが、位置 20 で '&' を取得しました: … = -1 [, int &̲errno [, string &$errstr [, float $timeout = ini_get(“default_socket_timeout”) ]]]] )
PHP fsockopen 関数を有効にする
PHP fsockopen PHP.ini のallow_url_fopen オプションをオンにする必要があります。
allow_url_fopen = On
パラメータ:
hostname: OpenSSL がインストールされている場合は、ホスト名アドレスの前にアクセス プロトコル ssl:// または tls:// を追加して、 TCP/IP プロトコルに基づく SSL または TLS クライアントはリモート ホストに接続します。
ポート: ポート番号。このパラメータに -1 が渡された場合、unix:// などのポートが使用されないことを意味します。
errno: errno の戻り値が 0 で、この関数の戻り値が FALSE の場合、ソケット接続 (connect()) 呼び出しの前にエラーが発生したことを示します。これが最大の原因です。ソケットの初期化時にエラーが発生した可能性があります。
errstr: エラー メッセージは文字列として返されます。
timeout: 接続の制限時間を秒単位で設定します。
戻り値:
fsockopen() はファイル ハンドルを返します。これは後で他のファイル クラス関数 (例: fgets()、fgetss()、fwrite()、 fclose() feof()) もあります。呼び出しが失敗した場合は、FALSE が返されます。
php fsockopen の使用例
1. HTTP 接続の生成をシミュレートする fsockopen
<?php $fp = fsockopen("127.0.0.1",80,$errno,$errstr,30); if(!$fp){ echo "$errstr ($errno)<br />\n"; }else{ $out = "GET / HTTP/1.1\r\n"; $out .= "Host: 127.0.0.1\r\n"; $out .= "Connection: Close\r\n\r\n"; fwrite($fp,$out); $content = ''; while(!feof($fp)){ $content .= fgets($fp,128); } echo $content; fclose($fp); } ?>
実行結果:
2. PHP fsockopen は POST/GET メソッドをシミュレートします
fsockopen は、上記の例のような HTTP 接続の生成をシミュレートするだけでなく、post メソッドや get メソッドのシミュレートなど、多くの関数を実装することもできます。データの送信について。
get :
<?php $url = "http://localhost/test2.php?site=www.tbrer.com"; print_r(parse_url($url));// 解析 URL,返回其组成部分 /* get提交 */ sock_get($url,'user=gonn'); // fsocket模拟get提交 function sock_get($url,$query){ $data = array( 'foo' => 'bar', 'baz' => 'boom', 'site' => 'www.tbrer.com', 'name' => 'nowa magic' ); $query_str = http_build_query($data);// http_build_query()函数的作用是使用给出的关联(或下标)数组生成一个经过 URL-encode 的请求字符串 $info = parse_url($url); $fp = fsockopen($info["host"],80,$errno,$errstr,30); $head = "GET " . $info['path'] . '?' . $query_str . " HTTP/1.0\r\n"; $head .= "Host: " . $info['host'] . "\r\n"; $head .= "\r\n"; $write = fputs($fp,$head); while(!feof($fp)){ $line = fread($fp,4096); echo $line; } } ?>
post :
<?php $url = "http://localhost/test2.php?site=www.tbrer.com"; print_r(parse_url($url));// 解析 URL,返回其组成部分 /* get提交 */ sock_post($url,'user=gonn'); // fsocket模拟get提交 function sock_post($url,$query){ $info = parse_url($url); $fp = fsockopen($info["host"],80,$errno,$errstr,30); $head = "POST " . $info['path'] . "?" . $info["query"] . " HTTP/1.0\r\n"; $head .= "Host: " . $info['host'] . "\r\n"; $head .= "Referer: http://" . $info['host'] . $info['path'] . "\r\n"; $head .= "Content-type: application/x-www-form-urlencoded\r\n"; $head .= "Content-Length: ". strlen(trim($query)) . "\r\n"; $head .= "\r\n"; $head .= trim($query); $write = fputs($fp,$head); while(!feof($fp)){ $line = fread($fp,4096); echo $line; } } ?>
ページ test2.php を受信するコードは次のとおりです:
<?php $data = $_REQUEST; echo '<pre class="brush:php;toolbar:false">'; print_r($data); echo ''; ?>
3. fsockopen はソケット モードで HTTP ダウンロード ファイルをシミュレートします
<?php /* * Socket 模拟HTTP协议传输文件 * Http是应用层协议使用80端口 */ $hostname = '127.0.0.1'; $port = '80'; // 建立连接 $fp = fsockopen($hostname,$port,$errno,$errstr); stream_set_blocking($fp,true); if(!$fp){ echo "$errno : $errstr<br />"; }else{ // 发送一个HTTP请求信息头 $request_header = "GET /aaa.txt"; // 起始行 // 头域 $request_header .= "Host: $hostname\n"; // 再一个回车换行表示头信息结束 $request_header .= "\n"; // 发送请求到服务器 fputs($fp,$request_header); // 接受响应 $fp2 = fopen('aaa.txt','w'); while(!feof($fp)){ $line = fputs($fp2,fgets($fp,128)); echo $line; } // 关闭 fclose($fp2); fclose($fp); } ?>
プログラムを実行すると、ダウンロードする必要のあるファイルがプログラム ファイルと同じレベルのディレクトリに表示されることがわかります。
これは本質的に、ファイルを転送するための HTTP プロトコルをシミュレートするソケットです。同時に、PHP のタイムアウト制限にも注意してください。ここでは、正しくダウンロードするために PHP サーバーのタイムアウトを無制限に設定しています。そうしないと、ダウンロードが完了せず、PHP プログラムが停止してしまう可能性があります。
注:
bool stream_set_blocking (resource $stream, int $mode)
ストリームのブロックまたはブロック モードを設定します。
この関数は、ノンブロッキング モードをサポートする任意のリソース ストリーム (通常のファイル、ソケット リソース ストリームなど) で動作します。
パラメータ
stream: リソース ストリーム。
mode: mode が 0 の場合、リソース フローはノンブロッキング モードに変換され、1 の場合、リソース フローはブロッキング モードに変換されます。このパラメータの設定は、リソース ストリームからデータを読み取る fgets() や fread() などの関数に影響します。非ブロッキング モードでは、 fgets() を呼び出すと常にすぐに戻りますが、ブロッキング モードでは、リソース ストリームからデータが取得されるまで待ってから戻ります。
戻り値
成功した場合は TRUE を返し、失敗した場合は FALSE を返します。
4. fsockopen を使用してソースを偽造する
<?php $host = "127.0.0.1"; //你要访问的域名 $ip = '127.0.0.1'; $target = "/test2.php"; //你要访问的页面地址 $referer = "http://www.tbrer.com/"; //伪造来路页面 //$fp = fsockopen($host, 80, $errno, $errstr, 30); $fp = fsockopen($ip, 80, $errno, $errstr, 30); if(!$fp) { echo "$errstr($errno)<br />\n"; } else { $end = "\r\n"; $out = "GET $target HTTP/1.1$end"; $out .= "Host: $ip$end"; $out .= "Referer: $referer$end"; $out .= "Connection: Close$end"; $out .= "$end"; fwrite($fp, $out); while(!feof($fp)) { echo fgets($fp, 1024); } fclose($fp); } ?>
test2.php のコードは次のとおりです:
<?php $data = $_REQUEST; echo '<pre class="brush:php;toolbar:false">'; print_r($data); echo ''; ?>
HTTP_REFERER の値が http://www であることがわかります。 .tribrer.com /、つまり、オリジンは正常に偽造されました。
関連する推奨事項:
PHP ビデオ チュートリアル: https://www.php.cn/course/list/29/type/2.html
以上がPHPのfsockopen関数の詳しい説明の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。