Home > PHP > CakePHP

CakePHP Archive

CakePHPでCSRF対策

この記事の所要時間: 33

CakePHPでCSRF対策を行う方法です。

フレームワークに含まれているSecurityコンポーネントを使います。

Security#requestAuth()にアクションを記述しておくと、アクション実行前に正規リクエストかどうかをチェックします。チェックの方法はCSRF対策で一般的なワンタイムトークン方式です。

まずController#beforeFilter()にてチェックを行うアクションを指定します。

[app/controller/test_controller.php]

< ?php
class TestController extends AppController {
  var $name = 'Test';
  var $components = array('Security');

  function beforeFilter() {
    $this->Security->requireAuth('add', 'edit');
  }

  function add() {
   //
  }

  function edit() {
   //
  }
}
?>

あとはビューファイルにトークンを埋め込みます。ポイントはformタグをHTMLで書かずにHtmlHelper#formTag()で記述するという事です。そうしておけばフレームワークがトークンをhiddenで埋め込んでくれます。(もとからformTag()で記述されている場合はそのままで良いです。)

[app/views/test/add.thtml]

< ?php echo $html->formTag() ?>

実行時のHTMLソースは以下のような感じになります。(トークンの値は表示毎に変化します。)

<form action="/test/add/" method="post">
<input type="hidden" name="data&#91;_Token&#93;&#91;key&#93;" value="cfa714174ecc102178c6c540b04fa94dc0d5bd5d" id="_TokenKey" /> 
</form>

トークンが一致しないリクエストが発生した場合は[HTTP/1.0 404 Not Found]が出力されます。(この動作は変更できます。)

上記は一つのコントローラでチェックを行っていますが、全てのフォームで同様のチェックを行うならSecurity#requestAuth()をAppController#beforeFileter()に書いておけばokです。

[app/app_controller.php]

< ?php
class AppController extends Controller {
  var $components = array('Security');

  function beforeFilter() {
    $this->Security->requireAuth('add', 'edit');
  }
}
?>

こうしておけば全てのControllerでadd/editアクションを実行する前にチェックがかかります。

 

ワンタイムトークン方式ではコントローラ/モデル側とビュー側の双方に記述が必要なのですが、フレームワーク側で考慮されているので手軽に使用できます。

ただ残念ながらbakeで生成したビューファイルはformタグがHTMLで書かれており、いちいち上記のように書き換える必要があります。HtmlHelperはデフォルトで読み込まれるのでformTag()で書いておいてくれれば楽なのですが。

# 気が向いたらTicket投げておきます。

CakePHPを使う理由

この記事の所要時間: 11

International PHP Magazineで「CakePHPを使う理由」というアンケートをやっています。

# Lightweight
# CakePHP does not believe in a components/widget approach
# Compatible with PHP4 and PHP 5
# Enhanced AJAX support
# Suitable for any kind of project
# The Bake command

International PHP Magazine::News::IPM Poll Question: Reasons to use CakePHP are ?

2つめは良く分からないのですが、後はまあ有りそうな選択肢ですね。

ちなみに私がCakePHPに興味を持った理由は「PHP4/5対応」と、選択肢には無いですが「ActiveRecordライクなModel」「設定ファイル不要」でした。(あとはやっぱりこれです。;-))

アンケートに回答すると現在の集計結果を見ることができます。bakerな方は回答してみては?

CakePHP1.1.11.4064リリース

この記事の所要時間: 051

CakePHP1.1.11.4064がリリースされています。

数々のバグフィックスの他、以下のような内容が盛り込まれています。

  • Configureクラスにメソッド追加(version(),read(),write())
  • Modelの遅延読込(the lazy loading of models)によるパフォーマンス向上
  • View#_viewVarsがdeprecatedに
    => これからはView#viewVarsになるようです。

CakePHP cakeError()は値を返さないCakePHP1.1.10.3825-bake.php修正パッチの内容も修正されていました。

ソースをざっと見たところではコードのクリーニングが行われていたり、phpdocが追記されていたりとソース自体の熟成も進んでいる印象を受けました。機能を実装するより地味ですが、クオリティを上げるのに重要な作業だと思います。開発者の方々には感謝感謝ですね。

CakePHP1.1.10.3825-bake.php修正パッチ

この記事の所要時間: 246

cakephp.jpにあるように、1.1.10.3825のbake.phpをWindows上で使用すると上手く動作しない場合があります。

この現象はcake\とは異なるディレクトリにプロジェクトを生成しようとした場合に発生するようです。

New App Directoryが作成するプロジェクトのディレクトリなのですが、妙なパスが表示されています。[D:\tmp\d:\tmp\app]

> php -q D:\tmp\cake\scripts\bake.php -project d:\tmp\app
...
New App Directory: D:\tmp\d:\tmp\app
---------------------------------------------------------------

原因はディレクトリ区切り文字を[/]に決めうちしているためです。この問題の修正パッチを作りましたのでよろしければどうぞ。

--- cake_1.1.10.3825.org/cake/scripts/bake.php       2006-11-10 14:37:00.531250000 +0900
+++cake_1.1.10.3825/cake/scripts/bake.php       2006-11-13 18:08:16.187500000 +0900
@@ -82,12 +82,12 @@
        }
 
        $shortPath = str_replace($root, '', $app);
-       $shortPath = str_replace('../', '', $shortPath);
-       $shortPath = str_replace('//', '/', $shortPath);
+       $shortPath = str_replace('..' . DS, '', $shortPath);
+       $shortPath = str_replace('//', DS, $shortPath);
 
-       $pathArray = explode('/', $shortPath);
+       $pathArray = explode(DS, $shortPath);
        $appDir = array_pop($pathArray);
-       $rootDir = implode('/', $pathArray);
+       $rootDir = implode(DS, $pathArray);
        $rootDir = str_replace('//', '', $rootDir);
 
        if(!$rootDir) {

 

2006/11/21追記:
修正パッチを取り込んで貰えました。https://trac.cakephp.org/changeset/3872
他にも修正されていますし、いずれ1.1.11が出そうですね。

CakePHP cakeError()は値を返さない

この記事の所要時間: 150

cakeError()は値を返さない、という話です。

Well, this solution would work fine as long as it is only used internally (even though it is not very elegant). But the framework allows you to write a custom error handler, and so if you want to handle a “missing helper file” error yourself, you get PHP errors when you don’t use an exit.

cakebaker » Don’t rely on side effects in your code

はじめてこの箇所のコードを追っかけた時にちょっと頭が「?」になりました。エントリでも言及されていますが、自分でエラーハンドラを作る際はこれを意識しておかないとまずい事になりますね。

どうせErrorHandlerでexitするなら、単純にcakeError()は値を返さず、メソッド内でexitすれば良いような気もします。コードで書くとこんな感じですね。

エラー呼び出し元

< ?php
...
//return $this->cakeError(...);
$this->cakeError(...); // returnしない
...
?>

Object#cakeError()

function cakeError($method, $messages) {
...
  if (class_exists('AppError')) {
    $error = new AppError($method, $messages);
  } else {
    $error = new ErrorHandler($method, $messages);
  }

  exit;
}

CakePHP1.1.10.3825リリース

この記事の所要時間: 059

CakePHP1.1.10.3825がリリースされました。(1.1.9がリリースされたのですがバグがあったようで、すぐに1.1.10がリリースされています。)

バグフィックスが主なですが、ACLに大きな変更がなされたようです。(ACL使ってます?)

1.1.8とのdiffを見てみると以前あった「Controllerのメソッドが外部から呼べる」(CakePHP Controller小話)の対策がなされていました。Controllerクラスにあるメソッドは直接外部からは呼べなくなっていますね。(Missing Methodが表示されます。)あとはAppControllerや各コントローラでアクション以外のメソッドを書かないようにすれば、ひとまず外から任意のメソッドを呼ばれる心配は無くなりました。

あとbakeにも色々と改良が加えられています。近頃はフレームワーク自体の出来もそうですが開発をサポートするツールの存在が大きいのでこれは嬉しいですね。

 

移行の方法ですが、ACLを使っていなければ1.1.10のcake/を既存のcake/にコピーすればokです。

CakePHP bake2タスクを作る

この記事の所要時間: 152

CakePHP bake2でテーブルひな形を作るでご紹介したように、1.2系に含まれているbake2では任意のタスクを呼びだせる設計になっています。なかなか面白い機能なので試しにHelloタスクを作ってみました。

bake2タスクはBakeTaskクラスを継承します。オーバーライドするメソッドはexecute()とhelp()メソッドです。名前のとおりexecute()メソッドではタスク処理、help()メソッドではタスクのヘルプを表示します。

[cake/script/tasks/hello_task.php]

< ?php
class HelloTask extends BakeTask {
    function execute($params) {
        foreach ($params as $param) {
            printf("Hello %s.\n", $param);
        }
    }

    function help() {
        echo "The Hello task \n";
        echo "Usage: bake2 hello name\n";
    }
}
?>

Helloタスクを呼びます。

FooとBarがHelloタスクへのパラメータになります。ソースを見ても分かるようにパラメータはexecute()メソッドに配列で渡されます。

$ php -f bake2.php hello Foo Bar
Hello Foo.
Hello Bar.

helpをパラメータにするとHelloタスクのhelp()メソッドが呼ばれ、ヘルプが表示されます。

$ php -f bake2.php hello help
The Hello task 
Usage: bake2 hello name 

 

単純ですがタスクを実行する仕組みが用意されたのは嬉しいです。コードジェネレータやDBのセットアップなど開発に役立つタスクを増やしていきたいですね。

CakePHP bake2でテーブルひな形を作る

この記事の所要時間: 114

テーブル生成・削除SQLを作成するタスクが紹介されています。

To make it a bit easier to write the sql scripts for creating and dropping tables, I wrote a simple bake task. There isn’t much to say about it, so I show you just an example.

cakebaker » A simple task to generate sql scripts (2006-10-26)

1.2系に付属されているbake2用のタスクです。

bake2.phpにテーブル名を指定すると、id(プライマリキー)・created(レコード生成日時)・modified(レコード更新日時)を持つテーブルの生成・削除SQLが[/app/config/sql]以下に生成されます。どのカラムもフレームワークで参照・更新されるカラムですのでひな形に含まれていると便利ですね。

ただ生成されるSQLがMySQL用なので他DBの場合はデータ型などを変更する必要があります。(生成対象のDBを[/app/config/database.php]を見て切り替えるという手もありです。)

bake2.phpを見ると任意のタスクを追加していけるようなので、こちらも色々と使えそうです。

CakePHPのコーディング規約

この記事の所要時間: 113

CakePHPにもコーディング規約があります。

Cake Developers will use the following coding standards.
It is recommended that others developing CakeIngredients follow the same standards.

Developement/CodingStandards – CakePHP : Rapid Development Framework – Trac (2006-10-12)

PHP.PL DevTeamのコーディング規約が元になっているようです。内容をざっと見た感じではZend Frameworkのコーディング規約に似ていますね。

まあフレームワーク自体が規約に従っていないのはアレですが。

We agreed on using four space characters for indentation.

Developement/CodingStandards – CakePHP : Rapid Development Framework – Trac (2006-10-12)

規約ではインデントは4スペースになってますが、[cake/libs/model/model.php]等々を見るとインデントはtabになってたり。。

CakePHP array-based Active Record

この記事の所要時間: 138

NYPHPにて行われたCakePHPプレゼンのレビュー記事です。

Last night at the monthly NYPHP meeting, Nate Abele presented an introduction to CakePHP, a web application framework.

Chris Shiflett: CakePHP Visits New York (2006-09-28)

CakePHPの特徴が簡潔に書かれていて興味深い内容なのですが、以下の一文にピクッときました。

Cake has an array-based Active Record implementation.

私が初めてCakePHPを触った時に感じた印象(違和感)がまさにこれでした。うーん、ぴったりの表現です。

Cakeを初めて触る方はこれを頭にいれておけばすんなり入れるかと思います。

 

エントリのコメントを見るとプレゼンを行ったnateからこの件についてコメントがありました。

(1) The reason we decided to go with an array-based approach to ActiveRecord had to do with PHP4, but it also has a lot to do with the fact that even in PHP5, the array support, (i.e. all the great things you can do with arrays really simply) still outweigh PHP’s ability to manipulate objects.

配列ならシンプルだし、オブジェクトより速いでしょ。という事ですね。まあこれはこれでアリですね。

ホーム > PHP > CakePHP

検索
フィード
メタ情報

Return to page top