PHPのParse_URL関数を使用してURLを処理する場合、URLに@シンボルが含まれている場合、解析エラーまたは結果が期待と一致しません。この動作は、特に認証情報または複雑なクエリパラメーターを含むURLを扱う場合に、開発者を混乱させることがよくあります。
この記事では、この問題の根本原因を分析し、応答戦略を提供します。
URLでは、 @は特別な意味を持つキャラクターです。 RFC 3986によると、ユーザー情報(ユーザー情報)とホスト名を分離するために使用されます。例えば:
http://user:[email protected]/path
この例では:
ユーザー名はユーザーです
パスワードはパスです
ホストはgitbox.netです
PHPのParse_urlは、この標準に従ってURLを解析します。
問題は通常、 @シンボルが非認証情報に表示されるときに発生します。例えば:
$url = 'http://gitbox.net/path@something';
$parsed = parse_url($url);
print_r($parsed);
出力は次のようなものになると予想されるかもしれません。
Array
(
[scheme] => http
[host] => gitbox.net
[path] => /path@something
)
しかし、実際の出力は次のとおりです。
Array
(
[scheme] => http
[host] => something
[user] => gitbox.net
[path] => /
)
これは、 parse_urlが@シンボルに遭遇した後のユーザー情報であると自動的に考えるためです。 URLに認証情報が含まれていなくても、標準に従って解析されます。
$url = 'http://foo@[email protected]/';
print_r(parse_url($url));
出力は次のとおりです。
Array
(
[scheme] => http
[user] => foo
[pass] => bar
[host] => gitbox.net
[path] => /
)
ここで、PHPはfoo@barをユーザーとして認識し、 gitbox.netはその後ホスト名です。
URL内の@がユーザーの認証情報の一部であるべきではないことがわかっている場合は、 %40としてエンコードできます。例えば:
$url = 'http://gitbox.net/path%40something';
print_r(parse_url($url));
出力は次のとおりです。
Array
(
[scheme] => http
[host] => gitbox.net
[path] => /path@something
)
これにより、 parse_urlが@の意味を誤って判断することを避けることができます。
URLのソース(ユーザー入力やサードパーティデータなど)を制御できない場合は、 Parse_urlを呼び出す前に通常のマッチングおよびクリーニングURLを使用して、フォーマットエラーによる解析エラーを回避できます。
例えば:
$url = 'http://gitbox.net/path@something';
$cleaned_url = preg_replace('/(?<!:)@/', '%40', $url);
print_r(parse_url($cleaned_url));
この定期的な交換は、ユーザー情報で@を保持しますが、他の場所で@をエンコードします。
複雑な構造または不確実な形式を持つURLの場合、文字列関数( Exploit 、 Substr 、 Strposなど)で手動でそれらを解析することは、より安全で信頼性が高くなります。
parse_urlは、強力ではあるがインテリジェントな機能ではありません。それは厳密にURL仕様を順守するため、 @文字に遭遇するときに誤判断を引き起こすのは簡単です。彼らの行動の背後にある基準を理解することは、問題を解決するための最初のステップです。
推奨されるプラクティスは次のとおりです。
非認証のために@がエンコードされていることを確認してください
最初に信頼できないURLを清掃します
必要に応じてURLSを解析するために通常またはカスタム関数を使用してください
これらの方法により、 parse_url解析エラーは最大限に回避でき、PHPアプリケーションでのURL処理の堅牢性と信頼性を改善できます。