2015年1月26日月曜日

Zend Frameworkのhtaccessの不思議(2)mod_rewriteの環境変数指定と呼び出し

前回の記事
Zend Frameworkのhtaccessの不思議(1)mod_rewriteの後方参照に続いて、今回は、一体Zend Frameworkのhtaccessにおける記述はなにをしているのか、について掘り下げてみる。

==============
【1行目】RewriteCond %{REQUEST_URI}::$1 ^(/.+)(.+)::\2$
【2行目】RewriteRule ^(.*) - [E=BASE:%1]
【3行目】RewriteRule ^(.*)$ %{ENV:BASE}index.php [NC,L]
==============

その前に前回書き逃していた点を一つ。

[E=BASE:%1]

この記述は、環境変数をsetしている。

設定   [E=変数名:値]
呼出   %{ENV:変数名}   として呼び出すことができるみたい。


そして本題 「いったいこの3行はなにをやっているのか」 だが、まずその直前のコメント行を読んでみると、

==============
# The following rewrites all other queries to index.php. The 
# condition ensures that if you are using Apache aliases to do
# mass virtual hosting, the base path will be prepended to 
# allow proper resolution of the index.php file; it will work
# in non-aliased environments as well, providing a safe, one-size 
# fits all solution.
==============

とある。

基本的には、リクエストされたパスが実在するファイルでもディレクトリでもシンボリックリンクでもない場合は、アクセスが全てフロントコントローラ(index.php)に集まる作りになっている。

そして上記のコメントでは「Apacheのaliasesを使用している場合でも、正しくフロントコントローラ(index.php)のパスを認識させるため」と書かれている。

また、以前の古いバージョンでは、
==============
RewriteRule ^.*$ index.php [NC,L]
==============
の1行だけだった。


まあ、上記のコメントでズバリな回答が出たことにもなるが、要するにpublic(Documentoroot)配下のディレクトリ・ファイルをどこか別のディレクトリに配置して、Apacheのエイリアスを指定するやり方でも、そうでない普通の配置をした時と変わらない感覚で管理ができる、ということのようだ。

viewscript側でも、この仕様になっていると、「$this->basePath()」で、[E=BASE:%1]で設定されたBASEのパスがそのまま出力されるようなので便利といえば便利。

ほんのちょっとした些細な気遣い程度のことだが、やはりなるべく余計なことは考えずにアプリ開発を進めたいので、なるほどなと思える設定だった。


にしても、まだ細かいところまでちゃんと理解できとらんな、、。


参考にさせてもらったのは以下。
Qiita - mod_rewriteでApache環境変数を一時変数として利用する

2015年1月22日木曜日

Zend Frameworkのhtaccessの不思議(1)mod_rewriteの後方参照

Zend Frameworkを触っていて、htaccessにいくつか気になる点があったので調べた。
理解に至るまでにわりと頭がこんがらがったので数回に分けてメモ。

気になった記述は以下。
==============
【1行目】RewriteCond %{REQUEST_URI}::$1 ^(/.+)(.+)::\2$
【2行目】RewriteRule ^(.*) - [E=BASE:%1]
【3行目】RewriteRule ^(.*)$ %{ENV:BASE}index.php [NC,L]
==============

まず 「$1」「%1」「\2」について。
これらはいずれも後方参照を指す。

$1 : RewriteRule内の正規表現における後方参照
%1 : RewriteCond内の正規表現における後方参照
\2 : インラインの後方参照
ということらしい。

【1行目】 RewriteCond %{REQUEST_URI}::$1 ^(/.+)(.+)::\2$
ここでの「\2」は、その直前の「(.+)」ということになるようだ。

【2行目】 RewriteRule ^(.*) - [E=BASE:%1]
ここでの「%1」は、1行目の「(/.+)」の部分に該当することになる。

では、【1行目】の「$1」は何を指すのだろうか?
htaccessのこの行以前に、RewriteRule内の正規表現に「()」で括られた箇所はないし、、、、?

ここで一度大きく詰まってしまって時間をかなり費やしたのだが、正解はmod_rewriteのURL書換における処理の順序にあるらしい。
mod_rewriteでは、RewriteCondに続けてRewriteRuleが記載されている場合、まずはじめにRewriteRuleを認識し、その後にRewriteCondの内容を確認してRuleの適用の可否を判断する。

そのため上記の場合は、
1. RewriteRule は ^(.*) - [E=BASE:%1] であると認識する
2. RewriteCondの内容 %{REQUEST_URI}::$1 ^(/.+)(.+)::\2$ に従って条件判定し、1.の適用の可否を判断
となるため、【1行目】の「$1」は、【2行目】RewriteRuleの「(.*)」に該当する。

「後方参照」というからには、てっきり「$1」よりも前の記述を参照しているものとばかり思っていたので、これは目からウロコだった。

てことは、要するにこの記述は一体なにをしているのか、、、というのが次回のメモとしよう。

・参考にさせてもらったページ
ずんWiki – mod_rewrite
stackoverflow - What does ::$1 mean in an htaccess?
stackoverflow - Backreferencing regex in apache


2015年1月19日月曜日

Windowsのメモ帳で書いたファイルをUTF-8で保存するとなぜBOMがつくのだろう?

Windowsに標準でついてくるエディター「メモ帳」は、今まで特に気にも留めていませんでした。

普段の仕事に使っていたサードパーティー製のエディターソフト(※シェアウェア・有料)がなにやら奇妙な価格体系になったことから、なんかこうあまりバージョンアップやらなんやらでいちいちお財布との相談をするのもいい加減アキアキしてたこともあって、無料で使えるステキなエディターはないかと探っている中でいつのまにかメモ帳もUTF-8を扱えることを発見したのが、コトの発端です。

試しに今まで書いていたPHPのファイルをメモ帳で開き、スクリプト本体とは関係ない適当なコメント行を追加し、上書き保存。
サーバーにアップし動作を見てみると、動かない。
※PHPが全て動作しなくなるわけではないようなのですが、その詳細はここでは割愛。

なんじゃこりゃと思い、使い慣れたエディターで開いてみてみると、なんと「BOM付き」で保存されている。

今までも、「UTF-8で記述されたCSVファイルをエクセルで開くとき、BOMなしで保存されていると文字化けする」というケースには出会ったことがありましたが、BOM自体を気にすることはなかったので、そもそもBOMってなんなのさ、と調べてみました。

乱雑に要約すると、

  • BOMはバイト・オーダー・マーク(Byte Order Mark)の略
  • 言葉通り「バイトの並び順」の意
  • 複数バイトで表されるデータには、[上位バイト][下位バイト]の並びと、[下位バイト][上位バイト]の並びの2つの流儀がある。
  • インテルのCPUは[上位バイト][下位バイト](リトル・エンディアン)の方式を採っている。
  • SunやモトローラのCPUは[下位バイト][上位バイト](ビッグ・エンディアン)の方式を採っている。
  • ファイルごとにそのどちらの方式で表現されたものなのかを示すために、そのファイルの先頭にバイトの並び順を示す数バイトのバイナリ(例:0xEF 0xBB 0xBF)を記述しておき、その方式に合わせて正しくデータを解釈させる。

ということのようです。

メモ帳は、ファイルを保存する際に文字コード:UTF-8を選択することはできますが、BOMの有無は選択できず全てBOM付きで保存されるようです。

メモ帳でWindowsのちょっとしたバッチファイルを書いても、このBOMが原因で動作しないことがあるし、かといってBOMなしで保存されたUTF-8のファイルをメモ帳で開いても、それはそれで特に文字化けもしないし、いったい何のために、、?

いずれにしても、BOMも付くし、LF(改行コード)も改行として表示されないし、PHP書くには当然全く使えないので、今後も引き続き気にも留めませんが「BOMってなにさ?」という好奇心は少し満たされました。

何用途を想定してこの仕様なのかはMicrosoftに限らず、もし知っている人がいれば尋ねてみたいところです。

参照:バイトオーダーマーク - Wikipedia
※「UTF-8においてBOMは容認されるが、必須でも勧められるものでもないとされている」って書いてある。

BOM無しで統一のほうがいんでない?