anoncom blog
  • ホーム
  • About
KEEP IN TOUCH

PHPで相対パスから絶対URL(URI)を作成する

1月08
2010
Leave a Comment Written by anon
このエントリーをはてなブックマークに追加
はてなブックマーク - PHPで相対パスから絶対URL(URI)を作成する
Share on LinkedIn

HTMLページをパースしてURLを取り出す処理を書いていたのですが、ページ内のリンクなどが全部絶対URLで記述されていれば非常に楽なのですが、現実としてそうでもなく、ページによっては相対パスで書かれていたりして、正規表現で偏にリンクからURLを抜き出すだけではうまくできませんでした。

そこで少しググってみたら

PHPで相対パスから絶対URL(URI)を作成する|PHPプログラムメモ|プログラムメモ

という記事を発見!おぉ、これは便利!
と思って使わせてもらおうと思ったのですが、いくつかテストしてみて、相対パス処理で不備があるなーと思ったところがあったのでちょっと改良させてもらいました。

37~38行目は正直いらない気がしたのですが、 PHP 5.3 のCLIでWindows上でテストした際に、なぜか \/ (アルファベットのVではなく、\ と / ) で出力されたのが気になったので、無駄かもしれないけどあえて記述。
あと $parse の初期化もここまでする必要ないけど、念のためNotice対策を…w

相対パスから絶対URLする関数

< ?php
/**
 * 相対パスから絶対URLを返します
 * 
 * @param string $base ベースURL(絶対URL)
 * @param string $relational_path 相対パス
 * @return string 相対パスの絶対URL
 * @link http://blog.anoncom.net/2010/01/08/295.html
 * @link http://logic.stepserver.jp/data/archives/501.html
 */
function createUri( $base = '', $relational_path = '' ) {
	
	$parse = array (
		'scheme' => null,
		'user' => null,
		'pass' => null,
		'host' => null,
		'port' => null,
		'path' => null,
		'query' => null,
		'fragment' => null,
	);
	$parse = parse_url ( $base );
	
	// パス末尾が / で終わるパターン
	if ( strpos( $parse['path'], '/', ( strlen( $parse['path'] ) - 1 ) ) !== FALSE ) {
		$parse['path'] .= '.';	// ダミー挿入
	}
	if ( preg_match ( '#^https?\://#', $relational_path ) ) {
		// 相対パスがURLで指定された場合
		return $rel_path;
	} elseif ( preg_match ( '#^/.*$#', $relational_path ) ) {
		// ドキュメントルート指定
		return $parse['scheme'] . '://' . $parse ['host'] . $relational_path;
	} else {
		// 相対パス処理
		$basePath = explode ( '/', dirname ( $parse ['path'] ) );
		$relPath = explode ( '/', $relational_path );
		foreach ( $relPath as $relDirName ) {
			if ($relDirName == '.') {
				array_shift ( $basePath );
				array_unshift ( $basePath, '' );
			} elseif ($relDirName == '..') {
				array_pop ( $basePath );
				if ( count ( $basePath ) == 0 ) {
					$basePath = array( '' );
				}
			} else {
				array_push ( $basePath, $relDirName );
			}
		}
		$path = implode ( '/', $basePath );
		return $parse ['scheme'] . '://' . $parse ['host'] . $path;
	}
}


テストケース

ベースURL
 http://example.com/path/to/url

相対パス
  • /
  • /index.html
  • /foo/bar/baz/
  • ./foo/bar/baz
  • ../../../foo/bar/baz/index.html
  • foo/bar/baz.html
  • foo/bar/baz/../index.html

テストコード

< ?php
$base = 'http://example.com/path/to/url';

$pathes[] = '/';
$pathes[] = '/index.html';
$pathes[] = '/foo/bar/baz/';
$pathes[] = './foo/bar/baz';
$pathes[] = '../../../foo/bar/baz/index.html';
$pathes[] = 'foo/bar/baz.html';
$pathes[] = 'foo/bar/baz/../index.html';

foreach ( $pathes as $path ) {
	echo createUri($base, $path) . "\n";
}

結果

こんな感じ

http://example.com/

http://example.com/index.html


http://example.com/foo/bar/baz/


http://example.com/path/to/foo/bar/baz


http://example.com/foo/bar/baz/index.html


http://example.com/path/to/foo/bar/baz.html


http://example.com/path/to/foo/bar/index.html


Related posts:

  1. 簡易クラスローダ
  2. PHPでの簡易文字列の一致の判定
  3. 接続先のサーバが応答するか判別する
Posted in PHP - Tagged PHP, URL
SHARE THIS Twitter Facebook Delicious StumbleUpon E-mail
« PreparedなINSERT文を簡単に作る方法
» ミクの日感謝祭 39′s giving day 初音ミク昼コンサート に行ってきた

No Comments Yet

コメントを残す コメントをキャンセル

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です

*

*

次のHTML タグと属性が使えます: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>

中の人

名前: あのん (anon) anon
詳細

 

2010年1月
日 月 火 水 木 金 土
« 11月   3月 »
 12
3456789
10111213141516
17181920212223
24252627282930
31  

カテゴリー

  • Android
  • iPhone
  • Java
  • Linux
  • Mac
  • PC
  • PHP
  • Twitter
  • VOCALOID
  • イベント
  • サーバ
  • ソフトウェア
  • ネタ
  • ネット
  • モバイル
  • 無分類
  • 話題
  • 開発

アーカイブ

  • 2011年12月
  • 2011年9月
  • 2011年4月
  • 2011年3月
  • 2011年2月
  • 2011年1月
  • 2010年10月
  • 2010年8月
  • 2010年7月
  • 2010年6月
  • 2010年5月
  • 2010年3月
  • 2010年1月
  • 2009年11月
  • 2009年10月
  • 2009年8月
  • 2009年6月
  • 2009年4月
  • 2009年3月
  • 2009年2月
  • 2009年1月
  • 2008年12月
  • 2008年11月
  • 2008年7月
  • 2008年4月

最近の投稿

  • Galaxy Nexusを購入しました
  • さくらのVPSを使いながら行ったウェブサイトの3つの負荷対策
  • PSNの障害と個人情報漏洩について
  • ミクパ♪(初音ミク ライブパーティ 2011)に行ってきたよ
  • FirefoxからChromeに乗り換えてみた

最近のコメント

  • Twitterアカウント名が商標権侵害で訴えられそうになった話 に 2011年2月のこれだけ読めば分かる Web 制作者向け情報まとめ | ウェブル より
  • Twitterアカウント名が商標権侵害で訴えられそうになった話 に 2/1 (火) 前田敦子 豊胸疑惑でネット炎上(画像) | マスコミの気になるニュースをまとめ読み! より
  • Twitterアカウント名が商標権侵害で訴えられそうになった話 に クロネコ より
  • Twitterアカウント名が商標権侵害で訴えられそうになった話 に eamcet*[SEO対策調査自動更新ブログ] | とあるTwitterユーザー、商標権侵害を理由にTwitterアカウント名の変更を求められる より
  • Twitterアカウント名が商標権侵害で訴えられそうになった話 に 心は萌え より

Tweet on Twitter

EvoLve theme by Theme4Press  •  Powered by WordPress anoncom blog