PHPでは、 FSoCopenはネットワーク接続を開くための関数です。これは、特にプロキシサーバーに接続するときに、ソケット接続の作成によく使用されます。 FSOCOPENとデバッグの適切な構成は、スムーズなネットワークリクエストを確保するための鍵です。この記事では、 FSoCopen Connection Proxy Serverを適切に構成し、接続の問題をより適切に見つけて解決するためのデバッグのヒントを提供する方法を紹介します。
FSOCCKOPENは、ネットワーク接続を開くために使用され、HTTP、HTTPS、その他のプロトコルを介してサーバーとの通信をサポートします。基本的な構文は次のとおりです。
<span><span><span class="hljs-title function_ invoke__">fsockopen</span></span><span>(</span><span><span class="hljs-keyword">string</span></span><span> </span><span><span class="hljs-variable">$hostname</span></span><span>, </span><span><span class="hljs-keyword">int</span></span><span> </span><span><span class="hljs-variable">$port</span></span><span> = </span><span><span class="hljs-number">0</span></span><span>, </span><span><span class="hljs-keyword">int</span></span><span> &</span><span><span class="hljs-variable">$errno</span></span><span> = </span><span><span class="hljs-literal">null</span></span><span>, </span><span><span class="hljs-keyword">string</span></span><span> &</span><span><span class="hljs-variable">$errstr</span></span><span> = </span><span><span class="hljs-literal">null</span></span><span>, </span><span><span class="hljs-keyword">float</span></span><span> </span><span><span class="hljs-variable">$timeout</span></span><span> = </span><span><span class="hljs-title function_ invoke__">ini_get</span></span><span>(</span><span><span class="hljs-string">"default_socket_timeout"</span></span><span>))
</span></span>
$ hostname :ターゲットホストのアドレスまたはプロキシサーバーのアドレス。
$ポート:ターゲットサーバーのポート番号、デフォルトのHTTPは80、デフォルトのHTTPSは443です。
$ errno :接続エラーのエラーコード。
$ errstr :エラーメッセージ。
$タイムアウト:接続タイムアウト、ユニット秒。
プロキシサーバーを介してターゲットホストに接続するには、最初にプロキシサーバーのIPアドレスとポートを介して接続を確立する必要があります。一般的に言えば、プロキシサーバーでは、特定の認証情報(ユーザー名やパスワードなど)を提供する必要があるため、プロキシ設定の正しさを確保する必要があります。
プロキシサーバーを介してリモートホストに接続する方法を示す簡単な例を次に示します。
<span><span><span class="hljs-variable">$proxy</span></span><span> = </span><span><span class="hljs-string">'proxy.example.com'</span></span><span>; </span><span><span class="hljs-comment">// プロキシサーバーアドレス</span></span><span>
</span><span><span class="hljs-variable">$proxy_port</span></span><span> = </span><span><span class="hljs-number">8080</span></span><span>; </span><span><span class="hljs-comment">// プロキシポート</span></span><span>
</span><span><span class="hljs-variable">$target</span></span><span> = </span><span><span class="hljs-string">'example.com'</span></span><span>; </span><span><span class="hljs-comment">// ターゲットホスト</span></span><span>
</span><span><span class="hljs-variable">$target_port</span></span><span> = </span><span><span class="hljs-number">80</span></span><span>; </span><span><span class="hljs-comment">// ターゲットポート</span></span><span>
</span><span><span class="hljs-comment">// プロキシサーバーに接続します</span></span><span>
</span><span><span class="hljs-variable">$proxy_socket</span></span><span> = </span><span><span class="hljs-title function_ invoke__">fsockopen</span></span><span>(</span><span><span class="hljs-variable">$proxy</span></span><span>, </span><span><span class="hljs-variable">$proxy_port</span></span><span>, </span><span><span class="hljs-variable">$errno</span></span><span>, </span><span><span class="hljs-variable">$errstr</span></span><span>, </span><span><span class="hljs-number">30</span></span><span>);
</span><span><span class="hljs-keyword">if</span></span><span> (!</span><span><span class="hljs-variable">$proxy_socket</span></span><span>) {
</span><span><span class="hljs-keyword">echo</span></span><span> </span><span><span class="hljs-string">"无法プロキシサーバーに接続します: <span class="hljs-subst">$errstr</span></span></span><span> (</span><span><span class="hljs-subst">$errno</span></span><span>)\n";
} </span><span><span class="hljs-keyword">else</span></span><span> {
</span><span><span class="hljs-comment">// プロキシリクエストを送信します</span></span><span>
</span><span><span class="hljs-variable">$request</span></span><span> = </span><span><span class="hljs-string">"GET http://<span class="hljs-subst">$target</span></span></span><span>/ HTTP/1.1\r\n";
</span><span><span class="hljs-variable">$request</span></span><span> .= </span><span><span class="hljs-string">"Host: <span class="hljs-subst">$target</span></span></span><span>\r\n";
</span><span><span class="hljs-variable">$request</span></span><span> .= </span><span><span class="hljs-string">"Connection: Close\r\n"</span></span><span>;
</span><span><span class="hljs-variable">$request</span></span><span> .= </span><span><span class="hljs-string">"\r\n"</span></span><span>;
</span><span><span class="hljs-title function_ invoke__">fwrite</span></span><span>(</span><span><span class="hljs-variable">$proxy_socket</span></span><span>, </span><span><span class="hljs-variable">$request</span></span><span>);
</span><span><span class="hljs-comment">// プロキシサーバーの応答を取得します</span></span><span>
</span><span><span class="hljs-keyword">while</span></span><span> (!</span><span><span class="hljs-title function_ invoke__">feof</span></span><span>(</span><span><span class="hljs-variable">$proxy_socket</span></span><span>)) {
</span><span><span class="hljs-keyword">echo</span></span><span> </span><span><span class="hljs-title function_ invoke__">fgets</span></span><span>(</span><span><span class="hljs-variable">$proxy_socket</span></span><span>, </span><span><span class="hljs-number">128</span></span><span>);
}
</span><span><span class="hljs-title function_ invoke__">fclose</span></span><span>(</span><span><span class="hljs-variable">$proxy_socket</span></span><span>);
}
</span></span>
プロキシサーバーが認証を必要とする場合、リクエストを送信するときに対応する認証情報を提供する必要があります。通常、プロキシ認証は基本認証またはその他の認証メカニズムを使用します。
承認ヘッダーを使用して、基本認証を実現できます。
<span><span><span class="hljs-variable">$username</span></span><span> = </span><span><span class="hljs-string">'my_username'</span></span><span>;
</span><span><span class="hljs-variable">$password</span></span><span> = </span><span><span class="hljs-string">'my_password'</span></span><span>;
</span><span><span class="hljs-comment">// ユーザー名とパスワードを作成します Base64 コーディング</span></span><span>
</span><span><span class="hljs-variable">$auth</span></span><span> = </span><span><span class="hljs-title function_ invoke__">base64_encode</span></span><span>(</span><span><span class="hljs-string">"<span class="hljs-subst">$username</span></span></span><span>:</span><span><span class="hljs-subst">$password</span></span><span>");
</span><span><span class="hljs-variable">$request</span></span><span> = </span><span><span class="hljs-string">"GET http://<span class="hljs-subst">$target</span></span></span><span>/ HTTP/1.1\r\n";
</span><span><span class="hljs-variable">$request</span></span><span> .= </span><span><span class="hljs-string">"Host: <span class="hljs-subst">$target</span></span></span><span>\r\n";
</span><span><span class="hljs-variable">$request</span></span><span> .= </span><span><span class="hljs-string">"Connection: Close\r\n"</span></span><span>;
</span><span><span class="hljs-variable">$request</span></span><span> .= </span><span><span class="hljs-string">"Proxy-Authorization: Basic <span class="hljs-subst">$auth</span></span></span><span>\r\n";
</span><span><span class="hljs-variable">$request</span></span><span> .= </span><span><span class="hljs-string">"\r\n"</span></span><span>;
</span><span><span class="hljs-comment">// リクエストを送信します</span></span><span>
</span><span><span class="hljs-title function_ invoke__">fwrite</span></span><span>(</span><span><span class="hljs-variable">$proxy_socket</span></span><span>, </span><span><span class="hljs-variable">$request</span></span><span>);
</span></span>
プロキシサーバー接続を確認してください<br> プロキシサーバーに接続できない状況に遭遇した場合は、最初にプロキシサーバーに到達可能かどうかを確認します。 PingやTelnetなどのコマンドラインツールを使用して、接続が正常かどうかをテストできます。例えば:
<span><span>ping proxy.example.com
telnet proxy.example.com 8080
</span></span>
デバッグ情報を印刷<BR> PHPでは、 var_dumpまたはechoを使用して、リクエストと応答のコンテンツを印刷して、プロキシリクエストが正常に送信されるかどうかをデバッグするのに役立ちます。予期しないエラーメッセージまたは応答コンテンツを確認することもできます。
<span><span><span class="hljs-keyword">echo</span></span><span> </span><span><span class="hljs-string">"送信されたリクエスト:\n"</span></span><span> . </span><span><span class="hljs-variable">$request</span></span><span>;
</span><span><span class="hljs-keyword">echo</span></span><span> </span><span><span class="hljs-string">"応答コンテンツ:\n"</span></span><span>;
</span></span>
合理的なタイムアウトを設定します<br> 接続時間が長すぎると、タイムアウト時間を適切に増加または短縮できます。過度に長いタイムアウトにより、リクエストが遅くなる可能性がありますが、過度に短いタイムアウトにより、ネットワークの遅延により接続が失敗する可能性があります。
<span><span><span class="hljs-variable">$timeout</span></span><span> = </span><span><span class="hljs-number">10</span></span><span>; </span><span><span class="hljs-comment">// 接続タイムアウトをに設定します 10 2番</span></span><span>
</span></span>
プロキシサーバーログ<br>を確認してください PHPコードから直接問題を見つけることができない場合は、プロキシサーバーのログファイルをチェックすることは良い方法です。プロキシサーバーは通常、接続が成功したかどうか、認証が必要かどうかなど、リクエストの詳細を記録します。
fsocckopenの代わりにstream_socket_clientを使用します
接続とデータフローをより柔軟に処理する場合は、 FSOCKOPENの代わりにStream_Socket_Clientを使用できます。これは、より豊富なパラメーター設定をサポートし、複雑なネットワークリクエストをより適切に処理できます。
例:
<span><span><span class="hljs-variable">$context</span></span><span> = </span><span><span class="hljs-title function_ invoke__">stream_context_create</span></span><span>([
</span><span><span class="hljs-string">'http'</span></span><span> => [
</span><span><span class="hljs-string">'proxy'</span></span><span> => </span><span><span class="hljs-string">'tcp://proxy.example.com:8080'</span></span><span>,
</span><span><span class="hljs-string">'request_fulluri'</span></span><span> => </span><span><span class="hljs-literal">true</span></span><span>,
]
]);
</span><span><span class="hljs-variable">$file</span></span><span> = </span><span><span class="hljs-title function_ invoke__">fopen</span></span><span>(</span><span><span class="hljs-string">'http://example.com'</span></span><span>, </span><span><span class="hljs-string">'r'</span></span><span>, </span><span><span class="hljs-literal">false</span></span><span>, </span><span><span class="hljs-variable">$context</span></span><span>);
</span></span>
プロキシ接続タイムアウト<br> 接続タイムアウトは通常、ネットワーク条件またはプロキシサーバーの構成に関連しています。この問題は、タイムアウトを増やすか、別のプロキシサーバーを交換することで解決できます。
エージェント認証に失敗しました<BR> 認証情報、特にユーザー名とパスワードのbase64エンコードが正しいことを確認してください。他のタイプの認証(NTLMやダイジェストなど)を使用している場合、追加のサポートライブラリまたはそれを処理するためのより複雑なアプローチが必要です。
応答コンテンツが空です、またはフォーマットが正しくありません<br> この状況は、プロキシサーバーがリクエストを正しく転送していないか、ターゲットサーバーにプロキシを介してアクセスできないためである可能性があります。プロキシサーバーのデバッグログを使用するか、Postmanなどの他のネットワークツールを使用してプロキシサーバーの動作を確認できます。