phpで自分のURLを取得する方法がよくわからなかったので殴り書きメモ。
まず自分のphpのどこかに書いておく方法がある。しかしこれだとサーバー引越しとかしたとき直さないといけなくなるのでここでは無視。
基本に返ってブラウザがどうやってアクセスするかを確認。ブラウザがhttp://www.example.com/ddd/fff.phpにアクセスしたとき送られるHTTPヘッダはたとえば以下のようになる。
GET /ddd/fff.php HTTP/1.0
Accept: */*
Connection: close
Host: www.example.com
ここから$_SERVERなどの変数にいろいろ入ってくると思われるがどれがどれだかよくわからないが、たぶん以下のような感じだろう。上との対象で書くと。
$_SERVER['REQUEST_METHOD'] $_SERVER['REQUEST_URI'] $_SERVER['SERVER_PROTOCOL']
Accept: $_SERVER['HTTP_ACCEPT']
Connection: $_SERVER['HTTP_CONNECTION']
Host: $_SERVER['HTTP_HOST']
よって単純に考えれば以下のような感じでURLを取得できるか?
1 |
"http://" . $_SERVER['HTTP_HOST'] . $_SERVER['REQUEST_URI']; |
ポートが80じゃない場合はどうなるだろうか。その場合もHttpのHostヘッダに”Host: www.example.com:8080″見たいに入るから大丈夫か?
プロキシ経由の場合はサーバはプロキシからアクセスされるだけで、上に書いたことに大きな違いはないか?
IPアドレスでアクセスした場合は、HOSTがIPアドレスに変わるだけで大きな違いはないと思うが、この場合でもFDQNで取得したい場合はあらかじめどっかにかいとくしかないか?逆引きしてまですることじゃないと思う。
ではサイトのトップページを取得したい場合はどうするか?サイトのトップページがhttp://www.example.com/ddd/だとして、http://www.example.com/ddd/xxx/ppp.phpのアクセスから、トップページを取得したい場合。これはめんどくさそう。考えたくない。
いやその前にmod_rewriteを使っていて、QUERY_STRINGをディレクトリみたいに見せていた場合、$_SERVERの格変数にはどう格納されるのか?これもめんどくさい。調べるのもめんどくさい。
やっぱり素直にPHPに書いておいたほうが安全かな。
追記
pukiwikiの見ていたら関数を見つけたので適当に直してコピペ
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 |
foreach (array('SCRIPT_NAME', 'SERVER_ADMIN', 'SERVER_NAME', 'SERVER_PORT', 'SERVER_SOFTWARE') as $key) { define($key, isset($_SERVER[$key]) ? $_SERVER[$key] : ''); unset(${$key}, $_SERVER[$key], $HTTP_SERVER_VARS[$key]); } function die_message($msg) { echo htmlspecialchars($msg); die(); } function is_url($str, $only_http = FALSE) { $scheme = $only_http ? 'https?' : 'https?|ftp|news'; return preg_match('/^(' . $scheme . ')(:\/\/[-_.!~*\'()a-zA-Z0-9;\/?:\@&=+\$,%#]*)$/', $str); } function get_script_uri($init_uri = '') { global $script_directory_index; static $script; if ($init_uri == '') { // Get if (isset($script)) return $script; // Set automatically $msg = 'get_script_uri() failed: Please set $script at INI_FILE manually'; $script = (SERVER_PORT == 443 ? 'https://' : 'http://'); // scheme $script .= SERVER_NAME; // host $script .= (SERVER_PORT == 80 ? '' : ':' . SERVER_PORT); // port // SCRIPT_NAME が'/'で始まっていない場合(cgiなど) REQUEST_URIを使ってみる $path = SCRIPT_NAME; if ($path{0} != '/') { if (! isset($_SERVER['REQUEST_URI']) || $_SERVER['REQUEST_URI']{0} != '/') die_message($msg); // REQUEST_URIをパースし、path部分だけを取り出す $parse_url = parse_url($script . $_SERVER['REQUEST_URI']); if (! isset($parse_url['path']) || $parse_url['path']{0} != '/') die_message($msg); $path = $parse_url['path']; } $script .= $path; if (! is_url($script, TRUE) && php_sapi_name() == 'cgi') die_message($msg); unset($msg); } else { // Set manually if (isset($script)) die_message('$script: Already init'); if (! is_url($init_uri, TRUE)) die_message('$script: Invalid URI'); $script = $init_uri; } // Cut filename or not if (isset($script_directory_index)) { if (! file_exists($script_directory_index)) die_message('Directory index file not found: ' . htmlspecialchars($script_directory_index)); $matches = array(); if (preg_match('#^(.+/)' . preg_quote($script_directory_index, '#') . '$#', $script, $matches)) $script = $matches[1]; } return $script; } $uri = get_script_uri(); echo htmlspecialchars($uri); exit(); |
ライセンスはpukiwikiに従う。