URLの解析

構成要素への分解

parse_url()でURLを要素に分解できます。

mixed parse_url(
    string $url
    [, int $component = -1 ]
    )
PHP: parse_url - Manual

$urlだけを指定すると、結果は配列で返されます。

$url = 'http://username:password@hostname.com/dir/index.html?arg=value#anchor';

print_r( parse_url( $url ) );
// Array
// (
//     [scheme] => http
//     [host] => hostname.com
//     [user] => username
//     [pass] => password
//     [path] => /dir/index.html
//     [query] => arg=value
//     [fragment] => anchor
// )

第2引数の$componentには、次にいずれかを指定できます。

  • PHP_URL_SCHEME
  • PHP_URL_HOST
  • PHP_URL_PORT
  • PHP_URL_USER
  • PHP_URL_PASS
  • PHP_URL_PATH
  • PHP_URL_QUERY
  • PHP_URL_FRAGMENT

そうすると、指定した要素だけが文字列で返されます。

$url = 'http://hostname.com/dir';

echo parse_url( $url, PHP_URL_HOST );
// hostname.com

この関数はURLの正当性を考慮しないため、不正なURLであってもそれなりの結果を返します。

$url = 'abc://**.com...&&/1/2';

print_r( parse_url( $url ) );
// Array
// (
//     [scheme] => abc
//     [host] => **.com...&&
//     [path] => /1/2
// )

空文字列をパースすると、空文字列の'path'が返されます。

$a = parse_url( '' );

print_r( $a );
// Array
// (
//     [path] =>
// )

echo ( $a[ 'path' ] === '' )? 1 : 0; // 1

取得する構成要素を指定して無効な文字列をパースすると、NULLが返されます。

$a = parse_url( 'foo', PHP_URL_SCHEME );
echo ( $a === NULL )? 1 : 0; // 1

これとは逆に、クエリを結合するにはhttp_build_query()があります。

相対URLから絶対URLへの変換

相対URLから絶対URLへ変換するコードを以下に示します。

function RelToAbs( $baseUrl, $url )
{
    if( $url == '' ) return $baseUrl;

    // すでに絶対URLならば、それを返す
    if( parse_url( $url, PHP_URL_SCHEME ) != NULL ) return $url;

    // ベースURLをパースする
    $parsedUrl = parse_url( $baseUrl );
    $path = $parsedUrl[ 'path' ];

    if( $url[ 0 ] == '/' )
    {
        // URLがルートからの相対ならば、パスを削除する
        $path = '';
    }
    else if( $url[ 0 ] != '#' && $url[ 0 ] != '?' )
    {
        // パスからディレクトリ以外を削除
        $path = preg_replace( '#/[^/]*$#', '', $path ).'/';
    }
    $path .= $url;

    // '//'、'/./'または'/foo/../'ならば、'/'に置換する
    $pattern = array( '#/\.?/#', '#/(?!\.\.)[^/]+/\.\./#' );
    do{
        $path = preg_replace( $pattern, '/', $path, -1, $count );
    } while( 0 < $count );

    return $parsedUrl[ 'scheme' ].'://'.$parsedUrl[ 'host' ].$path;
}
parsing - Transfrom relative path into absolute URL using PHP - Stack Overflow
実行結果
引数 戻り値
$baseUrl $url
http://example.com/   http://example.com/
http://example.com/ / http://example.com/
http://example.com/a/b/sample.txt index.html http://example.com/a/b/index.html
http://example.com/a/b/sample.txt /index.html http://example.com/index.html
http://example.com/a/b/sample.txt index.html?a=b http://example.com/a/b/index.html?a=b
http://example.com/a/b/sample.txt index.html#bar http://example.com/a/b/index.html#bar
http://example.com/a/b/sample.txt ./ http://example.com/a/b/
http://example.com/a/b/sample.txt ../ http://example.com/a/
http://example.com/a/b/sample.txt ../../ http://example.com/
http://example.com/a/b/sample.txt ../AAA/ http://example.com/a/AAA/
http://example.com/a/b/sample.txt?b=2 ?a=1 http://example.com/a/b/sample.txt?a=1
http://example.com/a/b/sample.txt#B #A http://example.com/a/b/sample.txt#A
http://example.com/a/b/sample.txt#B index.html#A http://example.com/a/b/index.html#A
PHPのマニュアルから検索