Help us understand the problem. What is going on with this article?

Apache2.4でSSIを動かすときの後方参照でハマった話

はじめに

SSI(Server Side Include)を利用して、画面の表示をそこそこディープに制御する必要があった。
その際、後方参照を用いた手法に難儀した話である。
枯れた技術かもしれないが、目をつむってほしい。

環境

  • Apache2.4
  • httpd.conf には IncludesNoExec

後方参照という言葉について

正直はっきり理解できていないが、ここでは正規表現等を用いて条件マッチした際、特定の箇所を抜くときに利用する特殊変数(\$1、$2...)のことを指す。

$1がうまく機能しない?

さて、ハマった記述は以下の形である。

false.shtml
<!--#If expr="%{QUERY_STRING} =~ /age=([^&]+)/" -->
<!--#set var="age" value="$1" -->
<!--#Endif -->

期待する$1の返却値はクエリストリング内のage=に記載される数値だが、これで変数ageをechoすると(none)が返される。
Apacheの公式ドキュメントにサンプルとしてほぼ同一の記載があるのに、だ。

$0にはなにがある?

上記コードの\$1を\$0にしechoすると、age=数値が表示される。
つまり、まったく後方参照が利用できないというわけではなさそうだ。

結論

以下の記述であれば、期待する値を取得できることが分かった。

true.shtml
<!--#If expr="%{QUERY_STRING} =~ /age=([^&]+)/" && $1 =~ /([^&]+)/" -->
<!--#set var="age" value="$0" -->
<!--#Endif -->

http://~~~/?age=123

123

読解してみると、If文に合致する箇所は数値の部分であり、
\$0は条件合致した内容をすべて表示するため、これで数値箇所のみを取り出せることが分かった。

なぜこうなるか(考察)

\$1以降の後方参照は、If文と同列でないと取り扱えないようである。
※濁した書き方なのは、正式な仕様がどこにも見つからないからだ。

調査にだいぶ時間がかかったのは、日本語のドキュメントで本問題を取り扱ったものが見当たらなかったからである。
(stackoverflow には似たような質問が散見された)
何らかの事由で、SSIを利用し条件マッチによる制御を行う必要がある諸兄の一助になれば幸いである。

補足

Apache2.2では、If文と同列でなくとも後方参照は動作するようである。
そもそもApache2.4になってからSSIにおける変数の記述や正規表現マッチの書き方が微妙に変わっており、
日本語のナレッジも少ない為、ディープに利用している諸兄は是非発信していって欲しい。

moimoi22
しがない29歳エンジニア。フロントエンドでもバックエンドでもない畑で日々知識を育て中。
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
No comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
ユーザーは見つかりませんでした