相対/絶対 URI について($script, get_script_uri, get_base_uri等)†
- ページ: BugTrack
- 投稿者: ぃぉぃぉ
- 優先順位: 普通
- 状態: 完了
- カテゴリー: その他
- 投稿日: 2007-03-08 (木) 20:37:49
- バージョン: 1.4.7
- リリース予定バージョン: 1.5.2
メッセージ†
cvs:lib/func.phpで、get_script_uri()は
// Get absolute-URI of this script
とコメントがあるように、絶対URIを出力するための関数と思われます。
get_script_uri()をgrepしてみましたが、24ファイルほどヒットしました。ほとんど下名*1は使ったことのないプラグインだったのでよくわかりませんが、ほとんどがこの関数をつかわず相対URIの扱いで構わない気がしますが、いかがでしょうか。
これらの修正を行って動作確認でもして、変更箇所を示したらofficialに採用される可能性はあるでしょうか?それならやろうかなと思うのですが。
もともと相対URIで使用したかったのは、当方の環境ではDeleGateを使用してSSL化しているため、Webサーバーから見ると常に平文通信のため、リンクが全てhttpsにならずにhttpになってしまったのです。
で、相対URIならいけるかな、と。試しにget_script_uriで$script=''を返すようにしましたが、それなりに動きました。
現状の修正案†
求められている状態†
それぞれ、DirectoryIndex(例えばindex.php)を削ったものと、削っていないものとがありうる (他にも条件があるかもしれない)
絶対URI (absolute URI)†
http://example.com/
http://example.com/path?query=value
など、相対 URI に加えてスキーム、ホスト名、ポート番号を含んだ完全な URI。
相対URIにすると正常な動作を妨げるものがある
- RSS出力 -- 絶対URIでないと、購読者がリンクにたどり着けない。
- 自分自身のURIをコンテンツの中に表示させる場合 -- 例: NAVIBARのTOPICPATH非使用時(pukiwiki.skin.php)
- HTTP Location ヘッダで使用するURI -- http://www.studyinghttp.net/header#Location
- リンクは絶対URIと同様の働きをする。
- $link['reload']の出力が変わっている、ということは、get_script_uriをgrepしただけでは全ての影響箇所を見つけられていない。 -- ぃぉぃぉ
- get_script_uri() から 例えば http://pukiwiki.sourceforge.jp/dev/ のようなアドレスを取得して、クッキーの有効パスに利用しているようなプラグインもあります。 --
- これに対してはむしろ index.php のあるディレクトリURLを直接返す関数が欲しいです。たしか get_script_uri 内で index.php をくっつけてますよね?くっつけてから分離するというのは無駄っぽいので。 --
- このコメントは逆の事を言われているように思います。デフォルトでは index.php つきのURI が得られます。関数の中では、管理者の設定に応じて index.php といったファイル名を 削る 処理を行っています。 -- henoheno
- そうでしたか。確認はしていなかったので。とにかく、ディレクトリURLを直接返すAPI関数が欲しいかな、と。 --
- 関連: BugTrack/554 [携帯電話] HTTPのLocation ヘッダによるリダイレクトに失敗する --
絶対パスによる相対URI (absolute-path reference)†
/path?query#fragment
/path/file?query#fragment
必ず / で始まる
相対パスによる相対URI (relative-path reference)†
./path/file
../path/file?query
- 絶対URIに比べ転送量が小さい
get_script_uri()を呼ばずにすむ(空の文字列に置き換えればよい)ので速度も上がる 相対URIを使うかどうかと、どのようにして実現するかは別の話です -- henoheno
求められている状態のコメント†
- 相対URIでかまわない部分はget_script_uri()を'./'に置き換えて、get_script_uri()は絶対URIを返すという仕様でどうでしょう。 -- ぃぉぃぉ
- <a href="?hoge"> は Another HTML-lint で怒られたと思います。$script = 'index.php' にしないといけないと思います。 --
- そうすると今度は index.php を省略した URL を使用できなくなると思います。大したことではないと思うかどうかは人によりますね。 --
- <a href="./?hoge">なら通りそうですた。$script = './'でok? -- ぃぉぃぉ
- ./ におきかえようとしているようですが、index.php とは限らないし、index.php を省略できる環境とも限らないですよね。 --
- おーっと、そうでした。index.phpを省略できるかどうか、考慮が漏れていました。残念。やっぱり関数を呼ぶか式を入れるかが必要になるんですね。 -- ぃぉぃぉ
- デフォルトは index.php などのスクリプト名、pukiwiki.ini.php のスクリプト名を省略する設定が有効の場合 ./ 、というようにするのが良いでしょうね。 --
- 指摘があったようにindex.phpの省略/非省略がありうるので、定数'./'に置き換えは無理ですね。 -- ぃぉぃぉ
- いっそのこと静的コンテンツに偽装みたいなのを標準で取り込んでしまった方が簡単かもしれませんね。 -- Logue
- <a href="?hoge"> は Another HTML-lint で怒られるとしても、HTML としては正しいのでそれでいいのではないでしょうか?Another HTML-lint もバグかなにかだと認識していたようなしていなかったような --
- 結局、BugTrack2/213/lib/get_script_uri では相対スクリプトURIの取得に rel (index.php を返す)と rel_cut (空文字を返す) があるようですが、常に ($script_directory_index にもよらず)、空文字を返す仕様でよいのではないでしょうか? --
- それはなぜ --
- 「結局」とつなげているのでその上の文章が理由となります。index.php を返す仕様がほしかったのは、ただの Another HTML-lint 対策です。それは必要ないのでは。 --
- 文字列に書き換えようとしていたのが失敗だなぁ。使用箇所はSCRIPT_URIに置き換えて、init.phpあたりでSCRIPT_URIをdefineするようにすれば環境によってdefine値を変更するだけでいい。関数を呼ぶオーバーヘッドもなくなるし。
相対URIで良い部分についてはこれがベストに近い解な気がする。 -- ぃぉぃぉ
コメント†
コメント: 従来までの推移†
- お疲れ様です。細かく拝見していませんが・・・相対パスであってはならない局面があるのに今まではそれが安易に扱われていたため、(最初のステップとして)絶対パスを定義しなければ動かない様にした、という経緯で正しいです。次のステップとしては、複数のタイプを使い分けるようなスマートな解決策が求められています。「サイト自身の位置」という一つの情報は一箇所で管理しないとコードが増えますから、get_script_uri()を拡張・・・というか引数をを作り変えて、これに与える引数によって複数のタイプを選択できるようにすると楽なのだろうと思います。 -- henoheno
- そもそもget_script_uri()を呼んでいるのがおかしいですよね。$scriptがあるのだから。 -- ぃぉぃぉ
- get_script_uri() と $scriptの関係を補足します。$scriptは互換性のためにだけ残されています。get_script_uri() があるのにグローバル変数 $script を参照しているのはおかしい、というのが現状です。 -- henoheno
コメント: 実現方法 (グローバル変数か関数か)†
- 以下の仕様でいかがでしょ。 -- ぃぉぃぉ
- $script_rel(相対URI)、$script_abs(絶対URI)をlib/init.phpで設定。 -- ぃぉぃぉ
- 現状の$script、init.php以外で呼んでいるget_script_uri()を$script_relもしくは$script_absに置き換える。 -- ぃぉぃぉ
- 互換性を考慮した場合、グローバル変数 $script は(従来通り)、lib/init.php あたりで絶対URLとして正規化した後は、変更する場面があってはいけません。ただし、グローバル変数で値を持つというのは(いつ改変されるか解らないので)本来危険な設計ですから、今後の対応としては正しい値を持つ正規の関数(例えばget_script_uri()がそれを担当できる)に対して、どのような形(絶対、相対、・・・etc)で自身のURIが欲しいかを問い合わせる形にすると堅固になります。 -- henoheno
- できれば関数を呼び出す回数を減らしたいので、$scriptを相対URI、$script_absを絶対URIとしてlib/init.phpで設定し、あとは使う側で選んでもらう、ということでどうでしょう。多少負荷軽減になりますよね? -- ぃぉぃぉ
- ニーズとして求められているURIは二つではないので、その方向だとグローバル変数がさらに要るか、場面場面で別の加工をする必要があるでしょう。 -- henoheno
- セキュリティ、およびメンテナンスの観点から、グローバル変数をむやみに増やすべきではないという点と、重要な情報をグローバル変数に収める(改変される可能性を作る)べきでないという点と、場面ごとにバラバラなコードがあちこちに発散してしまうため、メンテナンスコストが増えてミスが起こり易くなるという点もコメントしておきますね -- henoheno
- クラスで作るのはどうか、といった話題もあると思います。PHP4なので以下略。 -- henoheno
- ぃぉぃぉさんも「やっぱり関数を呼ぶか式を入れるかが必要になるんですね」などとコメントされている通りなのですが、この件のポイントは、「ニーズが動的に変化する」という点にあると思います。index.php付きのURIを知りたいときもあるし、いらない時もあるし、絶対URIが欲しい時もあるし、相対パスで欲しい時もありえます。また、状況に応じてそれが変化する事もあります。今までは絶対URIで統一させていたので(そのサイトからコンテンツを提供し続けるのであれば)どの場面でも大体問題なかったのですが、蓋を開けるのであれば、それぞれのリクエストに柔軟に応じてあげなければいけないだろうという事です。 -- henoheno
- グローバル変数はなしだと思います。現在の $script は get_script_uri() が呼び出されたときに自動生成されます。あと、下位互換性を考えたら get_script_uri は現状どおり絶対URIを返して、get_script_rel とか get_script_uri('rel') などが相対URIを返す、とした方が楽かもしれません。そして変えられるところをちくちく変えていく、と。 --
- なるほど、$scriptの現状が分かってきました。「下位互換性を考えたら get_script_uri は現状どおり絶対URIを返し」という点は同意します。 -- ぃぉぃぉ
- ずいぶんかかりましたが、get_script_uriに引数を与えて出力を変える方向で実装してみました。 -- ぃぉぃぉ
コメント†
- 絶対URL の取得に失敗して、質問箱にくる人もよくいますよね。相対パスでよいならその辺のことで質問箱にくる人は少なくなって良いかもしれません。 --
- 絶対パスが必要なものはそういう対応をする必要があると思います。具体的なplugin等が分かればどんどん紹介して下さい。 -- ぃぉぃぉ
- contents を追加し、関連ページのリンクを追加し、とても大雑把に話題をまとめさせていただいています。すごく乱暴ですいません・・・ -- henoheno
- henohenoさん、整理お疲れ様です。検討しやすくなりました。ありがとうございます。 -- ぃぉぃぉ
- BugTrack2/260 --
- official:質問箱4/212 --
- HTTP RedirectでのLocationヘッダについて、RFC2616では絶対URIが必要でしたが、RFC7231で"URI参照(URI reference)"を指定できるようになったようです。例示されているのは「絶対パスによる相対URI」で"/"から始まるものです。もともとほとんどのブラウザで大丈夫でしたが、これは使ってよさそうです -- umorigu
- bugtrack_2213_relative_script_uriブランチで仮対応しました。標準配布の範囲では期待通り動いているようではあります。 -- umorigu
- (1) commit:8e51d1f113 get_script_uri() のデフォルト動作を相対パス (例: './') 返却に変更。ルート相対URI (/wiki/)、絶対URI(http://example.com/wiki/)を返すオプションを追加。 -- umorigu
- (2) commit:f88edebdd1 get_script_uri() を使っている個所で、ルート相対URI・絶対URIが必要な個所を変更。 -- umorigu
- (3) commit:8e51d1f113 グローバル変数 $script を使っていたコードを get_script_uri() 利用に変更。 -- umorigu
- 実質的な効果を考えるとget_script_uri()の標準状態(引数無し)で相対パスが返ってくるようにしたいですが、そうすると本来絶対URIやルート相対URIを求めている個所の変更が必要になります。やはり外部プラグインの互換性が課題です。標準配布の範囲であれば変更すればいいのですが、絶対パスを求めている実装があるとそこが壊れてしまいます。安全なのはやはり相対URI返却を基本とする別関数を作って、徐々にそちらに移行していってもらうしかなさそうです。get_app_uri()か、get_base_uri()か... -- umorigu
名無しさんのまとめ案†
叩き台。関数名、仕様も決めてみます。
- pukiwiki.ini.php にて絶対URIか絶対パスか相対パスのうちどれを使用するかのフラグをグローバル変数で用意する。$script_path_reference とする。
- $script_path_reference は以下の何れかの値を取る
- 'full' - 絶対(Full)URI (absolute URI)
- 'abs' - 絶対パス (absolute path-reference)
- 'rel' - 相対パス (relative path-reference)
- 絶対URIの初期化用関数として init_script_full_uri($full) 関数を用意する
- 旧 get_script_uri($init_uri = "") の動作。中々 $init_uri の引数が邪魔なので分離する。
- グローバル変数に従って get_script_uri() は絶対URIか絶対パスか相対パスのどれかを返す。
- また get_script_uri($path_reference) の形式で 'full', 'abs', 'rel' の何れかを指定することで明示的に対応する値を返す
- 必ず絶対URI、絶対パス、相対パス、のいづれかでなければならないプラグイン等は
get_script_uri($path_reference) の形式を使用するようにすべて変更する。自作プラグインも変更してもらう。
- 例えば必ず絶対URIでなければならないものとして
などがある。
- 必ず相対URIでなければならない、というものはない、むしろあってはならない。はず。
- よって実質的に get_script_uri('rel') が使用されることはない。はず。
- ちなみに get_script_uri('rel') は $script_directory_index にもよらず常に空文字を返す。
- get_pkwk_baseuri 関数の設置
- PukiWiki を設置したディレクトリへの絶対URI(index.php を除いた絶対スクリプトURI)、絶対パス、相対パスを返す
- get_script_uri() と同様に $path_reference 引数を持つ。同様にデフォルトではグローバル変数に従った動作。
- 絶対パスの値から index.php を除いて、クッキーの有効パスに利用しているようなプラグインがある。そのようなプラグインを get_pkwk_baseuri('abs') を使用するようにすべて変更する。
- get_page_uri($page) 関数の設置 (ついでに)
とりあえずの対応をする場合†
- pukiwiki.ini.php にて絶対URIを使用するか相対URIを使用するかのフラグ $script_path_reference グローバル変数を用意する。// Experimental と書いておく。
- init_script_full_uri($init_uri) の用意。get_script_uri($init_uri) の動作を使用していた箇所を変更する。少ないはず。
- get_script_uri() の変更
- get_pkwk_baseuri() 関数の設置
- get_page_uri($page) 関数の設置 (ついでに)
その後ちくちく変更していく。
絶対URIが必須な自作プラグインなどは、
$script = function_exists('init_script_full_uri') ? get_script_uri('full') : get_script_uri();
のように対応していってもらう。
パッチ†
関数設置パッチ。
diff -ru pukiwiki.orig/lib/func.php pukiwiki.path-reference/lib/func.php
--- pukiwiki.orig/lib/func.php 2008-01-08 08:50:30.656250000 -0500
+++ pukiwiki.path-reference/lib/func.php 2008-01-08 10:06:47.437500000 -0500
@@ -709,8 +709,54 @@
}
}
-// Get absolute-URI of this script
-function get_script_uri($init_uri = '')
+// Get Page URI (would be modified to use mod_rewrite, PATH_INFO)
+function get_page_uri($page, $path_reference = '')
+{
+ $script = get_script_uri($path_reference);
+ $pageuri = $script . '?' . rawurlencode($page);
+ return $pageuri;
+}
+
+// Get PukiWiki base URI (no index.php)
+function get_pkwk_baseuri($path_reference = '')
+{
+ $script = get_script_uri($path_reference);
+ if (($pos = strrpos($script, '/')) !== FALSE) {
+ $baseuri = substr($script, 0, $pos + 1);
+ }
+ return $baseuri;
+}
+
+// Get script URI
+function get_script_uri($path_reference = '')
+{
+ static $script_full, $script_abs, $script_rel;
+ global $script_path_reference;
+ $path_reference = ($path_reference !== '') ? $path_reference :
+ (isset($script_path_reference) ? $script_path_reference : 'full');
+ switch ($path_reference) {
+ case 'rel':
+ if (isset($script_rel)) return $script_rel;
+ $script_rel = '';
+ return $script_rel;
+ break;
+ case 'abs':
+ if (isset($script_abs)) return $script_abs;
+ $script = init_script_full_uri();
+ $parsed = parse_url($script);
+ $script_abs = $parsed['path'];
+ return $script_abs;
+ break;
+ default: // case 'full':
+ if (isset($script_full)) return $script_full;
+ $script_full = init_script_full_uri();
+ return $script_full;
+ break;
+ }
+}
+
+// Init absolute-URI of this script and return it (old get_script_uri)
+function init_script_full_uri($init_uri = '')
{
global $script_directory_index;
static $script;
diff -ru pukiwiki.orig/lib/init.php pukiwiki.path-reference/lib/init.php
--- pukiwiki.orig/lib/init.php 2008-01-08 08:50:30.671875000 -0500
+++ pukiwiki.path-reference/lib/init.php 2008-01-08 09:43:50.828125000 -0500
@@ -129,9 +129,10 @@
// INI_FILE: Init $script
if (isset($script)) {
- get_script_uri($script); // Init manually
+ init_script_full_uri($script); // Init manually
} else {
- $script = get_script_uri(); // Init automatically
+ $script = init_script_full_uri(); // Init automatically
+ // Set $script to support old versions
}
/////////////////////////////////////////////////
diff -ru pukiwiki.orig/pukiwiki.ini.php pukiwiki.path-reference/pukiwiki.ini.php
--- pukiwiki.orig/pukiwiki.ini.php 2008-01-08 08:50:24.937500000 -0500
+++ pukiwiki.path-reference/pukiwiki.ini.php 2008-01-08 10:00:06.843750000 -0500
@@ -118,6 +118,10 @@
// Shorten $script: Cut its file name (default: not cut)
//$script_directory_index = 'index.php';
+// Use absolute (full) uri or absolute path-reference or relative path-reference for internal links
+// Experimental function [[dev:BugTrack2/213]]
+//$script_path_reference = 'rel'; // 'full' or 'abs' or 'rel'
+
// Site admin's name (CHANGE THIS)
$modifier = 'anonymous';
コメント†
- 最終目標(まとめ)について。現状の修正案 (ぃぉぃぉ さんの案)の方は使えそうですか? --
- いいえ。です。部分的には利用できると思いますがアイデアの段階で多少異なります。現状のまとめは叩き台(関数名が決定でいいのか、など)なのでそれらをまず決定して作成に入りたいところです。また「まとめ」のつもりなのでコメントは移動させてください。関数名の議論などの場所が必要ならば別の項目にする予定です(作っていただいても結構です)。 --
- https:// などはそのままで、でも絶対パスで指定したい場合というのやはりあるんですかね? 'absuri', 'abspath', 'relpath' ? 1, 2, 3? 'fulluri', 'abspath', 'relpath'? 'full', 'abs', 'rel'? --
- さて、大分仕様は固まりつつありそうなので、現在の「まとめ」に対して何か意見をください --
- 関数設置パッチも作成しました。この仕様でよければとりあえずとりこんでもらって、別の BugTrack でもたてて必要箇所をリストアップ、ちくちく修正していくと良いと思います。 --
- 今まであった pukiwiki.ini.php での絶対URI設定項目である $script は $script_full_uri とでも名前を変え、$script はグローバル変数によって、absolute URI, absolute path-reference, relative path-reference に変形するようにしたらどうでしょうか?最終目標としては $script を get_script_uri に全て置き換える予定のようなのでそこは問題ではないのでしょうが、実質自作プラグインなどはサポートしようがなくその境地までにはおそらくたどり着けないので、とりあえずの対応として。 --
- get_page_uri()のような関数は欲しいな、と思っていました。確かにこのタイミングで導入するとよさそうです。plus:BugTrack/54を見たところPukiWiki Plus!に同じ関数があるんですね。これはちょっとやっかいかも... これに依存しているプラグインはあまりないか -- umorigu
案C by umorigu†
- 同Wiki内のリンクはすべて相対パスでのリンクとする。 (./?...) 特別な場合のみ、絶対URIを利用する。
- グローバル変数 $script: 絶対URIをマニュアル指定する役割。指定しない時はサーバー変数より推測して設定される (guess_script_absolute_uri in lib/func.php)
- $script をマニュアル指定する場合は必ず http: //example.com/wiki/ のような絶対パスであること。'./'のような相対パスはサポートされない。
- Deprecated プラグインから直接この変数を使うことは禁止する
- グローバル変数 $script_directory_index: URIが推測される場合に機能する。 (例: /www/index.php にアクセスされた場合に '/www/' を絶対URIとして扱う。)
- get_script_uri(): 必ず絶対URIを返す (互換性のため)。 get_base_uri(PKWK_URI_ABSOLUTE) と同じ
- get_base_uri(): 自身を示す、コンテキストに応じて適切なURIを返す。通常は相対パス('./')
- get_base_uri(PKWK_URI_RELATIVE): 相対URIを返す ( ex: ./, index.php )
- get_base_uri(PKWK_URI_ROOT): ルート相対URIを返す ( ex: /wiki/, /wiki/index.php )
- get_base_uri(PKWK_URI_ABSOLUTE): 絶対URIを返す ( ex: http: //example.com/wiki/, http:// example.com/wiki/index.php )
- get_page_uri($page): ページを示すURIを返す
- get_page_uri($page, PKWK_URI_RELATIVE): 相対URIを返す ( ex: ./?FrontPage )
- get_page_uri($page, PKWK_URI_ROOT)
- get_page_uri($page, PKWK_URI_ABSOLUTE)
- pkwk_base_uri_type_stack_push(PKWK_URI_ABSOLUTE) : get_base_uri() が必ず絶対URIを返すようになる
- pkwk_base_uri_type_stack_pop() : pkwk_base_uri_type_stack_push() の効果を終わらせる
互換性†
- $script はこれまで通り、絶対URIを示すが、利用しないのが望ましい。
- 利用しているプラグインは、get_base_uri() を使うようにする。
- get_script_uri() はこれまで通り、絶対URIを示すが、利用しないのが望ましい。
- 利用しているプラグインは、get_base_uri() を使うようにする。
- commit:7bad7de4c1 get_base_uri(), get_page_uri() の追加
- commit:82ae29696c get_script_uri()利用箇所のうち、ルート相対URI、絶対URIが必要な個所を get_base_uri(PKWK_URI_ROOT/ABSOLUTE) に置き換え
- commit:2019096e9d get_script_uri()利用箇所をget_base_uri()に置き換え
- commit:d4fd351122 グローバル変数$script利用箇所をget_base_uri()に置き換え
- commit:1c21a00bd5 Context - pkwk_base_uri_type_stack_push()/pop() の実装
- commit:42880ef94a Canonical URIを絶対パスに設定
コメント†
- これまでの議論を踏まえて案Cで対応しました。だいたい要件は満たしていると思います -- umorigu