symfony1.x+propel1.3+MySQL5.1/5.5で生成したSQLのCreate TableがType=InnoDBで失敗する場合の対処法


サーバーをMySQL5.0から5.5に変えたら、symfony1.2+propelでbuild:allした際に生成されたSQLがエラーで動かなくなりました。

このようなエラー

You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near ‘Type=InnoDB’ at line 13

MySQL5.1以降で、テーブルのエンジン指定でtype=が使えなくなり、engine=と書かなければいけなくなったようです(table_optionのところ)。propel1.4以前のジェネレーターでは”type=InnoDB”のようなSQL文を生成しているので、古いpropelを使っているsymfony1.xではMySQLを5.1以上に変更した際にテーブルが生成できなくなってしまいます。

symfony1.2がpropel1.3-devを更新することはなさそうなので、これを回避するには、自分でpropelにパッチをあてることになります。

(symfony)/lib/plugins/sfPropelPlugin/lib/vendor/propel-generator/classes/propel/engine/builder/sql/mysql/MysqlDDLBuilder.php

163行目の

$script .= “Type=$mysqlTableType”;

を、

$script .= “Engine=$mysqlTableType”;

に修正。

Windows+XamppでSymfony2開発環境を作る


第一回Symfony2勉強会のために、WindowsマシンにSymfony2の開発環境を構築したメモ [2011-10-14 もろもろ更新]

Windows版のPHP, MongoDBでSymfony2

メモリやディスクがふんだんにある場合は、VMWare等の仮想環境を使ってLinuxなりをインストールする方がいいかと思います。理由は、

  • デプロイ先の実機サーバはどのみちLinuxとかが多いだろう
  • 上にも関連するけど、各コンポーネントでWindowsでの実績が少なかったり、Windowsだけ動かないバグがあったりするかもしれない

対象は、仮想環境とか動かすといっぱいいっぱいな非力なノートPCでなんとかしたい人ぐらい。

ちなみにこの手順は2004年に買ったLet’s note R3E, Pentium M 1.1GHz, メモリ768MB, HDD40Gに、Windows XP SP3で動作確認しました。

Xamppで手っ取り早く環境を作る

Xampp使います。既にApacheやMySQLが単体で入ってたら、アンインストールか最低でも止めてください。

[更新 2011-01-31] Xampp 1.7.4が正式公開されました。以下の手順の一部の作業は不要となりました

[更新 2011-10-14] Xamppは1.7.7になってますね

Symfony2にはPHP5.3.2以上が必要ですが、最新のXampp1.7.3のPHPは5.3.1です。動きません。しょうがないので、Xamppの次のバージョン1.7.4のベータ版を入れます。これならPHPは5.3.3

Xampp beta xampp-win32-1.7.4-beta2-vc6.7z ダウンロード

ベータ版は.7zしか提供されてない…

拡張子.7z のファイルの展開。アーカイバによっては対応してないので、7-zip(32bit x86)とか入れる。7Zfm.exeを実行し、ファイル指定してc:\xamppとかに展開。

> cd \xampp
> setup_xampp.bat
適当なキーを押してインストール完了

xampp for windowsからXamppのインストーラをダウンロードして、実行

> xampp-control.exe
Apacheの[Start]を押す

ブラウザでhttp://localhost/にアクセス。xamppのページが出たらOK。「MySQL動いてないけどいいの?」みたいなことが出る。マシンに余力あればMySQLも[Start]してもよい

Symfony2のダウンロード

Sandboxのzipをダウンロード

[更新] symfony.comドメインに移っているので、Symfony.comのdownloadページからダウンロード

適当な場所に展開(c:\xampp\sandbox)

> cd \xampp\sandbox
> \xampp\php\php.exe check.php
不足している設定がエラー・警告で表示されるのでこれをつぶしていく

Apacheからsandboxを呼べるように

sandboxというドメインでアクセスすることにする。

Apacheの設定ファイルで、バーチャルホストを扱うファイルを編集

> \xampp\apache\conf\extra\httpd-vhosts.conf

NameVirtualHost *:80

# sandboxでアクセスしてきたらC:/xampp/sandbox/webにまわす
<VirtualHost *:80>
  ServerAdmin postmaster@sandbox
  DocumentRoot "C:/xampp/sandbox/web"
  ServerName sandbox
  ServerAlias www.sandbox
  ErrorLog "logs/sandbox-error.log"
  CustomLog "logs/sandbox-access.log" combined
</VirtualHost>

# ファイルへのアクセス権を与え、.htaccess等が効くようにする
<Directory "C:/xampp/sandbox/web">
  AllowOverride All
  Order deny,allow
  allow from all
</directory>

Apache再起動

ブラウザからsandboxでApacheにつながるように

hostsファイルを編集

> notepad \Windows\system32\drivers\etc\hosts

# 追加
127.0.0.1 sandbox

# Windows Vista/7とかだと、管理者として実行とかしないと書き換えられないかも

ブラウザからチェックスクリプトを実行

http://sandbox/check.php

水色で表示されたウォーニングを片付けていく

short_open_tagをオフに

“<?”のこと。これはオフにすべき。

# Xamppのデフォルト設定って…

> \xampp\php\php.ini

short_open_tag = Off
;short_open_tag = On

APCを有効にする

APCについても、Xampp 1.7.4の正式版で同梱されているので簡単になりました

ビルド済みのWindows版dllをphp_apc-3.1.5-5.3-vc6-x86.zip からダウンロード、展開

php_apc.dllをc:\xampp\php\ext にコピー

c:\xampp\php\php.ini を開いて、[PECL]の後ろに

extension=php_apc.dll

XSLTを有効にする

Propel使わないととりあえず不要っぽいけど。php.iniで、

# 追加
extension=php_xsl.dll

posix_isatty() CLI出力に色をつける

PHPのposix関数はWindowsでは使えないとマニュアルにあるので、この警告は消せない

正しいタイムゾーンの設定

何か設定してあれば警告は出ないのだけれど、実はXampp Betaのphp.iniはドイツのベルリン時刻になっている。そこで、php.iniを修正

# date.timezone = Europe/Berlin
date.timezone = Asia/Tokyo

その後ろのデフォルトlatitude/longitudeも自分の緯度経度にしておいても良い。どこで使うか知らないけど

sandboxについてきたアプリの実行

クイックツアー参照

http://sandbox/index_dev.php/

Hello, Fabienアプリ

http://sandbox/index_dev.php/hello/Fabien


MongoDBインストール

ダウンロードページ Windows 32bit

説明

今のstable最新は1.6.3。これをダウンロード (どこでもいいんだけど)c:\xamppに展開

> cd c:\xampp\mongodb-win32-i386-1.6.3
> cd bin
> mongod.exe

おっとエラー。DB置き場は手で掘らないといけない

> md \data
> md \data\db
> mongod
Windowsの警告→ブロック解除

MongoDBクライアントから確認

もういっこコンソール開く

> cd \xampp\mongodb-win32-i386-1.6.3\bin
> mongo
> 1+2
3
で良し
> Ctrl+C

PHPからMongoDBを使えるようにする

説明ここ

PHP MongoDBドライバはpeclなので、自分でビルドするか誰かがビルドしたものを持ってくるかしないといけない。ここは当然後者。ここからダウンロードする

VC6でts(スレッドセーフ)なバイナリをダウンロード mongo-1.0.10-php5.3vc6ts.zip

展開

php_mongo.dllをc:\xampp\php\ext にコピー

c:\xampp\php\php.iniを編集 [PECL]の後ろに

extension=php_mongo.dll

PHPから動作確認

Xampp-controlからApacheを再起動([stop]-[start])

http://localhost/ のxamppからphpinfo()を表示

“mongo”でページ内検索。設定が出てればOK

PHPから動作確認

適当なphpファイルを作る(mongo.php)

<?php

$mongo = new Mongo('localhost:27017');
$fuga = $mongo->hoge->fuga;
$fuga->insert(array('1' => 1));
echo $fuga->count();

実行

php mongo.php

実行のたびにエラー無く、表示される数が増えれば動いている

あとやること

Apache, (MySQL), MongoDBをWindowsサービスとしてインストールすると、PC再起動したときに動くようにできる。Apache/MySQLについてはc:\xamppの下にサービスにするコマンドがあるのでそれらを実行。

symfony1.3/1.4がリリースされましたね


PHPのフレームワークsymfonyの新しいバージョンがでました!

リリース文

主な変更点はFivestarさんが簡単にまとめられてます

1.2のメンテナンス期間の終わりを根拠に1.0を使い続けるという人がいて最近悲しかったですが、これで堂々と「新規プロジェクトは1.4で」「1.2は1.3で(可能なら1.4)」とできますね。

メールライブラリとしてSwift Mailer 4が同梱されていますが、まだJISメールの問題が直ってないので、ご注意ください。

単発でsymfony1.3/1.4からメールを送りたいだけなら、日本語JISメールに対応した他のメールライブラリをlib/vendorに突っ込んで呼ぶとかでいいと思います。symfonyとSwift Mailerが用意しているいろいろな技をJISでも活用するには、もう少しお待ちください。

symfonyの導入は、新しい1.3/1.4でも日本語のマニュアルが既に用意されています。

Symfony Meetup Tokyoやります


PHPカンファレンス当日でいろいろと連絡が滞っていてすみません。

6(日)昼の「symfonyのFabienさんと東京観光」は予定通りやります。これまで参加を表明された方は、朝10:00に四谷に集まると思っていてください(途中から参加とか遅れる人のために、あとでメールで詳細は送ります) まだ人数増やせると思うので参加表明はこちらを読んでください。

6(日)の夜、こちらも四谷近辺で、Symfony Meetupをやります。懇親会です。いい機会なのでsymfony使いで集まってゴハンを食べましょう。

申し込みフォーム

Symfony Meetup Tokyoは盛況のうちに終了いたしました。参加くださったみなさま、ありがとうございました!

技術メディアのみなさん、symfonyのFabien Potencierさんへの取材どうでしょう?


PHPカンファレンスの開催がいよいよ明日・明後日となりました。

今回は、10周年ということで海外からも3名の講演者をお呼びしての充実したカンファレンスとなっています。(参加は両日とも満員で締め切っています)

symfonyのリーダーFabien Potencierさん、FacebookのBrian Shireさん、台湾PHPユーザー会の江 明宗さんのお三方は、なかなか東京で話せる機会もないと思いますので、ぜひ取材等いかがでしょうか? (拙いですが通訳できます)

特に、カンファレンス当日はPHPカンファレンスのメディアスポンサー各社(スポンサーありがとうございます)のみなさまに、ぜひ取材いただければと思います。

ご興味ありましたら、ぜひPHPカンファレンスでお声をかけていただくか、akimotoアットgmailかtwitter.com/akkyまで御連絡ください

symfonyのFabienさんと東京一日観光


symfonyユーザーの皆様

きたる5日(土)のPHPカンファレンス2009テックデイでは、symfonyのプロジェクトリーダー兼Sensio社の社長であるFabien Potencier(ファビエン・プートンシェ)さんがはるばるフランスから初来日し、symfonyプロジェクトについて講演されます。

今回が初来日、また講演の翌日6日(日曜日)がオフということで、Fabienさんと一緒に日本のsymfonyコミュニティ(ユーザー/開発者)のみなさんとめぐる東京一日観光を行ないます。

二日間のPHPカンファレンスの直後でお疲れかもしれませんが、symfonyの今後についてやプロジェクトの要望などについて直接Fabienさんと話せる貴重な機会になるかと思います(通訳は有志2,3名でお手伝いしますが、ちょっと勇気を出して直接英語で、あるいは仏語でお話してみるのもよいかと)。

ツアー名: (仮)symfonyについて語りつつ一日東京観光
日時: 2009年9月6日(日) 朝から夜まで
場所候補(検討中): 浅草寺・秋葉原・皇居・明治神宮/原宿・まだ大地に立ってればお台場ガンダム・都庁展望台・他に面白いところあれば
移動手段: 電車/徒歩メイン
参加資格: symfonyを使ってる、使いたい、これを機に○○○○○○○から切り替えてみようかな、という人。あと昼食夕食場所の手配とかもろもろ手伝ってくれる人
予定人数: 多くて10人ぐらい? そこまで居ないと思いますが、20人とか30人とかになったらたいへんかもと思いますがどうでしょう?

申し込み: 「a k i m o t o あっと gmail どっと com」へ、サブジェクトに「symfony東京観光参加希望」と入れてください。金曜夜締め切り

symfony1.2でsfSuperCachePluginを使う


symfonyでsuper cacheを実現するsfSuperCachePluginの、symfony1.2での使い方について。

super cacheは、動的にページを生成するWebアプリケーションにおいて、ほとんどの場合にWebサーバの仕組みを使って静的に作成したhtml(等)を直接クライアントに返すことでサーバの応答を早くし、サーバの負荷も軽減する手法です。

よく知られているのはWordPressのSuperCacheプラグインです。これを正しく設定すれば、動的生成でありながら静的生成のパフォーマンスを持つブログを運営することができます。

これまで自作でsuper cache相当の仕組みを作ったことはあるのですが、symfonyのプラグインがあるのでこれが使えるかどうか調べてみました。

とりあえず、READMEにあるように進めてみます。

プラグインのインストール

まず、プラグインはsymfony1.0にしか対応していませんので、普通にsymfonyコマンドでインストールしようとするとエラーになります。

コマンドインストールで失敗したときはいつもそうですが、パッケージを持ってきて自分で展開してみます。バージョンチェックが入ってるだけのことも多いので、これで動いてしまうプラグインも多いです。

> wget http://plugins.symfony-project.org/get/sfSuperCachePlugin/sfSuperCachePlugin-1.0.5.tgz

展開したら、sfSuperCachePlugin-1.0.5 というフォルダを、symfonyの作業フォルダ以下の plugins/sfSuperCachePlugin というフォルダにリネームしつつコピーします。

あとは、pluginsの下のプラグインを全部読むようになっていればsymfony ccするだけで自動的にロードされます。なってなければ、config/ProjectConfiguration.class.php のsetup()で、enableAllPluginsExcept()等を使って読み込まれるプラグインに指定してください。

このまま先へ進んでいくと、1.0と1.2の非互換でエラーになります。先に修正箇所を示すと、sfSuperCacheFilterの次の行


$uri = sfRouting::getInstance()->getCurrentInternalUri();

を、以下のように変更する必要があります。


$uri = sfContext::getInstance()->getRouting()->getCurrentInternalUri();

キャッシュ格納ディレクトリの用意

(symfonyアプリ)/web 以下に、静的ファイルの置き場を作ります。READMEにならって”cache”ディレクトリにします

> cd web
> mkdir cache

Un*xの場合はオーナーやパーミッションも調整してください

フィルタを噛ませる

プラグインの中に入ってるphpは、フィルタファイル一個だけです。これを(frontend)/filters.yml の # insert your own filters here のところに追加します。

supercache:
  class: sfSuperCacheFilter
  param:
    cache_dir: cache
    with_host: false

ホスト名を複数持たないならwith_hostはfalseでいいです。持つ場合、この後の設定も準じて変わるのでREADMEを読んでください。

リクエストがまず静的ファイルを見に行くように、.htaccessを修正

web/.htaccess を書き換えます。以下の2行のところを、


RewriteRule ^$ index.html [QSA]
RewriteRule ^([^.]+)$ $1.html [QSA]

たとえば、以下のように書き換えます。


RewriteCond %{REQUEST_METHOD} GET
RewriteCond %{DOCUMENT_ROOT}/symfony_apps/sandbox/web/cache/supercache/%{PATH_INFO}.php -f
RewriteRule ^(.*)$ cache/$1.php [L]

この書き換え、READMEについてきたREQUEST_URIを使ったものが動かなかったので、自分で動くものを探してこんな風にしました。サブディレクトリにアプリを置いたりしなければREADMEのままのでも動くのかも。mod_rewriteは難しくてよくわからんです。

mod_rewriteが思うように動かないときは、とにかくhttpd.confの設定でrewrite logを取り、出たログを読みましょう。

やってるのは、


web/cache/ほげほげ/ふがふが.php

というファイルがアクセスされて、もしそれがあったら、そのファイルを直に実行して表示してしまう、という処理です。

もしファイルが無かったら、mod_rewriteの処理は下方のルールに落ちて行って、いつものフロントエンドコントローラ(web/index.php)を呼ぶようになっています。

これで、staticファイルが出来てればそのまま表示、出来てなければsymfonyを普通に実行(し、filters.ymlで挟んだフィルタがstaticファイルを生成)、というsuper cacheが完成となります。

super cacheを動かす条件

フィルタファイル sfSuperCacheFilter.class.php の中を読むとわかるのですが、super cacheが発動するには、いろいろな設定がされている必要があります。そうしないと、super cacheを動かしてたつもりが普通のキャッシュされたファイルを見てたりすることにもなります。

  • sf_cacheがtrue/onであること
  • $_GETや$_POSTのパラメータが無いこと
  • sf_debugがfalseであること、つまりデバッグモードでは呼ばれません
  • sf_no_script_nameがtrueであること
  • エラーコードが200(正常)であること。エラーページとかを403で返しているなら、それはsuper cacheの対象外です
  • そのmoduleのdefault cacheが enable: on であること
  • そのmodule/actionの cacheが enable: on であること
  • そのmodule/actionの with_layout: がtrueであること

キャッシュを使うことになってるページで、ページ全体をキャッシュして問題無く、GET/POSTパラメータも渡ってこない(パラメータが違えば普通ページ内容も変わりますから)という条件。

これ全部満たして、はじめてsuper cacheフィルタが効きます。

sfSuperCacheFilter::execute()のチェック文を、デバッガ等で確認しながらsettings.ymlやcache.ymlの設定を変え、(symfony ccもして、)動く設定になってることを確かめてください。

superキャッシュの動作確認

この状態でモジュールをつくり、適当にアクセスしてください。

frontend_dev.phpとか呼んじゃダメですよ。debug offなのでprodである/ (= index.php)を呼びます。


web/cache/(アプリ名)/(モジュール名)/(アクション名).php

などとファイルが出来ていたら、まずフィルタによるstaticファイル生成は合格です。

次に、もう一度アクセスしたときにこの生成されたファイルが開いてるのか、それともsymfony標準のcacheが開いてるのかを確認します。これは、cache/frontend/prod/template/… 以下の標準のキャッシュファイルを手で消してから、ブラウザでアクセスしてみるとわかります。staticなファイルが呼ばれて開かれていれば、標準のキャッシュは作られないはずです。

super cache完成か?

とまあ、プラグインで用意されているのはここまでです。しかし、生成されたstaticなファイルは拡張子が.phpなんですね。そこでそれらのファイルをエディタで開くと、先頭にphpのコードが一行入ってます。


<?php if (time() > 1241771234) { unlink(__FILE__); header('Location: '.$_SERVER['REQUEST_URI']); exit; } ?>

これで、自身のキャッシュ寿命を計りつつ、もし寿命が来ていたら自分自身を削除してもう一度同じURLにリダイレクト、とすることで、expireの処理を行なっているようです。

と、いうことは、このsuper cache、phpを回避してないのですね。厳密には super cacheと言えないのではと思います。たとえ一行とは言え、phpインタプリタをファイル毎に起動しているのです。

このプラグインはここまでなので、PHPを完全にスルーするsuper cacheの実現には、もう一手間かける必要があります。

生成するのは.phpじゃなく.htmlにし、もちろん先頭にphpコードは入れません。.htaccessの定義も.htmlに変えます。

そうなると、キャッシュのexpire判定は自分でやらせるわけには行きません。別のトリガーでこのキャッシュファイルを消すことになります。

たとえば、cronで動かしたスクリプトで定期的にこのcache/以下を見て、ファイル生成時を見つつ古すぎるものを消す、が一案。

もう一つは、CacheManagerで明示的にキャッシュをクリアされるタイミングで、このcache/以下の該当する静的ファイルも削除することです。

super cacheで用意したcache/以下のキャッシュファイルは、先頭行のPHPでexpireを自己診断した際しか消えないので、どのみちCacheManagerでのクリアをどうするかというのは検討しないといけないですね。