PHPの標準関数を利用してURLパラメーターを解析・生成する方法をまとめます。
URL解析
(1)URLを解析する前の下準備
URLを解析する場合、まず最初にURLデコードする必要があります。
URLデコード関数はurldecode()関数でデコードできます。
RFC3986に基づいたエンコード(rawurlencode()関数でエンコードしたURL)の場合はrawurldecode()関数でデコードします。
※デコードの厳密な検証はできていないので後日検証する予定。
$url = 'https://www.amazon.co.jp/GitHub%E5%AE%9F%E8%B7%B5%E5%85%A5%E9%96%80-Pull-Request%E3%81%AB%E3%82%88%E3%82%8B%E9%96%8B%E7%99%BA%E3%81%AE%E5%A4%89%E9%9D%A9-PRESS-plus/dp/477416366X?pd_rd_w=xxxx&pf_rd_p=yyyy&pf_rd_r=zzzz&pd_rd_r=aaaa&pd_rd_wg=bbbb&ref_=pd_gw_wish';
$url_decode = urldecode($url);
echo $url_decode . PHP_EOL;
// https://www.amazon.co.jp/GitHub実践入門-Pull-Requestによる開発の変革-PRESS-plus/dp/477416366X?pd_rd_w=xxxx&pf_rd_p=yyyy&pf_rd_r=zzzz&pd_rd_r=aaaa&pd_rd_wg=bbbb&ref_=pd_gw_wish
(2)URLを解析して構成要素を取得
parse_url()関数を利用すると取得できます。
第二パラメーターにPHP_URL_SCHEME、PHP_URL_HOST、PHP_URL_PORT、PHP_URL_USER、PHP_URL_PASS、PHP_URL_PATH、PHP_URL_QUERY、PHP_URL_FRAGMENTのいずれかを指定することで特定コンポーネントのみ取得することもできます。
$url2 = parse_url($url_decode);
print_r($url2);
/*
Array
(
[scheme] => https
[host] => www.amazon.co.jp
[path] => /GitHub実践入門-Pull-Requestによる開発の変革-PRESS-plus/dp/477416366X
[query] => pd_rd_w=xxxx&pf_rd_p=yyyy&pf_rd_r=zzzz&pd_rd_r=aaaa&pd_rd_wg=bbbb&ref_=pd_gw_wish
)
*/
// ホスト名のみ取得
echo parse_url($url_decode, PHP_URL_HOST) . PHP_EOL;
// www.amazon.co.jp
(3)クエリ文字列を配列化
parse_str()関数でクエリ文字列を配列化します。
エンコード処理はされるようですが、半角空白がハイフンになってしまうので挙動が怪しいので事前にエンコードしておいた方がよいと思います。
$params = [];
$url_str = parse_str($url2['query'], $params);
print_r($params);
/*
Array
(
[https://www_amazon_co_jp/GitHub実践入門-Pull-Requestによる開発の変革-PRESS-plus/dp/477416366X?pd_rd_w] => xxxx
[pf_rd_p] => yyyy
[pf_rd_r] => zzzz
[pd_rd_r] => aaaa
[pd_rd_wg] => bbbb
[ref_] => pd_gw_wish
)
*/
クエリ文字列の生成
配列からクエリパラメーターを生成する場合、http_build_query()関数で実現できます。
$params = [];
$params['ja_text'] = '日本語テキスト';
$params['color'] = 'blue';
$params['size'] = 'M';
echo http_build_query($params);
// ja_text=%E6%97%A5%E6%9C%AC%E8%AA%9E%E3%83%86%E3%82%AD%E3%82%B9%E3%83%88&color=blue&size=M
自動的にエンコードされますが、第4パラメーターで指定できます。
デフォルトはPHP_QUERY_RFC1738が設定され、RFc1738に基づいてエンコードされます。
PHP_QUERY_RFC3986を指定することでRFC3986に基づいたエンコードをすることができます。