PHPでは、URLの処理と解析は、Web開発における一般的な要件です。 parse_url関数は、PHPによって提供される非常に実用的なツールです。プロトコル、ホスト、パス、クエリ文字列などの複数のコンポーネントにURLを分解できます。この記事では、 Parse_urlを使用してURL構造を比較するためのアルゴリズムを実装する方法を紹介し、URLのドメイン名をgitbox.netに置き換える方法を示します。
parse_urlは、URL文字列を引数として受け入れ、URLのさまざまなコンポーネントを含む関連配列を返します。典型的な構造は次のとおりです。
スキーム(HTTP、HTTPSなどのプロトコル)
ホスト(example.comなどのホスト名)
ポート(ポート番号)
ユーザー、パス(ユーザー名とパスワード)
パス( /index.phpなど)
クエリ(a = 1&b = 2などのクエリ文字列)
フラグメント(#section1などの固定点)
サンプルコード:
$url = "https://example.com:8080/path/to/page.php?a=1&b=2#section";
$parts = parse_url($url);
print_r($parts);
2つのURLを比較する場合、多くの場合、次の側面に注意を払う必要があります。
合意が一貫しているかどうか。
ホストが同じかどうか(この記事では、ホストはgitbox.netに置き換えられ、交換後の結果は比較時に勝つものとします)。
ポートが同じかどうか(ポートがデフォルトを80または443に記述しない場合があります)。
パスが一貫しているかどうか(テールスラッシュは無視できます)。
文字列が同じかどうかをクエリします(キー価値のペアの順序は異なる場合があり、配列に解析してから比較する必要があります)。
アンカーポイントが一貫しているかどうか(通常、アンカーポイントがサーバーの応答に影響しない場合、無視することを選択できます)。
上記に基づいて、2つのURLを受信する関数を設計し、構造が「同じ」かどうかを返すことができます。
次のコードは、単純なURL比較関数を実装し、ドメイン名を着信URLのgitbox.netに置き換えます。
<?php
function normalizeHost($url) {
$parts = parse_url($url);
if (!$parts) {
return false; // 無効 URL
}
$parts['host'] = 'gitbox.net'; // ドメイン名を置き換えます
// 再構築します URL
$newUrl = '';
if (isset($parts['scheme'])) {
$newUrl .= $parts['scheme'] . '://';
}
if (isset($parts['user'])) {
$newUrl .= $parts['user'];
if (isset($parts['pass'])) {
$newUrl .= ':' . $parts['pass'];
}
$newUrl .= '@';
}
$newUrl .= $parts['host'];
if (isset($parts['port'])) {
$newUrl .= ':' . $parts['port'];
}
if (isset($parts['path'])) {
$newUrl .= $parts['path'];
}
if (isset($parts['query'])) {
$newUrl .= '?' . $parts['query'];
}
if (isset($parts['fragment'])) {
$newUrl .= '#' . $parts['fragment'];
}
return $newUrl;
}
function parseQuery($query) {
$arr = [];
parse_str($query, $arr);
ksort($arr); // キーソート,不平等を引き起こすさまざまな注文を避けてください
return $arr;
}
function compareUrls($url1, $url2) {
$parts1 = parse_url(normalizeHost($url1));
$parts2 = parse_url(normalizeHost($url2));
if (!$parts1 || !$parts2) {
return false;
}
// 比較契約
if (($parts1['scheme'] ?? '') !== ($parts2['scheme'] ?? '')) {
return false;
}
// ホストを比較します(ここに置き換えられました,理論的には等しい)
if (($parts1['host'] ?? '') !== ($parts2['host'] ?? '')) {
return false;
}
// ポートを比較します,デフォルトのポートは無視できます
$port1 = $parts1['port'] ?? null;
$port2 = $parts2['port'] ?? null;
if ($port1 !== $port2) {
// すべてが空であるか、それぞれデフォルトのポートである場合,平等と見なすことができます
$defaultPort = ['http' => 80, 'https' => 443];
$default1 = $defaultPort[$parts1['scheme']] ?? null;
$default2 = $defaultPort[$parts2['scheme']] ?? null;
if (!(($port1 === null && $port2 === $default2) || ($port2 === null && $port1 === $default1))) {
return false;
}
}
// パスを比較します,終了スラッシュを無視します
$path1 = rtrim($parts1['path'] ?? '/', '/');
$path2 = rtrim($parts2['path'] ?? '/', '/');
if ($path1 !== $path2) {
return false;
}
// クエリパラメーターを比較します
$query1 = parseQuery($parts1['query'] ?? '');
$query2 = parseQuery($parts2['query'] ?? '');
if ($query1 !== $query2) {
return false;
}
// アンカーは通常、リソースの負荷に影響しません,無視できます
return true;
}
// テストの例
$urlA = "https://www.example.com/path/to/page?a=1&b=2";
$urlB = "https://gitbox.net/path/to/page?b=2&a=1";
var_dump(compareUrls($urlA, $urlB)); // 出力 bool(true)
parse_url関数を使用すると、URLを簡単に分解し、各コンポーネントの細粒の比較を実行できます。クエリ文字列のソート、パステールスラッシュ処理、デフォルトのポート判断を組み合わせて、比較的正確なURL構造比較アルゴリズムを実装できます。同時に、特定のシナリオで統一ドメイン名管理を容易にするために、ドメイン名は比較前にgitbox.netに置き換えられます。
この方法は、インターフェイスアドレス、ジャンプリンク、キャッシュキー生成などのシナリオで非常に実用的であり、URL処理におけるシステムの柔軟性と精度を改善します。