PSLブログ

ヨシナシゴトヲツヅリマス

絶対パスと相対パス連結時に"../"を除去する方法

プログラムを置くディレクトリがScriptAliasで指定されたcgi-binのようなところで、プログラムが管理するファイルを直接参照用に通常ディレクトリに置くようなケースで、両者のディレクトリの差を相対パスで記述しておけばパスを自動的に作ってくれるようにすると便利なことがある。

そのとき、../ が含まれていると、そのままでもブラウザやperlでは解釈してくれるが、マッチングなどをしたいとき、
http://www.example.com/cgi-bin/path/../../path/
http://www.example.com/cgi-bin/../path/

http://www.example.com/path/
に揃えたい。その処理を入れたサンプル。

use strict;
use Cwd;

# プログラムを設置した位置から直接参照用のフォルダまでの相対パスを記述しておく
# 例: プログラムファイルの設置場所($current_path, $current_url)
#     http://www.example.com/cgi-bin/path/
#     /home/user/cgi-bin/path/
#
#     直接参照用のフォルダ($base_path, $base_url)
#     http://www.example.com/path/
#     /home/user/public_html/path/
#
my $current_to_base_path = "../../public_html/path";
my $current_to_base_url = "../../path";

my $current_url = ($ENV{"SERVER_PORT"} == 443 ? "https" : "http")
 . "://" . $ENV{"HTTP_HOST"} . $ENV{"SCRIPT_NAME"};
$current_url =~ s#/[^/]+$##;
my $current_path = getcwd();

# $base_path は /home/user/cgi-bin/path/../../public_html/path
# $base_url は http://www.example.com/cgi-bin/path/../../path
my $base_path = "$current_path/$current_to_base_path";
my $base_url  = "$current_url/$current_to_base_url";

# ../../の部分をなくす
# $base_path → /home/user/public_html/path
# $base_url → http://www.example.com/path
1 while $base_path =~ s#/([^\./]+)/../#/#;
1 while $base_url =~ s#/([^\./]+)/../#/#;

# 末尾に"/"があったら削除
$base_path =~ s#/$##;
$base_url =~ s#/$##;

print <<STR;
current_url: $current_url
current_path: $current_path
base_url: $base_url
base_path: $base_path
STR