とあるURLの相対パス(./ とか ../../hoge/ とか)から絶対URL(http://〜〜)の情報を取得したいような場合、PHPではそのような関数などはないため、自力でなんとか解決しなければなりません。
自分のために作ったけど、自分のための備忘録代わりに投稿しておきます。
ソースは以下の通り。
<?php $baseURL = 'http://www.example.com/hoge/fuga/'; $relativePath = './../foo/test.php'; echo getAbsURL($baseURL, $relativePath); // ベースURL と 相対パス情報から、絶対パス(http(s)://〜〜)を返す function getAbsURL($baseURL, $relativePath) { if ($relativePath == '') { // 相対パスが空の場合は、baseURLをそのまま返す return $baseURL; } if (preg_match('@^https?://@iD', $relativePath)) { // 相対パスが http(s):// から始まる場合は、そのまま返す return $relativePath; } // baseURL の分解 if (!preg_match('@^(https?://[^/]+)/?(.*)$@iD', $baseURL, $tmpMatches)) { // http(s)://〜〜から始まらない場合 if ($baseURL[0] != '/') { return false; } $tmpMatches = array( $baseURL, '', substr($baseURL, 1) ); } $base = $tmpMatches[1]; // e.g. http://www.example.com $tmpPath = $tmpMatches[2]; // e.g. hoge/fuga/index.php $path = array(); if (preg_match('@^/@iD', $relativePath)) { // 相対パスが/から始まる場合 return $base . $relativePath; } // baseURLパス情報にディレクトリが含まれていれば // baseURLのパス情報をディレクトリ情報のみに if (strlen($tmpPath) > 0 && strpos($tmpPath, '/') !== false) { if ($tmpPath[strlen($tmpPath) - 1] == '/') { // 最後が / なら/を削除 $tmpPath = substr($tmpPath, 0, -1); } else { // 最後が / ではない(ファイル名)の場合、/ までを削除 $tmpPath = substr($tmpPath, 0, strrpos($tmpPath, '/')); } // ディレクトリ名毎に配列にする $path = explode('/', $tmpPath); } // 相対パス情報をディレクトリ毎に配列にする $relativePath = explode('/', $relativePath); // 相対パスディレクトリ毎に foreach($relativePath as $dir) { if ($dir == '.') { // /./ は処理をスキップ continue; } if (preg_match('@^\.+$@iD', $dir)) { // /../ /.../ などなら、ディレクトリを上にたどる for ($i=1; $i < strlen($dir); $i++) { array_pop($path); } continue; } // .以外のディレクトリ名の場合は、そのまま追加 $path[] = $dir; } // パスを/で結合 $path = implode('/', $path); return $base . '/' . $path; }
以上。