2016年12月15日 : してログ

スマホで撮っていたスナップショットから作成しました。twitter 配信テストで何か上げようと思っても、最近まともに撮影していないので素材が無いんですよね。今年はもう捨ててますが、来年はもうちょっと頑張ってみようと新年の抱負に願ってみます。

10/30 加茂市
iPhone6s+(AutoBracket HDR)
JPG×3→Photomatix / Topaz Simplify / Photoshop
Tags #植物 #モミジ #落ち葉

相対 URL を絶対 URL に解消する関数を探したのですが、ぴったりのものが見つからないので自分で作ってみました。ただし、簡単そうにみえて難しい部類なので、あらゆるパターンで完璧かどうかは保証できません。なお、HTML を処理すると言っても、<a>、<img> の2つのみが処理対象になっています。他のタグを含めるには、正規表現のパターンを追加してください。

ソースコード
function html_absolute_url($base,$html) {

	return preg_replace_callback(

		'/(<a\s+.*?href=")(.+?)(".*?>)'.
		'|(<a\s+.*?href=\')(.+?)(\'.*?>)'.
		'|(<img\s+.*?src=")(.+?)(".*?>)'.
		'|(<img\s+.*?src=\')(.+?)(\'.*?>)/',

		create_function(
			'$matches',
			'$base = unserialize(\''.serialize($base).'\');'.
			'$n = (count($matches)-1)/3-1;'.
			'$url = $matches[$n*3+2];'.
			'$url = absolute_url($base,$url);'.
			'return $matches[$n*3+1].$url.$matches[$n*3+3];'
		),

		$html
	);

}

function absolute_url($base,$url) {

	if (substr($base,-1)!='/') $base.='/';

	$pbase = parse_url($base);

	$purl = parse_url($url);

	if (!isset($purl['scheme'])) {
		if (!isset($purl['host'])) {
			// スキームとホストが省略されている
			if (substr($url,0,1)=='/') {
				// 絶対URL
				$url = $pbase['scheme'].'://'.$pbase['host'].$url;
			} else {
				// 相対URLと判定(./と../の解消は行わない)
				$url = $base.$url;
			}
		} else {
			// スキームのみ省略されている
			$url = $pbase['scheme'].':'.$url;
		}
	} else {
		// 完全なURLと判定
	}

	return $url;
}

html_absolute_url が HTML を処理する関数で、absolute_url が URL を個別に処理する関数です。PHP5.3 未満に対応するために、preg_replace_callback のコールバック関数でクロージャを使用しておらず、変数の値を無理やり展開して渡しています。また、正規表現の中でシングルとダブルクオーテーションをそれぞれ記述していますが、まとめてうまく表現できないものかと思います。もっとスマートに書ける人がいたら、教えて欲しいです。