CakePHP アーカイブ
CakePHP開発者が知るべき10のこと
- 2011年3月9日 10:00 AM
- CakePHP

先日、こんな記事が上がっていました。
この記事でまとまっているのは、Android開発において必要な10の項目です。
インターフェースの設計から、データの取り扱いまで。
AndroidはモバイルデバイスのOSで、CakePHPは単なるWebフレームワーク。
しかし、予め用意されたルールやAPIを活用する点は同じです。
つまり、フレームワーク全般において、開発者が知るべきことをまとめることが出来るはずです。
ここでは、私が良く利用するCakePHPフレームワークについて、開発者が知るべき10のことをまとめます。
フォーラムにこの記事を書き込んだところ、shunさんがtipsを追記してくれています!
モデルに、配列を取り入れた経緯などを紹介してくれています。
こちらも併せてどうぞ。
1. CakePHPで良いのか

CakePHPを使う際に、知るべきことその1。
それは、あなたは本当にCakePHPを使うべきなのかということです。
現在、あらゆるフレームワークが溢れ返っています。
- Ruby
- Ruby On Rails
- Sinatra
- Python
- Django
- Pylons
- Juno
- Perl
- Catalyst
- CGI::Application
- PHP
- CakePHP
- Zend Framework
- Symforny
- Lemonade
- Java
- Stuts
- Slim3
これだけあるフレームワークの中で、なぜ、私はCakePHPを選ぶのか。
そもそも、その開発に使う言語は、本当にPHPで良いのか。
なぜ、PHPを使うのか。
例えば、Quoraを立ち上げた、Facebookの元CTOのAdam D’Angeloさんはこんなことを言っています。
PHP was out of the question. Facebook is stuck on that for legacy reasons, not because it’s the best choice right now. Our main takeaway from that experience is that programming language choice is very important and is extremely costly to change.
Why did Quora choose Python for its development?より
少し、古い記事ですが、現在のウェブではこれが現実でしょう。
Google App Engine、Amazon AWS、あるいはその他のPaaS。
環境を用意するのは、昔ほど難しくありません。
そして、コストもさほど高くありません。
私は、”PHP/CakePHPを使うな“と言っているのではありません。
盲目的にならず、その開発がどんなものかを考えて、フレームワーク選ぶべきだと言っているのです。
これは、CakePHPに限ったことではありませんが。
2. CakePHPの癖を知る

CakePHPを使うとして、次に知るべきことはCakePHPの癖です。
特にデータの取り扱い、つまりモデル周りには、癖があります。
>>> from mysite.polls.models import Poll, Choice # モデルクラスを import します。 # まだ Poll は一つもできていません。 >>> Poll.objects.all() [] # 新たな Poll を作成しましょう。 >>> import datetime >>> p = Poll(question="What's up?", pub_date=datetime.datetime.now()) # 出来たオブジェクトをデータベースに保存します。 save() は明示的に呼ば # ねばなりません。 >>> p.save() # これでオブジェクトに ID が割り当てられました。お使いのデータベースに # よっては、この値は "1" ではなく "1L" のときもあります。心配することは # ありません。単にデータベースバックエンドが Python 長整数型で値を返す # ようになっているだけのことです。 >>> p.id 1 # データベースの各カラムに Python の属性としてアクセスします。 >>> p.question "What's up?" >>> p.pub_date datetime.datetime(2007, 7, 15, 12, 00, 53) # 属性を変更して save() を呼び出すとカラムの値を変更します。 >>> p.pub_date = datetime.datetime(2007, 4, 1, 0, 0) >>> p.save() # objects.all() はデータベース上の全ての Poll を返します。 >>> Poll.objects.all() [<Poll: Poll object>]
>> p = Post.new(:content => "A new post")
=> #<Post id: nil, name: nil, title: nil,
content: "A new post", created_at: nil,
updated_at: nil>
>> p.save
=> false
>> p.errors
=> #<OrderedHash { :title=>["can't be blank",
"is too short (minimum is 5 characters)"],
:name=>["can't be blank"] }>
Ruby on Rails Guides: Getting Started with Rails: 6.6 Using the Consoleより
PythonやRubyは、あらゆるものをオブジェクトとして扱います。
そのため、データをインサートする際にも、まず、モデルのインスタンスを生成します。
その後、インサート用のメソッドを呼び出し、インサートを完了させます。
しかし、CakePHPではデータを配列で扱います。
データをインサートする際も、新しいインスタンスを作ったりしません。
function edit($id) {
//POST された form データがあるか?
if(!empty($this->data)) {
//form データが有効で保存できた場合...
if($this->Recipe->save($this->data)) {
//セッションにフラッシュメッセージをセットしリダイレクトする
$this->Session->setFlash("Recipe Saved!");
$this->redirect('/recipes');
}
}
//form データがない場合、編集する recipe を検索し
//ビューに渡す
$this->set('recipe', $this->Recipe->findById($id));
}
3 CakePHPによる開発: 3.7.4 データを保存するより
このことを知らなければ、あなたはforeachと配列の地獄に落ちるでしょう。
CakePHPでは、これをすっきりと記述するためにSetクラスが存在します。
Setクラスを活用し、配列地獄に落ちないように、気をつけましょう。
3. 高速開発手法を知る

せっかく、フレームワークを使うのだから、その資産を利用しましょう。
フレームワークの資産、それはプラグインです。
例えば、あなたがtwitter連携機能を開発しているとします。
必要なのは、あなたの書いたコードでなく、これらのプラグインです。
Facebook連携機能をエンハンスするとします。
さらに、携帯サイトに対応するとします。
これらのプラグインを作り、公開してくれる人はだいたい決まっています。
その人たちを把握しておきましょう。
- 国内
- 海外
順不同、敬称略です。
複数のCakePHPプラグインを公開している方をまとめました。
全てgithubへのリンクとなっているので、フォローしておくと良いでしょう。
4. 学習方法を知る

CakePHPを学ぶ方法を知ることは、あなたのためにも、そしてあなたの周りに居る人のためにもなります。
あなたの作ったウェブサイトを、後輩に引き継ぐかもしれない。
あるいは、新たなCakePHP開発者を追加するかもしれない。
こうした場合に、CakePHPの良い学習方法を知っていると役に立ちます。
対象者が、フレームワーク、それどころかPHPの初心者である場合、CakePHPの公式マニュアルが役に立ちます。
これは簡単なブログ作成のチュートリアルで、初心者でも手軽に始めることが出来ます。
しかし、このチュートリアルには弱点があります。
それは、MVCモデルを活用しきれていないこと。
もし、このチュートリアルだけでCakePHPを学習すると、ひどい目に遭います。
次に、学習すべきはこれです。
モデル側にロジックをまとめることを覚えましょう。
あるいは、hiromi2424さんのエントリも大変参考になります。
CakePHPを利用したウェブサイト開発を一通り学習したいのであれば、この本がお勧めです。
|
CakePHPによる実践Webアプリケーション開発
|
CakePHP v1.2を対象に書かれているため、少し情報が古い可能性があります。
しかし、その点を除いても、大変参考になります。
業務アプリケーションを対象とした開発手順は、とても実践的です。
最後に、話題のTDDをCakePHPでも取り入れましょう。
|
Webアプリケーションテスト手法
|
CakePHP 1.3で標準テスティングフレームワークSimpleTestの使い方が、わかりやすくまとまっています。
5. サイトを高速化する

サイトのアクセス負荷が増えてきたときのために、その負荷対策もCakePHP開発者は知るべきでしょう。
まず、簡単なところから。
CakePHP 2.0でも標準で取り入れられたプラグインです。
モデルの読み込みをマジックメソッドに寄せることで、プログラムのロードを高速化します。
一般的なウェブサイトであれば、全てのページが動的である必要はありません。
まずは、デフォルトのキャッシュシステムを利用しましょう。
しかし、このキャッシュシステムは完璧ではありません。
プログラムのロードが少なくなるだけで、少なからずCakePHPが呼ばれます。
そこで、静的ページには次のプラグインを利用します。
このプラグインを利用すると、HTMLの静的ファイルをwebroot以下に吐き出してくれます。
CakePHPにアクセスしないのだから、爆速ですよね。
モデル側のキャッシュは、デフォルトで用意されているキャッシュ機構を利用します。
これを有効化すると、クエリ毎に結果をキャッシュしてくれます。
ただし、1リクエスト毎のメモリキャッシュである点と、データ更新後の挙動には注意が必要です。
最後に、独自のキャッシュ機構を用意する場合。
Cacheクラスを利用します。
自動でシリアライズをしてくれたり、キャッシュの有効期限を決めれたりと、便利なクラスです。
6. デプロイを自動化する

CakePHPはデプロイが簡単です。
作成したアプリケーションを、ウェブサーバが参照出来る場所に置くだけです。
しかし、長期で運用する場合、色々と問題が生じます。
例えば、一時ファイルの問題です。
CakePHPはデフォルトでも、アプリケーションに支障が出ない範囲で様々なファイルをキャッシュし、一時ファイルに格納します。
そのため、新たなコードやファイルを追加した場合に、この一時ファイルが悪さをすることがあります。
予期せぬエラーが発生する場合、この一時ファイルが悪さをしていることが多いのです。
デプロイの度、一時ファイルを手動で消しても良いのですが、それは面倒です。
そして、ミスも増えます。
デプロイの簡単なCakePHPですが、その処理も自動化しておくと、多くのメリットが得られます。
CakePHPもCapistranoを利用し、デプロイを自動化できます。
もし、CLIに慣れないエンジニア、あるいはデザイナーが周りに居る場合は、Webistranoも良いでしょう。
Capistranoを使えば、簡単にデプロイを自動化できます。
しかし、データベースのマイグレーションが課題として残ります。
CakePHPのスキーマシェルは、とても貧弱です。
デフォルトのアップデート機能では、自動デプロイに耐えることが出来ません。
そこで、CakeDCが公開しているMigrationsPluginを利用します。
このプラグインを利用することで、Ruby On Railsのようなマイグレーションシェルを得ることが出来ます。
マイグレーションアップ、マイグレーションダウンも自由自在です。
7. 継続的インテグレーションを取り入れる

“4. 学習方法を知る“の中で、テストの話に簡単に触れました。
もし、あなたがテストケースを運用し始めたなら、継続的インテグレーションを取り入れましょう。
CakePHPでも、Hudsonを利用することで継続的インテグレーションすることが出来ます。
Ryuzeeさんの記事を見れば、数時間で環境を整えられるでしょう。
8. バリデーションを活用する

CakePHPを利用するのに欠かせない機能。
それはバリデーションです。
マニュアルの例は、とてもシンプルです。
バリデーションには、この他にも様々な使い道があります。
“4. 学習方法を知る“でも紹介しましたが、hiromi2424さんの記事を参考にしてください。
さらに、バリデーションを使うにあたって以下のことを踏まえておきましょう。
- バリデーションは必ずしも、テーブルのフィールドと1対1でなくても良い。つまり、テーブルに存在しないフィールドに対しても、バリデーションを定義出来る。
- 独自バリデーションメソッドの中から、保存予定の全てのデータにアクセス出来る。つまり、Model::$dataプロパティを利用し、複雑なバリデーションも書ける。
- Model::beforeValidate()コールバックを利用することで、オプションによってバリデーションを切り替えることが出来る。
バリデーションメソッドは、様々な可能性を秘めています。
9. エディタを活用する

CakePHPを利用出来るエディタを把握しましょう。
PHPを書くことが出来るエディタであれば、開発に支障はありません。
しかし、専用のプラグインがあるエディタを利用すれば、開発速度が上がります。
個人的に残念なのは、有用なvimプラグインがないことです。
そのうち、個人的に開発したいと思っているので、vimmerの方はしばしお待ちを。
10. 最新の情報を得る

最後に、CakePHPのトレンドを把握するために、必要な情報源を押さえましょう。
- 国内
- CakePHPフォーラム
- 24時間CakePHP
- cakephperの日記
- Shin x blog
- Copy/Cut/Paste/Hatena
- ECWorks Blog
- kanonjiの日記
- 半年前の私への教科書
- 開発メモのようなもの
- トーハム紀行
- kaz_29@はてな
- php-tips.com
- kunitの日記
- akiyan.com
- CakePHP のおいしい食べ方
- candycane development blog
- 海外
全てRSSリーダーに登録しておけば、ばっちりですね。
もし、CakePHPネタをたくさん書いてるのに、載っていない!っていう人が居たら教えてください。
掲載させて頂きます。
かなりの長文になってしまいました。
(そして、最後はヘタってしまいました:(
恐らく、生粋のCakePHP Bakerの皆さんは全て押さえているでしょう。
初級、あるいは中級者の方の参考になれば、幸いです。
また、他のフレームワークでも、”知るべき10のこと“シリーズを書いてみませんか?
Gitと一緒にCakePHPを楽しむ – CakePHP Advent Calendar 2010 6日目
- 2010年12月6日 1:00 PM
- CakePHP

これはCakePHP Advent Calendar 2010の6日目の記事です。
CakePHP Advent Calendarって何?という方はこちらへ。
CakePHPに関するtipsを1日1つ、順番に紹介するということなので、私はGitとCakePHPの活用について書きます。
恐らく、これはCakePHPに限らずあらゆるフレームワークで有効なtipsです。
CakePHPを初めとするフレームワークを長く使っていると、色々と面倒なことが起きてきます。
- フレームワークのバージョンアップ
- 外部ライブラリのバージョンアップ
- 複数プロジェクトにおけるコードの共通化
“フレームワークのバージョンアップ“は重要です。
先日、こんなバグも発見されましたしね。
こういったバージョンアップには素早く対処したいもの。
“複数プロジェクトにおけるコードの共通化“も重要です。
例えば、プロジェクトPancake向けに、MobileComponentを作ったとしましょう。
その後に立ち上がったプロジェクトFruitcakeでもモバイル対応が必要だとします。
そこで簡単に思いつくのは、MobileComponentのファイルを丸ごとコピーすることです。
しかし、この方法には問題があることにすぐに気づきます。
MobileComponentでバグがあった場合はどうするか?
プロジェクトPancakeのMobileComponentを修正すれば良いでしょう。
しかし、プロジェクトFruitcakeはどうするか?
コピーし直す?
そんなの面倒です。
しかも、独自の修正がプロジェクトFruitcakeに加えられているかもしれない。
単純にコピーしただけではプロジェクトFruitcakeが動かなくなるかも…。
コンポーネントにバグがあると、突然こんな恐怖に苛まれます。
今日は、これらの手間を省いたり、ソースコードを保証するためにバージョン管理システムGitを使います。
CakePHPのコアコードをGitで管理する
手始めにCakePHPのコアコードをGitで管理しましょう。
CakePHPはGithubで管理されています。
つまり、Gitを使ってソースコードをダウンロードできます。
やり方は簡単です。
Gitがインストールされたサーバで以下のコマンドを実行するだけです。
git clone https://github.com/cakephp/cakephp.git
私はCakePHPのコアコードを共通で使いたいので、/usr/lib以下のcakephp1.3というディレクトリを作って配置します。
つまり、こんなコマンドを打ちます。
cd /usr/lib sudo git clone https://github.com/cakephp/cakephp.git cakephp1.3
次にやるのは、CakePHPを自分の使いたいバージョンに合わせることです。
CakePHPリポジトリでは、バージョンをブランチとタグで管理しています。
現状では、こんなブランチとタグが存在します。
- ブランチ
- 1.2
- 1.3
- 1.3-postgresql
- 2.0
- 2.0-config
- 2.0-controller
- 2.0-pdo
- 2.0-spl
- 2.0-upgrade
- gh-pages
- master
- タグ
- 1.3-dev
- 1.3.6
- 1.3.5
- 1.3.4
- 1.3.3
- 1.3.2
- 1.3.1
- 1.3.0-beta
- 1.3.0-alpha
- 1.3.0-RC4
- 1.3.0-RC3
- 1.3.0-RC2
- 1.3.0-RC1
- 1.3.0
- 1.2.9
- 1.2.8
- 1.2.7
- 1.2.6
- 1.2.5
- 1.2.4
- 1.2.3
- 1.2.2
- 1.2.1
- 1.2.0
ブランチでは、各バージョンの最新のソースコードを管理しています。
タグでは、公式に公開した各マイナーバージョンのソースコードを管理しています。
タグとブランチは、開発する上でその運用が異なります。
しかし、Gitにとってはこれらに違いはありません。
(詳しく知りたい方はオライリーの実用Gitがオススメです。)
git cloneで出来たディレクトリに移動し、以下のコマンドを実行することで、自分の好きなソースコードを手に入れることが出来ます。
ブランチの場合は、以下のコマンドを実行します。
sudo git checkout -t origin/[ブランチ名]
タグの場合は、以下のコマンドを実行します。
sudo git checkout -b [タグ名]
私は先ほどgit cloneで作成したディレクトリで、CakePHP1.3.xの最新版を管理しています。
sudo git checkout -b 1.3.6
このようにディレクトリをGitで管理しておけば、バージョンアップも簡単です。
最新版がリリースされたら、次のコマンドを実行します。
cd /usr/lib/cakephp1.3 sudo git fetch sudo git tag sudo git checkout -b [最新のバージョンナンバー]
これで楽にCakePHPのコアコードのバージョン管理が出来ますね!
ちなみに、この方法で管理しておけば、”コアコードリーディングの途中に、うっかりコードを編集してしまった!“ということも防げますよ。
(git statusを実行すると、どのコードが編集されたかわかります。git checkout — [ファイル名]で編集前の状態に戻せます。)
外部ライブラリをGitで管理する
うまくCakePHPをGitで管理出来ましたか?
次は外部ライブラリをGitで管理してみます。
“自身のプロジェクトのソースコードがGitで管理されていること“を前提とします。
さて、何のライブラリを入れましょうか。
定番のdebug_kitを入れましょう。
自分のプロジェクトのディレクトリに移動した後に、以下のコマンドを打ちます。
git submodule add https://github.com/cakephp/debug_kit.git plugins/debug_kit git add plugins/debug_kit .gitmodules git commit -m 'Add debug_kit plugin.'
これで、plugins/debug_kitにdebug_kitプラグインのソースコードがダウンロードされます。
.gitmodulesという不思議なファイルが出来たので中身を確認してみます。
[submodule &quot;plugins/debug_kit&quot;] path = plugins/debug_kit url = https://github.com/cakephp/debug_kit.git
意味は簡単に分かるでしょう。
- plugins/debug_kitをサブモジュールとして管理しますよ。
- そのモジュールはhttps://github.com/cakephp/debug_kit.gitで管理しますよ。
ということです。
次はこのプロジェクトをgit cloneします。
(プロジェクトのリポジトリは/home/tfmagician/advent_calendarにあるとします。)
git clone file:///home/tfmagician/advent_calendar ~/advent_calendar_clone cd ~/advent_calendar_clone ls plugins/debug_kit
git cloneは出来たのですが、plugins/debug_kitの中身は空です。
そこで以下のコマンドを打ちます。
cd ~/advent_calendar_clone git submodule init git submodule update ls plugins/debug_kit
これでplugins/debug_kitにソースコードがダウンロードされました。
この状態では、debug_kitは名無しのブランチとなっています。
そこで、debug_kitを自分の使いたいブランチに切り替えます。
cd ~/advent_calendar_clone/plugins/debug_kit git checkout -b 1.3.0 git branch
これで外部ライブラリのバージョンを、自身のプロジェクトと別に管理できます。
git submodule addしたライブラリは、単純なGitのリポジトリです。
バージョンアップがあった場合は、git fetchやgit pullで最新の状態に更新できます。
しかし、少し注意点が。
git submoduleは便利なのですが、git cloneをするときに少し手間です。
先ほど示した通り、サブモジュールのブランチは手動で切り替える必要があります。
実際に使う場合は、git submodule initやupdate、ブランチの切り替えなどをひとまとめにしたセットアップスクリプトを用意しておくと良いかもしれませんね。
より詳しくgit submoduleについて知りたい場合は、以下のページが参考になります。
CakePHPでは、ソースコードを以下のように管理するよう規約で決まっています。
(不要な部分は省いています。)
models/ # アプリケーションで使用するモデル + behaviors/ # モデルの処理を共通化するビヘイビア views/ # アプリケーションで使用するビュー + helpers/ # ビューの処理を共通化するヘルパー controllers/ # アプリケーションで使用するコントローラ + components/ # コントローラの処理を共通化するコンポーネント plugins/ # CakePHPのプラグイン vendors/ # 外部ライブラリ
このうち、git submoduleで管理するのはpluginsディレクトリとvendorsディレクトリでしょう。
behaviorsやcomponents、helpersもgit submoduleで管理したくなるのですが、そのあたりの住み分けは次で説明します。
自分のコードをGitで管理する
最後は、自分のコードをGitで管理しましょう。
自分のコードといっても、単純にGitを使うだけではありません。
git submoduleを使った複数プロジェクトでのコード管理です。
git submoduleの使い方は、先ほど説明したので省略します。
CakePHPにおいて、どのようにgit submoduleを活用するかに焦点をおきます。
models/ # アプリケーションで使用するモデル + behaviors/ # モデルの処理を共通化するビヘイビア views/ # アプリケーションで使用するビュー + helpers/ # ビューの処理を共通化するヘルパー controllers/ # アプリケーションで使用するコントローラ + components/ # コントローラの処理を共通化するコンポーネント plugins/ # CakePHPのプラグイン vendors/ # 外部ライブラリ
CakePHPではこのような構成を取ります。
プロジェクトを立ち上げた後、共通処理がbehaviorsとcomponents、そしてhelpersにまとまります。
コードを書いていると、ふと気づきます。
このコードは他のプロジェクトで再利用出来るんじゃないか?
そのことに気づいた時点で、そのコードは別に管理したくなるはずです。
幸いにもCakePHPにはプラグインという仕組みがあります。
CakePHPのプラグインでは、pluginsディレクトリの中に通常のCakePHPアプリケーションと同じ構成のアプリケーションを配置できます。
配置したアプリケーションは、親のアプリケーションから自由にインポート出来ます。
つまり、再利用したいと考えたコードはプラグインとしてまとめて、git submoduleで管理すれば良いんです。
例として、ビヘイビアに焦点を当てて考えてみましょう。
以下の構成で、RicepanBakerBehavior(ricepan_baker.php)を複数プロジェクトで共通化したいとします。
models/
+ behaviors/
ricepan_baker.php
something.php
tests/
+ cases/
+ models/
+ behaviors/
ricepan_baker.test.php
something.test.php
+ fixtures/
bakery_fixture.php
something_fixture.php
plugins/
これをこのように変更します。
models/
+ behaviors/
something.php
tests/
+ cases/
+ models/
+ behaviors/
something.test.php
+ fixtures/
something_fixture.php
plugins/
+ ricepan/
+ models/
+ behaviors/
ricepan_baker.php
+ tests/
+ cases/
+ models/
+ behaviors/
ricepan_baker.test.php
+ fixtures/
bakery_fixture.php
これで、ソースコードやテストケースを完全に分離できました。
あとはplugins/ricepanをGitリポジトリとして分離し、どこかにホストすればOKです。
その後は、先ほど紹介したgit submoduleを使って管理ですね。
ホストする場所はどこでも良いのですが、せっかくなのでGithubなどの公開リポジトリに置けないかを考えてみましょう。
ソースコードを公開すれば、それだけ共通の資産が増えますからね。
他の人のアドバイスも貰えるかもしれない。
自分の成長の手助けにもなるでしょう。
いかがでしょうか。
初心者向け…で書いたつもりが、GitやCakePHPの前提知識がかなり必要な内容となってしまいました。
しかし、Gitは使いこなすと本当に便利です。
フレームワークとも相性はバッチリです。
どんどん活用していきましょう!
明日は@ecworks_masapさんです。
CakePHP辞典の著者としてものすごいtipsを書いてくれるでしょう!
期待してます!
|
CakePHP辞典
|
CakePHP 1.3で大量のクエリを投げるときの注意点
- 2010年10月29日 12:00 AM
- CakePHP

今日は簡単な記事です。
自分がハマったので、他の人がハマらないように情報共有を。
CakePHPネタで、特にシェルを使っている人向けの記事です。
興味がない方はスルーしてください。
CakePHPで大量のクエリを投げる
CakePHPで、データベースに対して大量のクエリを投げたことがありますか?
お知らせメールでは、シェルもCakePHPで書いています。
そのため、一度の実行で大量のクエリが発行されることがあります。
クエリといっても、CakePHPのラッパーのModel::find()やModel::save()のことです。
これをレコード分繰り返すことがあります。
この場合、一回の実行あたりのクエリ発行数は数千から数万に。
このような処理を書いていると、どうもおかしな現象に出くわします。
Warning: SQL Error: 1054: Unknown column 'ComicAuthorMergeQueue.base_id' in 'where clause' in /usr/lib/cakephp1.3/cake/libs/model/datasources/dbo_source.php on line 673 Query: SELECT `SearchIndex`.`id`, `SearchIndex`.`search_index` FROM `search_indices` AS `SearchIndex` WHERE `ComicAuthorMergeQueue`.`base_id` = 6899
ん…こんなクエリ発行した覚えはないんだけど?
初めはモデル周りの参照の関係が原因だと考えました。
しかし、実はもっと根が深い問題で、CakePHPのキャッシュが絡んでいました。
CakePHPがWHEREをキャッシュしている
CakePHPはデフォルトでWHERE文をキャッシュしています。
例として、Model::find()を取り上げます。
$params = array(
'conditions' => array('id = ' => 1000));
$this->User->find('all', $params);
SELECT * FROM `users` AS `User` WHERE `User`.`id` = 1000;
この”‘conditions’ => array(‘id = ‘ => 1000)“と”WHERE `User`.`id` = 1000“の対応関係をキャッシュするのです。
キャッシュする場所はインスタンスのプロパティ。つまりメモリキャッシュです。
そのため、二度目に同じ条件のModel::find()を呼んだ場合、SQLは動的に生成されません。
メモリキャッシュからWHERE文を取り出し、そのまま使用します。
/**
* Returns a quoted name of $data for use in an SQL statement.
* Strips fields out of SQL functions before quoting.
*
* @param string $data
* @return string SQL field
* @access public
*/
function name($data) {
if (is_object($data) && isset($data->type)) {
return $data->value;
}
if ($data === '*') {
return '*';
}
if (is_array($data)) {
foreach ($data as $i => $dataItem) {
$data[$i] = $this->name($dataItem);
}
return $data;
}
$cacheKey = crc32($this->startQuote.$data.$this->endQuote);
if ($return = $this->cacheMethod(__FUNCTION__, $cacheKey)) {
return $return;
}
/**
* Cache a value into the methodCaches. Will respect the value of DboSource::$cacheMethods.
* Will retrieve a value from the cache if $value is null.
*
* If caching is disabled and a write is attempted, the $value will be returned.
* A read will either return the value or null.
*
* @param string $method Name of the method being cached.
* @param string $key The keyname for the cache operation.
* @param mixed $value The value to cache into memory.
* @return mixed Either null on failure, or the value if its set.
*/
function cacheMethod($method, $key, $value = null) {
if ($this->cacheMethods === false) {
return $value;
}
if ($value === null) {
return (isset($this->methodCache[$method][$key])) ? $this->methodCache[$method][$key] : null;
}
return $this->methodCache[$method][$key] = $value;
}
ちょっと省略していますが、このコードがそのキャッシュに当たる部分です。
詳しく調べたい方はdbo_source.phpのDboSource::cacheMethod()を追ってください。
ここで見て分かる通り、crc32()を使ってハッシュを管理しています。
実はこのcrc32()を使ったハッシュは数万件のデータで衝突が発生するようです。
衝突が起こると、まったく無関係のWHERE文がModel::find()やModel::save()に対して呼ばれます。
その結果が冒頭のエラーです。
キャッシュをオフにする
この現象を突き止めるまでは色々と調べて回りました。
この情報に辿りつくまでに半日ぐらい掛かりました。
CakePHPのチケットです。
このチケットには、こうあります。
I think documentation is a good approach. Fully unique hashes can be slower than crc32 which is why it was chosen. Disabling the cache when its not helpful and providing good documentation on how to do that is probably more pertinent.
#870 Issues with DboSource::$methodCache – CakePHP – cakephpより
これに従って修正されたAPIドキュメントがこれです。
Caches result from query parsing operations. Cached results for both DboSource::name() and DboSource::conditions() will be stored here. Method caching uses `crc32()` which is fast but can collisions more easily than other hashing algorithms. If you have problems with collisions, set DboSource::$cacheMethods to false.
Commit e023350af57e07ac3351ab86c07361697fc1b369 to cakephp’s cakephp – GitHubより
なるほど。
DboSourceクラスのcacheMethodsプロパティをfalseに設定すれば良いみたいです。
そうすれば、このキャッシュはオフになると。
余談ですが、CakePHP側ではこの部分の衝突を問題にしていないようですね。
パフォーマンスの問題と、使用方法を天秤にかけたのでしょう。
CakePHPはWebフレームワークで、シェルの重たい処理なんて想定してないでしょうから。
シェルでこのキャッシュ機能をオフにするために、AppShellクラスを作ります。
<?php
App::import('Shell', 'Shell');
class AppShell extends Shell {
var $cacheMethods = false;
function initialize() {
$db =& ConnectionManager::getDataSource('default');
$db->cacheMethods = $this->cacheMethods;
parent::initialize();
}
}
あとは、これを各シェルのクラスが継承すればOKです。
<?php
App::import('Shell', 'AppShell');
class EggShell extends AppShell {
}
キャッシュをオンにしたいシェルがある場合は、こう書きます。
<?php
App::import('Shell', 'AppShell');
class EggShell extends AppShell {
var $cacheMethods = true;
}
これでOKです。
ここではシェルクラスにAppShellを継承させる形で解決しましたが、これはCakePHP 1.3.x限定です。
CakePHP 1.2.xではシェルクラスに自分で作ったクラスを継承させることができません(厳密に言えばできるのですが、色々と動かなくなるのでそれの対処が面倒くさい)。
ちなみに、この内容はPHP MatsuriのJIREI Nightで話した内容です。
もし、同じ現象でハマった場合は試してみてください。
[書評] これを読めばCakePHPに再度惚れられる?CakePHP辞典
- 2010年10月24日 1:00 AM
- CakePHP

Bakerの皆さんはCakePHPの魅力は十分に分かっているでしょう。
しっかりとした規約と十分にラップされたデータベース周りのロジック。
様々な環境に簡単にデプロイ出来るPHPの強みとPHPの手軽さ。
私自身、CakePHPを使い始めて2年目になります。
2年もCakePHPのコードばかりを書いていれば、CakePHPのうまみを全て味わい尽くしたようにも思えます。
しかし、それを見事に”CakePHP辞典”が打ち崩してくれました。
書店で手に取り、目次を読んだ時点でCakePHPの魅力や楽しさが蘇ってきました。
CakePHPにはまだまだ知らない深みがあると。
CakePHP辞典とは
CakePHP向けの携帯サイト構築用ライブラリ”KtaiLibrary“を作成している@ecworks_masapさんこと滝下真玄さんが書かれた本です。
帯には以下のように書かれています。
随一の圧倒的な情報量!
フレームワークの新しい使い方が、必ず見つかる本!
え、誇大広告過ぎやしないか?とも思えるこの謳い文句。
そう思っても、騙されたと思って手に取ってみてください。
始めの1分で謳い文句通り”フレームワークの新しい使い方“が見つかります。
私がそうでした。
“滝下さんに買いますね!書評書きますね!“と言っておきながら、実は買うかどうか迷っていた(苦笑)
そこで、書店に行って実際に内容を見てみることにしました。
行ったのは”有林堂 戸塚駅前支店”(自宅がこの周辺なのでよく現れます)。
こんなところにも、ちゃんと置いてありました。
それで、ぱっと目次を開いた瞬間…これは買いだな、と。
そんな本です。
API代わりに使う
それで、なぜ”ぱっと開いた瞬間に買うことが決まる“のか。
それは目次の情報量に秘密があります。
ちょっと失礼して、目次を引用してみます。
(ページ番号は省略しています)
モデルクラス
バリデーション
アソシエーション
AppModelクラス
Modelクラス・プロパティ
Modelクラス・メソッド
Model::find() データソースからデータを検索して入手
Model::findBy() 指定フィールドを条件付けて検索
Model::bindModel() アソシエーション設定を動的に行う
Model::unbindModel() アソシエーションを動的に解除する
Model::setSource() 指定したテーブルでモデルのセッティングを行う
Model::set 値をセット
Model::deconstruct() 日時データを指定フィールドが認識できる日時形式に加工
Model::schema() スキーマを入手
Model::getColumnType() 指定カラムのデータ形式を入手
Model::getColumnTypes() 各カラムのデータ形式をまとめて入手
…
滝下真玄著 – CakePHP辞典より
えー、書ききれませんね。
これは”モデル”の目次の3分の1も書けていません。
こんな目次が始めの21ページに渡り、書かれています。
“ぱっと見で機能がわかる目次“がこの本の大きな魅力の一つだと思います。
この情報は普段ならCakePHPのAPIドキュメントから探します。
しかし、このドキュメントは英語である上に、説明がある程度までしか書かれていません。
さらにサンプルコードも少ない。
単純に比較する訳にはいかないのですが、APIドキュメントは下記のリンクの”Model::find()“の説明を見てください。
これに対して、”CakePHP辞典”にはここまで説明があります(引用するのはModel:find()の説明の一部だけです)。
$typeに設定する値
- all : 条件に合致するすべてのデータを取り出します
- first : 最初に見つかったデータのみを取り出します
- list : 指定したフィールドのデータをリスト化して取り出します。指定フィールドが1つの場合は、idをキーとする連想配列で取り出します。指定フィールドが2つの場合は「1番目 => 2番目」の連想配列で取り出します。フィールドが無指定の場合はidを配列で取り出します。
- threaded : 通常は自分のレコードとアソシエーションモデルのレコードを1レコード値として受け取ることができますが、threadedを指定すると、そのレコードの親子関係を解析し、子レコードを階層で取得することができます。このレコード内にさらにこのレコードが存在する場合も再帰的に取得します。この機能を使う場合は「parent_id」という名前のフィールドが必要になります(ほかの名前に変更することはできません)
- neighbors : find(‘first’)と似ていますが、これは該当レコードの隣り合ったレコードの情報を取得できます。連想配列で「prev」キーの値は該当レコードの値の前のレコード、「next」には後のレコードが格納されます。
滝下真玄著 – CakePHP辞典より
このように、”この辞典一冊で特定のメソッドの使い方がわかる“というのが魅力の二つ目です。
そしてこの二つの魅力が合わさることで、あなたは(少なくとも私は)CakePHPに再度惚れてしまうでしょう。
例えば、私は普段使わない”SecurityComponent“に地味に使える機能があることに気がつきました。
Securityコンポーネント
SecurityComponentのクラス・プロパティ
SecurityComponentのクラス・メソッド
SecurityComponent::requirePost() POST形式のリクエストを必要とするアクションを指定
SecurityComponent::requireGet() GET形式のリクエストを必要とするアクションを指定
SecurityComponent::requirePut() PUT形式のリクエストを必要とするアクションを指定
SecurityComponent::requireDelete() DELETE形式のリクエストを必要とするアクションを指定
…
SecurityComponent::blackHole() 不正なリクエストに対して行う処理を指定する
滝下真玄著 – CakePHP辞典より
POST、GETなどの形式を制限することが出来るんですね!
さらに”SecurityComponent::blackHole()”というコールバックメソッドまで。
うまく使えば、いつも自分で書いているあんなことやこんなことが簡単に…。
皆さんに知っていてもらいたいのは”Set“クラスですね。
CakePHPは基本的にデータを配列で扱います。
そのため、コードの大半が配列処理で埋まります。
この世話を色々としてくれるのがこの”Set“クラス。
もちろんSetクラスも”CakePHP辞典”に載っていますよ。
と、あまり詳しく書いたり、引用すると滝下さんに怒られてしまいそうです(笑)
あとは、本を読んで勉強してくださいね。
便利なtipsを知る
先ほど紹介した辞典的な使い方も良いのですが、ちょっとしたtipsもCakePHP辞典には載っています。
“これは良いな“と思ったのが、30ページにある”開発環境と本番環境でのコードの共通化“というtips。
(コメントは省略しています)
class DATABASE_CONFIG {
var $default;
var $default_pub = array(
);
var $default_dev = array(
);
function DATABASE_CONFIG(){
if($_SERVER['SERVER_ADDR'] == '12.34.56.78'){
$this->default = $this->default_pub;
}else{
$this->default = $this->default_dev;
}
}
}
滝下真玄著 – CakePHP辞典より
このようなコードを示したtipsがいくつか載っています。
どれもこれも、すぐに実践で使えるコードです。
これもCakePHP辞典の嬉しいところ。
おまけ、しかし有益な情報
この情報は”資料“として載っているものです。
おまけとして載せたのでしょう。
しかし、とても有益な情報です。
- CakePHPの定数
- すぐに忘れるのがこの定数。各ディレクトリのパスなどが格納される定数が一覧化されています。
- CakePHPの処理の流れ
- CakePHPの処理が図示されています。コアコード読むのに便利!
- CakePHPバージョン1.2と1.3の違い
- 1.2と1.3の差異の概要が分かる。
- CakePHPに関する情報の入手
- この情報は初心者にとってとても有益。フレームワークを始めたころは、どこから情報を入手するのかわからないですから。ここを網羅しておけばとりあえず大丈夫でしょう!
あとは最後の索引。
“名前は分かるんだけど、どうやって使うんだっけ…“という場合は最後の索引から探してください!
ここにも全てのクラスとメソッドが網羅されてます。
CakePHP辞典はまさに”辞典“と呼ぶに相応しい内容です。
情報へのアクセスのしやすさ、その内容の濃さ。
表現力を高めるために、よく”辞書を読書する“ということが行われます。
小学生のときに先生にやらされた方もいるはず。
フレームワークの表現力を高めるためにも、是非”CakePHP辞典”を読書してください。
CakePHPの魅力に気づき、再度惚れてしまうこと間違いなし。
|
CakePHP辞典
|
CakePHPでメールの送信を簡単にするEmailPlugin
- 2010年10月14日 11:30 PM
- CakePHP

CakePHP付属のEmailComponentは使いにくくありませんか?
色々な設定を何度も書かなければいけなかったり、シェルで使うために自分で設定を初期化しなければいけなかったり。
そういった点を解消したプラグインを作ったので紹介します。
しかし、まだ発展途上なのでバグがあったり、機能が足りなかったりするかもしれません。
気長に見守ってやってください:D
EmailPluginとは
先ほど説明した通り、CakePHP付属のEmailComponentを使いやすくしたプラグインです。
メールに関する機能を取りまとめたいと思い、EmailPluginと名付けました。
現在、EmailPluginには以下のクラスが含まれています。
- ExEmailComponent
- EmailComponentを継承したクラス
- EmailShell
- ExEmailComponentをシェルで使うためのクラス
この二つのクラスを使って、メールの送信を簡単に行うことが出来ます。
基本的な使い方はCakePHP付属のEmailComponentと同じなので、CakePHPのマニュアルに目を通しておくと、説明が理解しやすいと思います。
設定を作成する
EmailPluginを使うにあたって、設定ファイルを作る必要があります。
CakePHPの設定ファイルであるdatabase.phpに似せて作ってあります。
/path/to/your_app/mailer.php
<?php
class MAILER_CONFIG {
var $default = array(
'to' => 'to@test.com',
'from' => 'from@phpmatsuri.com',
'replyTo' => 'replayTo@test.com',
'readReceipt' => 'readReceipt@test.com',
'cc' => array('cc@test.com'),
'bcc' => array('bcc@test.com'),
'subject' => 'This is test.',
'headers' => array('headers'),
'additionalParams' => array('additionalParams'),
'layout' => 'default',
'template' => 'phpmatsuri',
'lineLength' => false,
'sendAs' => 'text',
'delivery' => 'smtp',
'charset' => 'utf-8',
'xMailer' => 'PHP Matsuri Mailer',
'port' => 25,
'host' => 'localhost',
'timeout' => 10,
'username' => 'test@m.ubuntu',
'password' => 'test',
'client' => 'testclient',
);
}
各設定値はEmailComponentのプロパティと同じです。
もちろん、省略も可能です。
設定値の意味合いを知りたい方はCakePHPのAPIを参照ください。
$defaultだけでなく、自分の好きな名前で設定を作ってください。
そうすると、コントローラやシェルから動的に設定値を変更出来ます。
コントローラからメールを送る
コントローラからメールを送るには、“Email.ExEmail”をコンポーネントとして、$useMailerConfigにMAILER_CONFIGに設定した名前をセットするだけです。
class MailController extends Controller {
var $uses = array();
/* Email.ExEmailをコンポーネントとして定義します。 */
var $components = array('Email.ExEmail');
/* MAILER_CONFIGのプロパティの名前を指定してください。 */
var $useMailerConfig = 'default';
function index() {
if(isset($this->params['data']['send'])) {
/* 設定を動的に変える場合はExEmail::useConfig()を使います。 */
// $this->ExEmail->useConfig($this->params['data']['setting']);
/* 各設定を動的に変える場合はEmailComponentと同様にプロパティを変更します。 */
$this->ExEmail->to = $this->params['data']['to'];
$this->ExEmail->set('body', $this->params['data']['body']);
/* 送信はもちろんExEmail::send()を使います。 */
$this->ExEmail->send();
/* あとはお好きに処理を書いてください。 */
$this->set('error', $this->ExEmail->smtpError);
$this->render('result');
}
}
}
シェルからメールを送る
シェルからメールを送る場合もコントローラと同様です。
$componentsプロパティを設定する必要がない点が異なります。
また、通常シェルでは指定出来ない$helpersプロパティも指定出来ます。
$helpersプロパティを指定すると、メールのテンプレート中で指定したヘルパーが使用出来るようになります。
言い忘れていましたが、AppShellでなくEmailShellを継承してください。
EmailShellを継承しないと、ExEmailComponentを使ってメールが送れません。
/* プラグインからEmailShellを読み込みます。 */
App::import('Shell', 'Email.EmailShell');
/* EmailShellを継承してください。 */
class SendShell extends EmailShell {
/* MAILER_CONFIGのプロパティの名前を指定してください。 */
var $useMailerConfig = 'default';
/* メールのテンプレートで使用するヘルパーを指定してください。 */
var $helpers = array('Html', 'Time');
function startup() {
}
function main() {
/* 各設定を動的に変える場合はEmailComponentと同様にプロパティを変更します。 */
$this->ExEmail->to = 'test@test.com';
$this->ExEmail->set('body', $this->params['body']);
$this->ExEmail->send();
/* あとの処理はご自由にどうぞ。 */
if(empty($this->ExEmail->smtpError)) {
$this->out('Complete.');
return;
}
$this->out($this->ExEmail->smtpError);
}
}
ちょっとした機能
ちょっとした機能も追加されています。
- 文字コードの自動変換
- デフォルトのEmailComponentは文字コードを自動で変換しませんが、ExEmailComponentは$charsetプロパティの値を見て自動で文字コードを変換します。
- 自動改行禁止
- EmailComponentはRFC2822で推奨される1行 = 70字を守り、自動で改行を入れてくれます。しかし、ここで使われているwordwrap関数はマルチバイトに対応していません。そのため、日本語で送信する場合はこれが文字化けの原因となります。これを防ぐため、自動改行禁止のオプションを追加しました。ExEmailComponentの$lineLengthプロパティにfalseを指定することで自動改行を禁止します。
今後の拡張
今後の拡張として、以下を考えています。
- 空メール登録機能
- エラーメール処理機能
- メールキュー機能
EmailPluginを入れることで、”簡易的なメルマガサーバ“を作ることが出来れば良いな、と。
EmailPluginはCakePHP 1.3+専用で、githubで公開しています。
説明文を書いていたら、いつもと違い、堅苦しい文章になってしまいましたorz
まだまだ、発展途上なプラグインです。
将来性を考慮して使って頂ければありがたいですね。
PHP Matsuriに行って、日本のエンジニアのリアリティを感じてきた
- 2010年10月5日 1:00 PM
- CakePHP

先日、PHP Matsuriが盛大に開催されました。
1-byte.jpでもPHP Matsuriの紹介記事を1ヶ月ほど前に書きました。
これを書いたときは、不参戦表明をしていたのですが、急遽参加出来ることが決定。
気張って参加してきました!
PHP Matsuriで何が起こったか
会場は、総勢約80名ほどのPHPer達の熱気が充満しています。
長い期間を掛け、準備してきたスタッフ達、今日のためにハックネタを用意してきたエンジニア達…。
とにかく、様々な方々が様々なところから、様々な期待を込めて集まっていました。
その中にはCakePHP、Lithium、Symfonyのコアデベロッパも含まれます。
PHP Matsuriと普通の勉強会は何が異なるか。
その一つがこのコアデベロッパの存在です。
普通に、他の勉強会でも海外のすごいデベロッパが来ています。
PHP Conference 2010でもPHPの生みの親である”Rasmus Lerdorf“さんも来ていましたしね。
しかし、PHP Matsuriでは”このデベロッパと一緒に開発出来る“ことが大きな差です。
徹夜で2日間、隣の席に座って開発出来るんです。
食事さえ一緒でした。
こんな機会は滅多にありません。

PHP Matsuriで一緒に開発するGrahamさん
Web上だけでは得られない”リアリティ“を感じた2日間でした。
英語を感じる
オープニング・セッション、”Linuxカーネル読書会“のよしおかひろたかさんから。
話の中心は”ハッカソンで何をすべきか、何を学ぶべきか“です。
内容は”Linuxカーネル読書会“や”プログラミング&セキュリティキャンプ“を踏まえて、こういった場でどのように大人のエンジニアが勉強するか。
中学生や高校生が”プログラミング&セキュリティキャンプ“に来て、”英語のリアリティを感じる“という話がとても印象的でした。
始めはLinuxのカーネルを開発したいだけ。しかし、そのディスクリプションを英語で書く必要があることを知り、英語のリアリティを感じる。
これってとても大事ですよね。
自分が学生時代に足りなかったことでもあります。
さらに話は、”達人と弟子“へ。
Learn how to learn. “学び方を学ぶ”
実際に”Linuxカーネル読書会“、”プログラミング&セキュリティキャンプ“、そして”PHP Matsuri“に来て、あなたの達人を見つける。
そして、”達人がどのように学んでいるのか“を学び、弟子は達人になる。
その上で不可欠なのが”濃密なコミュニケーション“。
やはり、先ほどの”英語“の話に帰着します。
まさに、”PHP Matsuri“はこれを感じ取り、学ぶ場であったように思えます。
技術を学ぶ
技術を学ぶ上で重要なのは、
- あなたの達人を見つけること
- 自分のモチベーションを高めること
この2つです。
“PHP Matsuri“はこの両方が揃った場であったと言えます。
まずは1つ目、”あなたの達人を見つけること“です。
これは”コアデベロッパ“と”総勢約80名の日本のエンジニア達“です。
この中には自分よりもレベルの高いエンジニア、低いエンジニア、同じレベルのエンジニアがいます。
(ちなみに自分は最下層のほうですが:D)
そして、それぞれの得意分野も違います。
これだけいるのですから、見つからないのがおかしい話。
あとはあなたのコミュニケーション次第。積極的にいけばたくさん学べるし、一言も話さなければ一つも学べない。
それはコアデベロッパの方から学ぶときも同じことです。
今回、来日した4名の方々はとてもフレンドリーに接してくれました。
つまり、後は
英語を話せるかどうかではなく、英語を話そうとするかどうか。
ということです。
分からないことは聞いてみれば良いんです。
片言の英語と、ソースコードを見せながら。
今回、会場を見ていて思ったのは”これが出来る人と出来ない人の差が大きい“ということです。
これも一つのリアリティでした。
“英語は完璧じゃなくていい“といった趣旨のブログ記事がよく上がりますが、このリアリティです。
英語を完璧に話すよりも、伝えることを優先する。
これも”日本と海外“のリアリティではないでしょうか。
ちょっと話が逸れている気がしますが、”PHP Matsuriには学ぶためのあなたの達人はたくさんいた。そして達人に学ぶかどうかはあなた次第。“ということです。
そして2つ目、”自分のモチベーションを高めること“です。
“ハッカソン“という環境があなたのモチベーションを高めてくれます。
人間は不思議なもので、周りの感情次第で良くも悪くもなる。
その場の雰囲気が確実に自分に影響します。
もちろん、周りの雰囲気に関わらず、最高の状態を保てる人もごく少数いると思います。
しかし、少なくとも自分はそうではない。
私は完全に”ハッカソンの熱気“にやられた一人です。
その結果が”徹夜での開発“と”発表出来ないと思っていた成果物の完成“です。
この光景は夜中の会場を見れば感じてもらえると思います。

午前1時の開発風景
これ午前1時ですよ。この時点でほぼ全員が開発を続けています。
そして、時間と共に人数は減りましたが、最終的に30名ほどの方が徹夜で開発していました。
そして残った方々はデモのぎりぎりまで、ひたすらコードを書いていました。
ちょっと皆さんおかしくないですか?(笑
しかし、この環境はすごく心地良いものです。
自分のやりたいことに没頭出来る。
聞きたいことは周りに聞ける。
周りからすぐにフィードバックがあり、それを成果物に含める。
そして、その人の開発がガンガン進み、周りもつられて開発を進める。
ま、もちろんエネルギーは使い果たしますが。
そして自分は
自分の成果物は次の2つです。
- “JIREI NIGHT お知らせメール”の発表
- “EmailPlugin”の公開
“JIREI NIGHT“では15分の枠を頂き、CakePHPで開発した”お知らせメール“というサービスを発表させて貰いました。
ハッカソンではCakePHPのコアコンポーネントであるEmailComponentを使いやすくしたEmailPluginを作り、発表しました。
目に見える成果はこの2つですが、この他にたくさんの学びと自分を鍛え直す決意を得ました。
学び得たことは、技術的なことよりも精神的なことが多いです。
まさに”学び方を学んで来た“ようです。
- 英語を話せるかどうかではなく、英語を話そうとするかどうか。
- 自分の強みが相手の印象に。
- ハック = アイディアであること。
英語を話せるかどうかではなく、英語を話そうとするかどうか。
これは先ほど説明した通りです。
“英語を話そうとするかどうか“の意思の差はとてつもなく大きいです。
これが今の自分の”英語のリアリティ“です。
自分の強みが相手の印象に。
恐らく自分は、PHP Matsuriのエンジニアの方々に印象づけられなかったでしょうね。
強みが何一つない。
普通のことを普通にやっているだけじゃ、ダメなんです。
特にコミュニケーションの苦手な自分は。
それを感じ取れました。
テストの達人、@sizuhikoさん。
KtaiLibraryの@ecworks_masapさん。
TDDの@hirocastさん。
CakePluginの@k1LoWさん。
CakePHP + mongoDBの@cakephperさん。
CakePHPドキュメント翻訳の@hiromi2424さん
他にもまだまだ印象深いエンジニアの方々は居たのですが、長くなってしまうのでここまで。
Webの情報がリアル(PHP Matsuri)に繋がり、そこ(PHP Matsuri)でやっていることでさらにその人を印象づける。
そういった流れで、今回顔と名前を覚えた方々もたくさん居ます。
こういった流れを自分も作って行きたいところです。
ハック = アイディアであること。
あくまで”ハック“なので、便利なものを追求する姿勢もありだと思います。
そもそも、その”便利“でさえ、アイディアであるとは思うのですが、今回感じたのは”別のアイディア“です。
最後のデモで”変態的“という言葉が飛び交っていました。
“変態的“とは”突飛なアイディア“だと思います。
誰も考えつかなかったことを、2日間で形に仕上げる。
その短い時間と、その突飛なアイディアが相まって、最後のデモは異常な盛り上がりを見せていました。
ハック = アイディア
当たり前なのですが、これも意識出来るか、出来ないかで大きく変わってくると思います。
今回、私はこれを意識出来ませんでした。
“実際に使えるものを。“という意識が、自分のアイディアを縛ってしまったのかもしれません。
次回は自由なアイディアで、”ハック“していきたいですね。
PHP Matsuriの感想はこれでおしまいです。
技術的なまとめは別に記事にしたいと思っています。
PHP Matsuriの一つの技術的中心として”PHP 5.3“がありました。
これについて、次回はまとめます。
来年は是非、皆さんも参加しましょう!
“@yandoさんは来年は開催するかどうかは分からない”と言ってますが、やってくれると信じて!:D
運営は相当しんどそうなので、皆、協力出来るところは協力して行きましょう。
PHP Matsuri、お疲れさまでした!
CakePHP 1.3.4 リリース
- 2010年9月15日 10:30 PM
- CakePHP

ちょっと記事を書くのが遅いですね(汗)
こういう記事は早く書かないと価値がない。
CakePHP 1.3.4がリリースされました。
CakePHP 1.3のマイナーバージョンアップで、いくつかのバグフィックスが含まれているようです。
簡単にThe Bakeryの記事を翻訳しておきます。
CakePHP 1.3.4 リリース
CakePHP開発チームはCakePHP 1.3.4をリリース出来たことをアナウンス出来て嬉しく思います。
このリリースにはコミュニティから上がったいくつものレポート、そしてチームの1ヶ月間の努力が含まれています。
CakePHP 1.3.3のリリースから77コミット[1]、そして54のチケットが消化されました。
あなたのアプリケーションに対して少し影響が出ます。
- プラグインに対して生成されたスキーマファイルが、AppSchemaの代わりのクラスネームを保持する$PluginSchemaを持つようになりました。
- Routeのパラメータに”-”を含んだ場合も正常に動くようになりました。
- SessionComponent::destroy()がデータを削除しないことがある問題を修正しました。
- Scaffoldがテーマに対して正常に動くようになりました。
- String::insert()が他のキーのサブパターンから始まるキーに対して正常に動くようになりました。
- DboMysqlがカラムとテーブルパラメータを正常に取得出来るようになりました。
- setlocale()とfloatの10進の区切りとして’,'を使うローケルに対して起こるSQLエラーの問題が修正されました。
- EmailComponentがネームエイリアスを含むアドレスをさらに正しく扱えるようになりました。
この最新版[2]をダウンロードし、変更歴を読んでアップデートを確認してください。
CakePHP 2.0のブランチは開発が進められており、いくつかのトピックブランチがマージされています。
どんな機能が2.0に含まれるか気になるなら、lighthouseのwiki[3]を見てください。
まだ完璧に仕上げる時間はありませんが、ここでだいたいのことはわかるでしょう。
1.3の一時wikiページはしばらく更新がないので、数週間以内に削除されるでしょう。
もし、あなたがこのページをリンクまたはブックマークしているなら、クックブックに切り替えてください。
コミットを通じて貢献してくれた全ての方に大いに感謝します。そして同じぐらい、チケットを投げてくれた方、ドキュメントを更新してくれた方、その他のところでフレームワークに貢献してくれた人に感謝します。
最新版のパッケージは[2]を。
変更歴は[1]を。
[1] http://cakephp.lighthouseapp.com/projects/42648/changelog-1-3-4
[2] http://github.com/cakephp/cakephp/downloads
[3] http://cakephp.lighthouseapp.com/projects/42648
さほど大きな変更はありませんね。
気になるのはSessionComponent::destroy()の修正ぐらいですか。
CakePHP 2.0の開発も順調に進んでいるよう。
コアデベロッパの方には本当に足を向けて寝られませんね。
CakePHPプラグインのまとめ – 総括編
- 2010年9月6日 3:30 PM
- CakePHP

CakePHPはやはり便利ですね。
記事を翻訳したことで、まだまだ知らない世界があったことを知りました。
そしてまた新しい知識欲が湧いてきました。
皆さんはどうですか?
何か使ってみたいプラグインはあったでしょうか。
これまで載せたCakePHPプラグインの記事を一覧にしておきます。
- 認証編
- AuthComponentの代替えになるプラグインやfacebookと連携するプラグインが紹介されています。それに加え、使いにくいACLを使いやすくするツールも。個人的には一番、興味のある記事でした。
- 検索とページネーション/ファイルアップロード編
- CakePHPの使いにくいページネーションを使いやすくするプラグイン、Yahoo! BOSSのプラグインが紹介されています。ファイルアップロードはTransloaditというサービスに対応させるプラグインから、メジャーなメディアプラグインまで。
- 最適化/デバッグ編
- CakePHP 2に取り込まれるであろうプラグイン、そしてContainableBehaviorをさらに高機能にしたようなプラグインが紹介されています。DebugKitの使い勝手を向上するものもありますよ!
- ヘルパー編
- ブログを作るなら使いたいGravatarやGoogle APIをCakePHPのために取りまとめたプラグインが紹介されています。Google APIにCakePHPを対応させるプラグインは必見です。使った人がいたら、ぜひコメントください。
最後にこのブログで取り上げる(かもしれない)プラグインをピックアップしておきます。
- Authsome
- AuthComponentお役御免のプラグイン。
- Facebookの機能を全面的にCakePHPに実装出来るプラグイン。
- Searchable
- 全文検索に対応したプラグイン。
- YahooBoss
- Yahoo! Boss検索をCakePHPに実装するためのプラグイン。
- TransloaditPlugin
- TransloaditというサービスにCakePHPを対応させるためのプラグイン。
- Linkable
- findの結果を関連テーブルに対する条件でフィルタリング出来るプラグイン。
- AssetCompress
- JSとCSSを圧縮してくれるプラグイン。
- GooglePlugin
- Google APIのサービスにCakePHPを対応させるプラグイン。
これらのプラグインを教えてくれたJose Diaz-Gonzalezさんとプラグインを作り公開してくれたBakerの方々に感謝です!
そして、1-byte.jpも皆さんに有益な情報を提供出来るように日々、精進していきます。
今後とも御贔屓に。
CakePHPプラグインのまとめ – ヘルパー編
- 2010年9月4日 4:00 AM
- CakePHP

CakePHPプラグインのまとめもこれで最後になります。
最後はヘルパーとその他のソースの紹介です。
便利なヘルパーたち
- Graham Weldon’s Gravatar: ヘルパーを使って簡単に君のアプリケーションにGravatarを埋め込んでくれるよ。ベーカリーの記事はここ。
- Chris Your’s CakeHelper: “今まで君のCakePHPのビューでHTMLブロックをキャプチャーするクリーンな方法を、そしてそれを後から$content_for_layoutのように使いたいと思ったことは?” このヘルパーはRailsのcontent_forをCakePHPに実装してくれるよ。とても良いね。
- Joe Beeson’s Analogue Helper: ときどき君はコアヘルパーのふりをするヘルパーが欲しくならない?なぜ?それがどれぐらい地獄か知ってる?けど君はこれを使えばそれが出来るんだ!
- Graham Weldon’s Auto-Javascript: 阿呆なGrahamはまだコードを分割して置くことを拒否してるよ :P 知る人は知っていると思うけど、彼はJavaScriptのテンプレートへの組み込みを効率化するために小さなヘルパーを書いたんだ。ベーカリーの記事はここ。
180行のコードで出来たGravatar対応のためのヘルパーです。
Gravatarって何っていう人は公式サイトをどうぞ。
ビューでCakeHelper::capture()とCakeHelper::content_for()を使うことで$content_for_layoutを独自に定義出来ます。
つまり、$content_for_sidebarや$content_for_leftなどを自分で用意出来るということ。
ビューがわかりやすくなるので結構使えるのでは?
これは便利かもしれません。
よくヘルパーに機能が足りず、コアヘルパーを継承してMyHtmlやMyPaginationなど作ると思うのですが、このMyHogeHogeをコアヘルパーの代替えとして使えるようになります。
つまり、$this->MyHtml->url()という形ではなく、$this->Html->url()といった形で呼び出せますね。
コントローラ名やアクション名と対応したJSを自動で探し、includeしてくれるヘルパーですね。
特定のコントローラにだけJSを当てたいときに便利ですね。
便利だとは思うのですが、これを便利便利と使いすぎるとダウンロードするJSの数が増え、ページ表示が遅くなると思うので注意が必要かと。
その他の素晴らしいソース
- Carl Sutton’s Google Plugin: 誰かこいつに賞をやってくれ。たくさんのGoogle APIをCakePHP向けに統合したんだ。なんでも来い、だ。
- ライブラリ
- google_api_adsense.php
- google_api_adwords.php
- google_api_analytics.php
- google_api_blogger.php
- google_api_calendar.php
- google_api_checkout.php
- google_api_contacts.php
- google_api_finance.php
- モデル
- google_contacts.php
- google_adwords.php
- google_analytics.php
- google_blogger.php
- google_calendar.php
- google_checkout.php
- google_contacts.php
- google_finance.php
- データソース
- google_contacts_source.php
- google_adwords_source.php
- google_analytics_source.php
- google_blogger_source.php
- google_calendar_source.php
- google_checkout_source.php
- google_contacts_source.php
- google_finance_source.php
- ヘルパー
- chart
- map
- Joe Beeson’s Sassy: これが気に入ったなら、君はSASSが大好きだな。JoeはCakePHPにSASSを実装出来る(君のためにリリースされた)この狂ったプラグインを定義し、ビルドしたんだ。
これは確かにこれは賞に値すると思います。
説明するよりも、このファイル一覧を見た方が早いですね。
すごいですよね。
これは一度使ってみたいプラグインです。
SASSって何?と思ったのですが、どうやらCSSを定義するためのメタ言語のようですね。
CSSより簡潔にメンテナンスしやすいコードを書けるようです。このヘルパーはSASSをリクエスト毎にCSSに変換してくれる機能を提供するようです。
ここで気になるのはcontent_forのヘルパーとコアヘルパーの代替えを簡単に行えるヘルパーでしょうか。
Googleのプラグインもすごいですね。
一度、どうなっているのかレビューしてみたいところ。
CakePHPプラグインのまとめはこれで最後です。
長々とお付き合いして頂き、ありがとうございました。
翻訳がかなり適当なので、間違いがあればご指摘ください(私の勉強にもなるので!)。
あ、総括編でこれらのページをまとめようと思うので、もう1記事だけお付き合いください(笑)
[2010/09/07 追記]
hiromi2424さんからAnalogueプラグインよりも便利ですよ。とHackプラグインを紹介頂きました。
- HackPlugin
ヘルパーやコンポーネント、モデルのエイリアスを設定出来るようです。
これを知っていれば、今作ってる機能にも使えたな…。次のリファクタリングのときにでも使いましょうか。
[連載記事一覧]
- 認証編
- AuthComponentの代替えになるプラグインやfacebookと連携するプラグインが紹介されています。それに加え、使いにくいACLを使いやすくするツールも。個人的には一番、興味のある記事でした。
- 検索とページネーション/ファイルアップロード編
- CakePHPの使いにくいページネーションを使いやすくするプラグイン、Yahoo! BOSSのプラグインが紹介されています。ファイルアップロードはTransloaditというサービスに対応させるプラグインから、メジャーなメディアプラグインまで。
- 最適化/デバッグ編
- CakePHP 2に取り込まれるであろうプラグイン、そしてContainableBehaviorをさらに高機能にしたようなプラグインが紹介されています。DebugKitの使い勝手を向上するものもありますよ!
CakePHPプラグインのまとめ – 最適化/デバッグ編
- 2010年9月3日 2:00 PM
- CakePHP

CakePHPプラグインのまとめも大詰めです。
今回は”Optimization“と”Debugging“を訳します。
最適化
- Frank de Graaf’s Lazy Model: これは君のモデルのチェインローディングを最適化し、君の作った巨大なアプリをスピードアップさせてくれるよ。君がCakePHP1.2または1.3を使っているのなら確実に見ておくべきものだ。CakePHP 2.0ではこれはコアに組み込まれる予定だけど、まだ入っちゃいない。Lazy Modelは次のお楽しみだね。
- Rafael Bandeiras’ Linkable: 思うに、こいつはContainableBehaviorの良い相棒だ。そうだ、いつかこの世界の1つのルールになるだろうね。けど彼はベースとなるSQLを書くのでもうしばらく忙しいみたいだ。Terrがそのアップデートされたバージョンを持っているようなんで、これはそこへのリンクだ。要チェックだね。
- Mark Story’s Asset Compress: 君のCSSとJSを圧縮してくれるプラグインだ。このプラグインの使い方とCakePHPで最も大切でこれ以上ないリードデベロッパーが誰だか、彼のgithubのプロフィールを見ればわかるはずだ!
- Matt Curry’s HTML Cache: 君のページをHTMLでキャッシュする。ものすごくスピードアップするよ。静的なページには最高だ。君がもしCroogo CMSを使うんならこいつはCroogoのフックも持ってるよ。
- Matt Curry’s URL Cache: この不機嫌な野郎はgithubのプロフィール中に良いもんを持っているようだね。君が使ってるどんなキャッシュシステムに対してもURLの生成過程をキャッシュしてくれる。ページリクエストに対して発生する重たいURLの生成処理をとてもスピードアップしてくれるよ。
- Matt Curry’s Custom Find Types: 君のアプリケーションに対してfindのカスタムタイプを作り出すのに確実で簡単な方法だな。キャッシュやフィルタリングのカスタマイズも簡単だ。
このプラグインをディレクトリに配置し、通常、AppModelを継承するところをLazyModelを継承することで動作速度の改善を図れるようです。
ただ、その分だけメモリを食うとも書いてあるので、そこは注意ですね。CakePHPはただでさえ、大食いですからね…。
hasManyやhasAndBelongsToManyのアソシエーションの場合に効果を発揮するプラグインですね。
これを使用すると、hasManyやHABTMのテーブルに対して条件を指定し、それに関連のあるレコードを取得出来るようです。
READMEにある例ではTagを条件に指定して、関連あるEntryを取得しています。
コメントの通りCSSとJSを自動で圧縮してくれるプラグインですね。
プラグインをインストールし、Routesを設定すると、そのURLで圧縮したJSやCSSを取得出来るようです。シェルで圧縮したJS/CSSを吐き出したり、それを削除することも可能だそうです。便利ですね!
ヘルパーを読み込むだけでHTMLキャッシュをwebroot以下に生成してくれるようです。
こうすると、.htaccessの書き換えが必要ですが、それも載っています。cronでのキャッシュ削除方法も載せてあるのが良いですね。
AppHelperの継承元を変えるだけで、Routesの処理をキャッシュしてくれるようです。これもすごく簡単ですね。
これもすごく便利なプラグインです。
プラグインをインストールして、モデルの継承元を変えてやるだけで使えます。
あとは”__findHogeHoge”というメソッドを定義するとtypeに”hoge_hoge”が使えるようになり、そのメソッドでfindの処理がされるようになります。すごいよ、Curryさん。
デバッグ
- Mark Story’s DebugKit: いや、マジでこの男はモンスターだ。彼はJS忍者でさらにCakePHPのバッシュ魔人であるだけじゃなく、君のCakePHPのアプリケーションのためにデバッグのための素晴らしいツールを書き続けている。これは今すぐインストールすべきだね。使い始めたら虜になること間違いなし。
- Joe Beeson’s Referee: “エラーと例外をキャッチし、それをロギング出来るCakePHP 1.3+ のプラグイン” 思うにこいつはすこいイカしてる。君もそう思うだろうね。
- Matt Curry’s Interactive: DebugKitをページ更新なしにインタラクティブに表示してくれるパネルだ。特定のクエリがどんな風に動いているか見るのに良いね。
言わずとしれたDebugKitですね。これは皆さん知っていると思うので省略。
詳しく知りたい方はcakephperさんが書かれた以下のページを参照してください。
コンポーネントで設定出来るので、コントローラ毎にエラーをロギング出来そうです。
CakePHP 1.3からはログエンジンを変えることが出来るようになったので、ほとんど不要かもしれませんが、きめ細かなロギングの設定をしたいときに。
これもすごく便利ですね。
DebugKitのコントロールパネルからクエリを発行したり、PHPのコードをインタラクティブに実行出来るようになるみたいです。
ここまで来るとDebugKitがちょっとしたIDEみたいですね。
最適化のプラグインは気になるのがたくさんありますね。
モデル周りの最適化を図ってくれる”Lazy Model”やCSSとJSを圧縮してくれる”Aseset Compress”、そしてHTMLキャッシュを作ってくれる”HTML Cache”…。
CSSとJSの圧縮がタスクにあがっているので、今度は”Asset Compress“の使い方をまとめましょうか。
次回が最後です。”Useful Helpers“と”Random Awesome-sauce“を訳しますね。
[連載記事一覧]
- 認証編
- AuthComponentの代替えになるプラグインやfacebookと連携するプラグインが紹介されています。それに加え、使いにくいACLを使いやすくするツールも。個人的には一番、興味のある記事でした。
- 検索とページネーション/ファイルアップロード編
- CakePHPの使いにくいページネーションを使いやすくするプラグイン、Yahoo! BOSSのプラグインが紹介されています。ファイルアップロードはTransloaditというサービスに対応させるプラグインから、メジャーなメディアプラグインまで。
- ヘルパー編
- ブログを作るなら使いたいGravatarやGoogle APIをCakePHPのために取りまとめたプラグインが紹介されています。Google APIにCakePHPを対応させるプラグインは必見です。使った人がいたら、ぜひコメントください。
- エキスパートPythonプログラミング読書会 第二期 07の募集を開始しました! http://t.co/DuVQ32jM #expertpython 2 days ago
- 受付を撤収したので、遅れてくる方は @sanojimaru か、 @tfmagician まで声をかけてください。 #expertpython 3 days ago
- http://t.co/e4N59JH3 4章ですね、募集ページを修正しました。 #expertpython 3 days ago
- More updates...
- 無印良品の高度なFacebook連携がさすがだと思った件 « Looops 直人の備忘録
- Node.jsがどうして注目されているのか、もしくはどうして他のサーバサイドJavaScriptはスルーされているのか - id:anatooのブログ
- 0から始めるiPhoneからのWordPress更新術。第9回 終わりに。一連の流れ ...
- shell.vim 0.9.6 -- Improved integration between Vim and its environment (fullscreen, open URL, etc)
- Cakephp auth refresh websites and posts on cakephp auth refresh
- さよなら、iPhone。 日本でも訴訟されて発売されるGalaxyS2の凄さがわかる動画 alpha device
- フィードからの情報をデスクトップ通知してくれるChrome拡張機能「RSS Alert」
- PHPとアジャイル開発の勉強会を開催しました | 48JIGEN
- レノボ、Android 採用の ThinkPad タブレットを今夏発売へ。Windowsタブレットは年内
- 致命的すぎるバグがgithubで話題 « A-Listers



