Home > PHP > CakePHP

CakePHP Archive

CakePHP FormHelper#datetime()で年月日表示を変える

この記事の所要時間: 116

CakePHP1.2で追加されたFormHelperには日時をプルダウンメニューで選択する機能があります。

<?php echo $form->datetime('hoge', 'YMD', 'NONE'); ?>

これで年月日を選択できるのですが、デフォルトだと↓のように月が英語表現で表示されます。

そこで月を数字表現に変更する方法です。

datetimeメソッドはFormHelper#$optionsの値をプルダウンで表示するリストに使用します。(値が無ければデフォルト値を使用)よってこれを書き換えれば任意の値をリストに表示できます。

<?php
// 月を数字へ
$form->options['month'] = array();
for ($i = 1 ; $i <= 12 ; $i++) {
  $form->options['month'][$i] = sprintf("%02d", $i);  
}
?>
<?php echo $form->datetime('hoge', 'YMD', 'NONE'); ?>

これで以下のようになります。

FormHelper#$optionsでは月の他に様々なリストを指定できるので、年を和暦表現する、任意の日のみ選択対象にするなど変更できます。

■指定できるリスト

$options[‘year’]
$options[‘month’]
$options[‘day’]
$options[‘hour’] 時(12時間表現)
$options[‘hour24’] 時(24時間表現)
$options[‘minute’]
$options[‘second’]
$options[‘meridian’] 午前・午後

日時表現としては、FormHelper#time()、FormHelper#input()もありますが、これらも内部的には同じロジックを共有しているので、同じように指定ができます。

CakePHP Model#save()のSELECT文を抑制する

この記事の所要時間: 154

Model#save()でUPDATE文が発行される際は、まず該当ID(primary key)がDBに存在するかを確認するSELECT文が発行されて、存在すればUPDATE文が発行されます。

1レコードだけを更新するなら特に気にする必要は無いのですが、大量のレコードを逐次UPDATEする際はこのSELECT文を抑制したくなります。

そこでこのSELECT文を抑制する方法を調べてみました。

1. Model#$__exitstsにtrueを入れる

ちょっと強引な方法ですが、save()を実行する直前でModel#$__exitstsにtrueを入れると、SELECT文が発行されません。

Model#$__exitstsはsave()実行後、nullにリセットされるので元の値を戻す必要はありません。

    // FooがModel
    $this->Foo->__exists = true;
    $this->Foo->save($data);
    $this->Foo->save($data); // こちらはSELECT文が発行される

2. Model#exists()を継承する

SELECT文はModel#exists()で発行されるのでこれを継承して実行を抑制する方法です。

下のソースのように抑制するか否かでフラグを持たせると使い勝手が良いでしょう。

[app/app_model.php]

<?php
class AppModel extends Model {
  public $checkExists = true;

  public function exists($reset = false) {
    if ($this->checkExists) {
      return parent::exists($reset);
    }

    return true;
  }
}
?>

使う側

    $f = $this->Foo->checkExists; // フラグ値を保存
    
    // FooがModel
    $this->Foo->checkExists = false; // 抑制
    $this->Foo->save($data);
    
    $this->Foo->checkExists = $f; // フラグ値戻す

手軽で使い勝手も良いのは1.ですが、いちおうModel#$__existsは(コメント上では)privateのようなので、2.の方がお行儀の良いコードですね。:-D

第2回CakePHP勉強会も盛り上がりました!

この記事の所要時間: 32

第2回CakePHP勉強会が無事に終了しました。

申込受付時もそうでしたが、勉強会・懇親会も熱気に包まれて盛り上がりました。

Cakeだけに焼き立てな感じでした(・・・)

addons.mozilla.org@CakePHP

  • 37.5万PV/Web1台
  • やはり実際に稼働しているのでかなり参考になる
  • ソースの他にhttp://wiki.mozilla.org/Update:Remoraも参考になる
  • 相変わらずさすがのプレゼンw
  • ソースをちらちらと見たが、すっきりまとまっており読みやすい
  • 今は1.2 に盛り込まれている内容が独自に実装されていたり
    => memcached対応、多言語化とか
  • 本家とのやりとりをしたyando++

ニフティトピックイット@CakePHP

  • 数百万PV/m => TVで紹介される => 数千万PV/mへ
  • プレゼンの場で仕様確認w
  • 使った理由
    ・PHP4で高速開発
    ・ActiveRecord
    ・Railsっぽい

  • 開発は早くできた
  • CAKE_SECURITY=highにつまづく。mediumで解決(個人的にもhighは使いづらい)
  • 次は負荷対策w
  • やっぱり事例は強力だ

CakePHP1.2のメールコンポーネント

  • メール屋さんらしく専門家からみたEmailComponent
  • SMTP実装で陥りやすい点を知っているからこその着眼点はさすが!
  • 問題点をticket投げているのもさすが!
  • ちょっぴりEmailComponentは使おうと思っていたけどキツイかなw
  • 本の宣伝ありがとうございましたーw

初心者がはまりやすいCakePHPのうっかりポイントまとめ

  • 百式のたぐちさん!
  • ユーモアを交えてテンポの良いプレゼンはさすが。
  • 相手に「使ってみたい」と思わせるのは結構大事。

CakePHP+Oracle

  • 「Do You CakePHP はてな」の中の人w
  • OracleとCakePHPの組み合わせはレアなので実際の検証された内容は貴重
  • 1.2betaでは発行されるSQLがおかしいっぽい。(PostgreSQL向けと同じ問題かも)
  • 話し慣れているご様子でした

あのオープンソースソフトウェアを CakePHP に移植する

  • RailsでできたFastladderをCakePHPに移植!
  • ディレクトリ構成やファイル構成が似ているから移植はやりやすい
  • このネタを思いついたp4life++
  • 是非ソース公開をw

懇親会

会場のビル内に隣接(!)するバーで懇親会。人口密度が高かったのでクラブっぽい熱気がありました。バーカウンタの中から全体を見渡すと、皆さん良い笑顔をされていたのが印象に残っています。

記憶に残っていて、書いても良さげなネタwをつらつらと。

  • メール配信は奥が深い
  • CakePHPのリポジトリはtrunkとbranchesが逆じゃない?
  • 1.2prebetaから1.2betaで結構変わっている
  • 今回も自分以外に大阪から参加の方が!
    これは大阪でも勉強会やらないと。
  • @niftyの方々となぜか関西ローカルネタで盛り上がるw
  • ようやくkunitさんとお会いできた!
  • ちょっとへばってたのでおとなしくしてました。でもやっぱりもうちょっと動けば良かった。。。

参加された皆さん、発表された皆さん、会場提供の他諸々の準備をやって下さったトライコーンのすずきさん、そしてあきやんさん、そしてそして安藤さん本当にありがとうございました。

PHP Fatal error: Cannot use string offset as an array

この記事の所要時間: 120

文字列を三次元以上の配列とみなしてisset()すると「Fatal error: Cannot use string offset as an array」が発生しました。

PHP5.2.5/5.1.6で試しました。

<?php
$a = "";
var_dump(isset($a&#91;'0'&#93;&#91;'0'&#93;)); // 2次元は可
var_dump(isset($a&#91;'0'&#93;&#91;'0'&#93;&#91;'0'&#93;)); // Fatal error

// empty も同じ
var_dump(empty($a&#91;'0'&#93;&#91;'0'&#93;)); // 2次元は可
var_dump(empty($a&#91;'0'&#93;&#91;'0'&#93;&#91;'0'&#93;)); // Fatal error
?>

$aは空文字でも”hoge”でも同じようにNGでした。ちなみに$aが文字列の時に発生するもので、数値やnullでは問題ありません。

文字列変数に[]を使うとインデックスで指定したオフセットの文字へアクセスできるので、これが影響しているのかもしれません。(ただPHP4.3.9ではこのエラーは発生しませんでした。)

これ自体は単にis_array()でチェックすれば良い話なのでそれほど大した事ではないです。

<?php
$a = "";
if (is_array($a)) {
  var_dump(isset($a&#91;'0'&#93;&#91;'0'&#93;&#91;'0'&#93;));
}
?>

実はこのエラーはCakePHP1.2-prebetaで稼働しているシステムをCakePHP1.2-betaのフレームワークに移行した際に気づきました(Helper#value()で発生)。Helperを上記のように書き換えれば問題無いのですが、フレームワークにあまり手は入れたくないので解決策を調査中です;-)

[2008/02/12追記]

CakePHP1.2-betaの問題は自作Component#beforeRender()での変換処理に問題があったことが原因でした。NULLな値を空文字に変換してしまっていました。これまでは上手く動いていたのが、1.2-betaのヘルパーで顕在化したというところですね。いやはや;-)。

[告知] 第2回CakePHP勉強会の申込を開始しました。

この記事の所要時間: 052

[告知] 第2回CakePHP勉強会を行います。でご案内した第2回CakePHP勉強会の申込を開始しました。

日時:2008年02月20日(水)20:30 – 22:15

会場:トライコーン株式会社

地図

参加費用 無料

懇親会参加費 実費(2000円前後予定)

events.php.gr.jp

会場はPHP勉強会でお馴染みのトライコーンさんです。(ありがとうございます!)

CakePHPを使った大規模サイトの事例としてyandoさんが調査された「addons.mozilla.org」、そして何と「ニフティトピックイット」の中の方々に発表を行っていただけます(ありがとうございます!)。

またLT枠(一人5分程度の発表)もありますので、Cakeに関するネタをお持ちの方は発表をお願いします。

CakePHPを使った大規模サイトの事例を直に聞ける機会ですので是非ご参加下さい。

申込はevents.php.gr.jpからどうぞ。

[告知] 第2回CakePHP勉強会を行います。

この記事の所要時間: 038

[2008/02/08] 申込を開始しました。

告知です。第2回CakePHP勉強会を都内で行います。

第2回CakePHP勉強会

  • 日時: 2008/2/20(水) 夜(19:00 or 20:00~?)
  • 場所: 都内(会場は調整中です)

日程はほぼ決まりなのですが、会場の最終調整を行っているところです。決まりましたらまたこのblogにてご連絡します。

今回は事例発表などもあり、かなり楽しみな内容になりそうです。またLT枠も設けるのでネタをお持ちの方是非ご参加下さい。

前回のレビュー等々はhttp://events.php.gr.jp/event.php/event_show/30から辿れます。

Twitterのキーワードをグラフで見るTwitterTrendをリリースしました。

この記事の所要時間: 136

Twitterで、あるキーワードがどれくらい投稿されているかをグラフ化するTwitterTrendをリリースしました。

TwitterTrend

なにをするの?

キーワードを入力して「集計」ボタンをクリックすると直近1ヶ月でキーワードが含まれた投稿数をグラフで表示します。

流行のキーワードがどの程度反応されているかを見ることができます。

例えば最近物議を醸しているあの話題で集計すると↓のようになります。

TwitterTrend : PHP – .php

キーワード

キーワードはTwitter検索と同じ検索式が使えます。

また3つまでなら複数のキーワードを指定することもできます。この場合それぞれのキーワードについてグラフが表示されるので、投稿数を比較することができます。それぞれのキーワードは[,](カンマ)で区切ります。

TwitterTrend : ラーメン,うどん,そば

集計対象

集計されるのは前日から直近1ヶ月間の日本語ユーザの投稿です。

Twitterでの伝播

今回はblogでリリースを出す前にTwitterでURLを投稿してみました。ものの数分でサーバにアクセスが来だして、はてブにブックマークが付きました。1h経過した頃には10users程度になってました。その後予定があったので外出したのですが、帰ってきた頃には30usersが付いていました。

Twitterで呟いたサービスがどんどん広がっていく様は、改めて驚きました。情報の伝達スピードがハンバじゃないですね。

TwitterやSBMで速攻で反応が返ってくるのはわくわくしますね。この感覚はやみつきになりそうですw。

# ちなみにこのサービスは今話題のPHPで作ってます。

# id:moto0915さん、はてぶで不具合報告ありがとうございました!「OR」の件は修正しましたー。

CakePHP 管理者サイトでBasic認証を簡単に行うコンポーネント

この記事の所要時間: 226

CakePHPの管理者向けサイトにBasic認証を簡単に追加するコンポーネントです。

1.2系で動作しますが、ちょこちょこっといじれば1.1でも動くかと。

1. Routing.adminを有効にする

そもそもこれをやらないと意味がありません。[app/config/core.php]でRouting.adminを有効にします。

これにより[http://example.com/admin/~]のURLで管理者用アクションにアクセスできます。

   Configure::write('Routing.admin', 'admin');

2. 認証コンポーネントを設置

認証コンポーネントを[app/controllers/components/admin_auth.php]に設置します。

[2008/05/29] 継承元をComponentからObjectへ変更しました。(janさんありがとうございます!)

<?php
class AdminAuthComponent extends Object {
  /**
   * before filter
   */
  public function startup(&$controller) {
    if (!preg_match("/^" . Configure::read('Routing.admin')  . "_/i", $controller->action)) {
      return;
    }

    $user = env('PHP_AUTH_USER');
    $pass = env('PHP_AUTH_PW');

    if (empty($user) || empty($pass)) {
      $this->unauthorized($controller);
    } else {
      if (!$this->auth($user, $pass)) {
        $this->forbidden($controller);
      }
    }
  }

  /**
   * unauthorized
   *
   * @param  object Controller $controller
   */
  protected function unauthorized($controller) {
    header("WWW-Authenticate: Basic realm=\"Please Enter Your Password\"");
    $controller->redirect(null, 401, false);
    echo "Authorization Required";
    exit;
  }

  /**
   * forbidden
   *
   * @param  object Controller $controller
   */
  protected function forbidden($controller) {
    $controller->redirect(null, 403, false);
    echo "Authorization Required";
    exit;
  }

  /**
   * auth
   *
   * @param  string $user
   * @param  string $pass
   * @return boolean
   */
  protected function auth($user, $pass) {
    $hash = sha1($user . $pass . Configure::read('Security.salt'));
//debug: var_dump($hash);
    return $hash === ADMIN_AUTH_HASH;
  }
}
?>

3. AppControllerで読み込む

AppControllerの$componentsでAdminAuthComponentを読み込むだけでokです。これで[/admin/]なURLにアクセスされるとBasic認証を行い、認証が通った場合のみアクションを実行します。

<?php
class AppController extends Controller {
  public $components = array('AdminAuth');
}
?>

認証情報

上記ソースでは簡易的にユーザ名+パスワード+Security.saltでsha1ハッシュを生成して、それを定数ADMIN_AUTH_HASHと比較して認証を行っています。

ADMIN_AUTH_HASHは[app/config/core.php]等で定義しておけばokです。

ちなみにハッシュ値を簡単に作成するには、AdminAuthComponent#auth()でコメントアウトしているvar_dump()を有効にします。これでブラウザからアクセスしてユーザID・パスワードを認証ダイアログで入力すればハッシュ値が出力されます。

ハッシュ生成後はvar_dump()の行は削除する or コメントアウトするようにしましょう。

拡張とか

ここでは単純な実装になっていますが、AdminAuthComponentを変更すれば以下のような拡張が考えられます。

  • ハッシュ値では無くDBの値で認証
  • HTTPからのアクセスはHTTPSへリダイレクト
  • Basic認証を他の認証に変更

ちなみにRouting.adminのURLは単純にapache側で認証をかけるとすり抜けられる可能性があります。(@see:CakePHP URLマッピング修正パッチ)

このコンポーネントを使えばいかなるURLでアクセスされても、管理者用アクションを(初回)実行する際は認証を通過させることができます。

CakePHP勉強会を開催しました

この記事の所要時間: 244

CakePHP勉強会を開催します。従来のPHP勉強会では一般化した内容しか取り扱えない面もある為、特化したイベントの開催を企画しました。

CakePHPを実際に使っている人、CakePHPに興味がある人で語らいましょう!

events.php.gr.jp

12/7に東京で開催したCakePHP勉強会は無事に終了しました。

参加された方々、発表を行ったyandoさん、akiyanさん本当にありがとうございました。

私もわたわたしながらも何とか発表を行うことができました。役立つかどうかは分かりませんwが、発表で使ったスライドをアップしておきます。

CakePHPを業務で導入する shin1x1

  • 開始直前に内容から判断して順番を変えていただきました。
  • ここ最近バタバタで手が付けられず、結局新幹線でスライドを作りました。
  • な感じなのでいまいちパッとしない内容だったかもしれません。。。
  • ただダメなりに自身は学べた事が多々あったのでとても楽しかったです。
  • 皆さんから色々意見を聞けたのは収穫でした!
    もっと議論を誘発するような発表もアリかな。

参加された皆さんとのやりとりで

  • bakeは予想以上に誰も使っていなかった:-p
  • CakePHP1.2はまだ様子見の人が多かった
  • CakePHPを業務で使っている人が意外に多くてびっくり
  • CakePHPガイドブック保持者がかなり多くてびっくり(本当にありがとうございます_O_))

CakePHPをさらにDRYにする、ドライケーキレシピ akiyanさん

  • 高橋メソッド+akiyanトークでテンポ良いプレゼンでした。
  • 立って説明しつつ片手でマウスを持ってスライドを進める。なるほど。
  • DRY Cake++
  • SQLを連想配列を駆使して作り上げる視点。
  • こういう実践的なTipsはどんどん共有したいですね。

CakePHP1.1 to 1.2 yandoさん

  • いつもながら、さすがのプレゼンでした。
  • Garrett Woodworthの写真w
  • 1.1システムを1.2へ移行するデモ++
  • やはり最後はもちろんいつものでしたw

懇親会

  • ほとんどの方が懇親会に参加!
  • CakePHPやらその周辺の話を色々と。
  • おそらくこれだけCakePHPの話を他の人としたのは人生初w
  • もっともっと話したかったし、聞きたかった。
  • 軽くリクルーティングw
  • かなり皆さんネタを持っているもよう。第2回もある?
  • 名刺持って行くのを忘れるという大失態><名刺を頂いた皆さんスミマセン。。。

てな感じで

楽しくてあっという間に終わった勉強会でした。

今回初めて勉強会を開催する側、発表する側に回ったのですが、やはり楽しいですね。特に今回はyandoさん・akiyanさんと3人で進めていったのでチームで物事を進める楽しさがありました。

個人的にもお会いしたかった方々と少しですがお話ができ、嬉しかったです。

またこういった機会があれば是非参加したいと思います。

皆さんお疲れ様でした&ありがとうございました。

# アンケートご協力ありがとうございました!見るのが楽しみなような怖いような;-)

CakePHP勉強会を開催します

この記事の所要時間: 023

申込については近日中に行う予定ですので、またお知らせいたします。しばしお待ちを。

CakePHP勉強会を開催します[告知] | Shin x blog

先日告知したCakePHP勉強会の申込を開始しました。

events.php.gr.jpから申込できますのでCakeな皆さんは是非ご参加下さい。

しかしうえちょこさんshimookaさんエントリ早すぎです;-)

ホーム > PHP > CakePHP

検索
フィード
メタ情報

Return to page top