CakePHPサイトでSSL制御をhtaccessで行う方法

mod_rewriteモジュールでサイト全体をSSL対応(https)する「.htaccess」ファイルの書き方は・・・

RewriteEngine On
RewriteCond %{HTTP_HOST} ^free-style.biz$
RewriteCond %{HTTPS} off
RewriteRule ^(.*) https://free-style.biz/$1 [R=301,L]

条件として2行目の「HTTP_HOST」はあってもなくてもよいです。
3行目の「%{HTTPS} off」により「http://で始まっている」=「https://で始まっていない」という条件になります。
4行目で絶対表示でURLを指定し、ルート以下のパスを「$1」として追加します。
さて、CakePHPサイトで「www」で始まるURLを「wwwなし」に変更してアクセスする場合の書き方を説明します。(/app/webroot/.htaccess)

RewriteEngine On
RewriteCond %{HTTP_HOST} ^www.free-style.biz$
RewriteCond %{HTTPS} on
RewriteRule ^(.*) https://free-style.biz/$1 [R=301,L]
RewriteCond %{HTTP_HOST} ^www.free-style.biz$
RewriteCond %{HTTPS} off
RewriteRule ^(.*) http://free-style.biz/$1 [R=301,L]
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^(.*)$ index.php?url=$1 [QSA,L]

大まかな流れは
1.www付きをwwwなしにして再アクセスする(http://の場合)
2.www付きをwwwなしにして再アクセスする(https://の場合)
3.ディレクトリやフォルダが実在しない場合はindex.phpを実行する
となります。3は通常のCakePHPのままです。
条件(RewriteCond)とルール(RewriteRule)は何個も重ねて定義されますが、「[R=301,L]」により正常に再アクセスされた場合はここで一旦終了するようになります。
http://www.free-style.biz/でアクセスされた場合は、1番目で「http://free-style.biz/」に再アクセスされて一度終了し、「http://free-style.biz/」でアクセスされて3番目でindex.phpが実行されます。
この仕組みが理解できれば、htaccessを使いこなせるようになりますよ!

CakePHPのhtaccessファイル解説

普段CakePHP(v1.3)を利用するにあたり、あまり考えずに使用している「.htaccess」ファイルについて解説します。
/(ルート)

RewriteEngine on
RewriteRule ^$ app/webroot/ [L]
RewriteRule (.*) app/webroot/$1 [L]

1行目「RewriteEngine on」はmod_rewriteモジュールを使用するためのスイッチです。
2、3行目はともに「RewriteRule」なので、書き換えルールの適用となります。意味は「app/webroot/ に移動する」となります。
/app/

RewriteEngine on
RewriteRule ^$ webroot/ [L]
RewriteRule (.*) webroot/$1 [L]

ここはルートとほぼ変わりないですが、書き換えルールが「webroot/に移動する」となっています。
/app/webroot/

RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^(.*)$ index.php?url=$1 [QSA,L]

一般公開するときはここをルートにすることが推奨となっています。その理由はこのファイルにあります。
1行目「RewriteEngine on」はmod_rewriteモジュールを使用するためのスイッチです。
2、3行目の「RewriteCond」は書き換えルールを適用するための条件を定義しています。2行目はパラメータ「-d」により、実際にディレクトリが存在しない場合、3行目はパラメータ「-f」により、実際にファイルが存在しない場合となり、両方合わせて、指定されたURLパスに実際にディレクトリもファイルも存在しない場合となります。
4行目で書き換えルールが指定されています。「^(.*)$ index.php?url=$1」は同フォルダ内の「index.php」を実行するという意味ですが、「?url=$1」の「$1」が何なのか?よくわかりませんでした。
Perlを使用するには当たり前の正規表現らしいのですが、「$1」の「$」は末尾を示すわけではなく、「$1」で「要素の1番目を適用する」ということになります。
要素の1番目とは「^(.*)$」のことです。index.phpの前に半角スペースがあり、半角スペースでつなげていくことにより要素を複数定義できます。「^(.*)$」は「先頭から0文字以上の文字列を末尾まで」という意味です。つまり、ルート以下のパスがここに入ります。
CakePHPでは必ずindex.phpから始まると誤解している人がいますが、これはある意味で正しく、ある意味で間違っています。
CakePHPのフレームワーク内の制御としてはindex.phpが常に実行されます(正しい部分)が、webwoot配下に実際に配置されたhtmlファイルや画像ファイルはそのまま表示され、index.phpは実行されません(間違っている部分)。
静的なhtmlファイルのみではなく、phpファイルであっても、webroot配下に配置すれば実行することができます。ただし、ルートが「/app/webroot/」まで下げられていないと、CakePHPのフレームワーク外ではURLに「/app/webroot/」が表示されてしまうことがあります。

CakePHP 1.3.2 接続できるデータベースの種類のはなし

CakePHP バージョン1.3.2をインストールしてみました。
データベース設定ファイルのテンプレート(config/database.php.default)には、バージョン1.2.Xと同様のデータベースが記載されています。


* Database configuration class.
* You can specify multiple configurations for production, development and testing.
*
* driver => The name of a supported driver; valid options are as follows:
* mysql – MySQL 4 & 5,
* mysqli – MySQL 4 & 5 Improved Interface (PHP5 only),
* sqlite – SQLite (PHP5 only),
* postgres – PostgreSQL 7 and higher,
* mssql – Microsoft SQL Server 2000 and higher,
* db2 – IBM DB2, Cloudscape, and Apache Derby (http://php.net/ibm-db2)
* oracle – Oracle 8 and higher
* firebird – Firebird/Interbase
* sybase – Sybase ASE
* adodb-[drivername] – ADOdb interface wrapper (see below),
* odbc – ODBC DBO driver


MySQL、SQLite、PostgreSQL、SQL Server、DB2、Oracle、Firebird、Sybase、ADODB接続、ODBC接続
さてさて、実際にデータソースを覗いてみましょうか。
cake/libs/model/datasources/dbo/
接続できるデータベースの種類のはなし
SQL Server、MySQL、Oracle、PostgreSQL、SQLite ・・・・・・・
・・・・・・・
なんか少なくなったぞ??
調べてみると、他のデータソースはインターネットからダウンロードして入れるようです。
接続できるデータベースの種類のはなし
http://github.com/cakephp/datasources/tree/master/models/datasources/dbo/
ADODB接続、DB2、Firebird、ODBC接続、SQLite3、SQL Server、Sybase ・・・ と。
SQL Serverは「dbo_mssql.php」のほかに「dbo_sqlsvr.php」が新しく用意されたようですね。
全部入れると、かなりにぎやかな状態になりました。
接続できるデータベースの種類のはなし
しかし、標準でインストールされていないデータソースについては、今後データソースがバージョンアップされてもCakePHP本体に入っていないということになりますので、自分で時々のぞきに来る必要がありそうですね。
今回は、CentOS上のCakePHPからWindowsServer上のSQL Serverにネイティブ接続してみたかったのですが、新しいデータソースが出たのも役立たず・・・、結局LinuxにはSQL Serverに接続するネイティブドライバが容易されていませんから。
そう考えると、「SQL Server (dbo_mssql.php)」「SQL Server (dbo_sqlsvr.php)」「ADODB接続」については、Windows専用ということですね。まぎらわしいなあ・・・もう。

CakePHPで大量データのCSV出力

今やはりのプログラムはMVCモデルのフレームワークですね。
PHPには、Zend Framework、Symfonyとありますが、今回はCakePHPの話。
CakePHPでWebサイトを作成してもう少しで一年。フレームワークのよい所、わるい所が見えてきました。
最近の話・・・
200万件レコードをCSVデータとして出力する処理を作成していました。
テキストデータで300MBもないデータですが、PHPに割り当てた1GBのメモリがイッパイになってしまうこと数回・・・・
なぜ?なぜ?
同じデータをphpMyAdminのCSVエクスポート機能から出力すると、最後まで出力できる。
両方のコードを調査してみた。
phpMyAdminのコードは、データベースを開いた後で、オブジェクトに取得したデータを1行ずつ出力していきます。
対して、
CakePHPのコードは、データベースから取得したデータを何やら配列らしいものにセットして・・・
って、ここがどうもメモリを相当に圧迫しているらしい。速度的にもボトルネックになっていそう。
まあ、こんな大量なデータベースデータを標準機能で取得することは想定されていないだろうな?