CakePHP1.2でキャッシュが消えない

9月 9th, 2009 admin

CakePHP の自動キャッシュクリアが効くのは、コントローラ名=モデル名のときだけ : akiyan.com
↑という時用 behaviorsで指定すれば多少ましかもしれないと思った。

たとえばPostモデルってのがあるんだけど、Postモデルにsave()かdelete()があったときにはトップページのtopっていうアクションのビューも削除して欲しいって時には。

post.php

PHP:
  1. var $actsAs = array('ClearCache'=>array('names'=>array('top')));

として

以下のコードをclear_cache.phpとかで/models/behaviorsに保存しておけば

PHP:
  1. <?php
  2. /*
  3. *  キャッシュクリア
  4. */
  5. class ClearCacheBehavior extends ModelBehavior {
  6.  
  7.     var $names = array();
  8.  
  9.     function setup(&$model, $config = array()){
  10.         if(!empty($config['names']))
  11.             $this->names = $config['names'];
  12.     }
  13.  
  14.     function afterSave($created){
  15.         $this->_clear();
  16.     }
  17.  
  18.     function afterDelete(){
  19.         $this->_clear();
  20.     }
  21.  
  22.     function _clear(){
  23.         foreach($this->names as $name){
  24.             clearCache($name);
  25.         }
  26.     }
  27.  
  28. }
  29. ?>

Postモデルが更新されるたびにtopのビューキャッシュもクリアされて
いいと思います

まとめ

あと、CakePHPのビューのキャッシュはアクション名ベース(?)なので?id=99みたいなGETパラメータには対応していないとかもあるので、いっそビューのキャッシュはあきらめるというのも手です。

CakePHP1.2 Behaviorでモデルのメソッドキャッシュを行う : エクスギア Blog

AjaxZip2.0のjsonファイルをPHPで圧縮管理する

2月 18th, 2009 admin

Webのフォームで郵便番号から住所を自動入力するJavaScriptで
AjaxZip 2.0 - Ajax郵便番号→住所自動入力フォーム(CGI不要版)
というのがあって、以下点が気に入っているのでよく使わせていただいています。

・JavaScriptだけで動作(CGI・DB不要)
・さまざまな住所入力フォームに対応(都道府県がセレクトボックスとか郵便番号が2分割型など)

これのすごいのはCGIとDBを不要にするために郵便番号データを、あらかじめ約1000個のjson形式のファイルにするという斬新な方法が使われているということで、これを初めて見た時はその発想にとても感動しました。

大抵の場合はそのまま設置して使うのですが、約1000個というjsonファイルの管理が面倒なので、今回PHPを使って別の方法を探してみました(CGI不要の意味はなくなりますね)

今回やりたかったこと

・約1000個のファイルを扱わないようにしたい
・そのためならPHPなどを使っても良い
・そのためなら多少遅くなっても良い
・ただしDBは使いたくない
・AjaxZip2.0のフロント部分はそのまま使いたい

方法

(1)jsonファイルをZIPで一つにする
(2)zip-xxx.jsonに来たGETリクエストをPHPに転送(mod_rewrite)
(3)ZIPの中から必要なファイルだけ展開して返す

手順

(1)ajaxzip2をダウンロードしてくる
(2)展開してできたdata以下の.jsonファイルをallzip.zipという名前で保存
(3)mod_rewrite用の.htaccessをつくりdataに入れる

CODE:
  1. RewriteEngine On
  2. RewriteRule ^zip-([0-9]+)\.json$ ajaxzip2.php?zip=$1 [L]

(4)ajaxzip2.phpという名前でPHPも作ってdataにいれる

PHP:
  1. <?php
  2. define("ALL_ZIP_FILE", "./allzip.zip");
  3.  
  4. if(!isset($_GET['zip']) || !preg_match("/[0-9]{3}/",$_GET['zip'])){
  5.   exit;
  6. }
  7.  
  8. $zip = $_GET['zip'];
  9. $za = new ZipArchive();
  10. $za->open(ALL_ZIP_FILE);
  11. $json = $za->getFromName('zip-' . $zip .'.json');
  12. $za->close();
  13.  
  14. header("Content-Type: text/javascript; charset=utf-8");
  15. echo $json;
  16. ?>

(5)data以下はajaxzip2.phpと.htaccessとallzip.zipだけにする
(6)完成

ダウンロード

data(1,550KB)

まとめ

・1000個のファイルを扱わなくていいようになった
・jsonは約9Mあったのが、圧縮することで1.6Mぐらいになるという嬉しい副作用
・必要なファイルだけ解凍するのでメモリも食わない
・スピードも実用レベル
・AjaxZip2は超便利 Kawa.net様に感謝

CakePHP1.2で使えるテンプレート

2月 3rd, 2009 admin

CakePHPのサイトはカッコいいのに、CakePHPにデフォルトで入っているテンプレートはかっこ悪い。
もっと管理画面用のテンプレートってないのかなと思ったので、まず自分が一個公開します。
もとはフリーのテンプレートですがフォームやnotice,errorの部分などをCake風にアレンジしてあります。

見た目

cakephp001

cakephp002

ファイル

default.ctpとstyle.cssが入っているので、適切な場所に配置してください。
minimalistic.zip(9KB)
ライセンスはGPLです。

参考サイト

Minimalistic Design

xampp環境からPHPのメール送信を行う

12月 1st, 2008 admin

xampp環境でWebアプリケーションを開発していて困るのがメール送信だ。
今回はこれを解決する。

やりたいこと

・ローカルにSMTPサーバを立ててXAMPPのPHPからメール送信テストを行えるようにしたい
・ただし実際にメールは送らなくて良い

準備

Radish 札幌ソフト開発工場

手順

php.iniの編集

C:\xampp\apache\bin\php.iniを編集する。

CODE:
  1. [mail function]
  2. ; For Win32 only.
  3. SMTP = localhost
  4. smtp_port = 25
  5.  
  6. ; For Win32 only.
  7. sendmail_from = xxxx@example.com

ってな感じにする、僕の場合はsendmail_fromのコメントアウトをはずしてメールアドレスを自分の物にしました。

Radishの起動+設定

Radishを起動する。これだけでメールは送信されるのだけど、実際に送信される必要はないので
メインメニューから
「設定」->「SMTP/POP3サーバ」を押して
「基本設定」タブを開き
キュー常時処理という項目のチェックをはずす。すると自動でメールが送信されなくなりSMTPサーバに蓄積されるだけになる。

まとめ

・Radishすごい
・こんなに簡単ならもっと前からやっておけばよかった

phpThumbnailerで背景を埋める処理

11月 18th, 2008 admin

Index of /projects/phpThumbnailer
というPHPで画像のリサイズをしてくれるライブラリがあって、これが1ファイルでできている上にリサイズするだけなら

PHP:
  1. <?
  2. include("../class.Thumbnail.php");
  3. $tn_image = new Thumbnail("sample.jpg", 0, 0, 25);
  4. $tn_image->save("tn_sample.jpg");
  5. ?>

というシンプルさなのでとても重宝しています。
使い方とか、キャッシュをする方法は以前書いたのでこちらをご覧下さい。

Webアプリには必要十分なのですが唯一つ、画像のリサイズで空白を埋めるというのをやってほしかったので拡張をしました。
たとえばw100xh50の画像を50x50にリサイズしたときに、結果として50x25の画像を受け取るのではなく、50x50の画像ができあがって、縦の足りない部分は背景色を表示するというような感じです。

thumbnail.inc.phpに下記のメソッドを追加して使ってください。

PHP:
  1. /**
  2.      * Resizes image to maxWidth x maxHeight
  3.      *
  4.      * @param int $maxWidth
  5.      * @param int $maxHeight
  6.      * @param string $color
  7.      */
  8.     function resizeFar($maxWidth = 0, $maxHeight = 0, $color = "FFFFFF") {
  9.         $this->resize($maxWidth, $maxHeight);
  10.  
  11.         if($maxWidth> $this->currentDimensions['width'] || $maxHeight> $this->currentDimensions['height']){
  12.             if(function_exists("ImageCreateTrueColor")) {
  13.                 $this->workingImage = ImageCreateTrueColor($maxWidth, $maxHeight);
  14.             }else {
  15.                 $this->workingImage = ImageCreate($maxWidth, $maxHeight);
  16.             }
  17.             $color = imagecolorallocate($this->workingImage, hexdec('0x' . $color{0} . $color{1}), hexdec('0x' . $color{2} . $color{3}), hexdec('0x' . $color{4} . $color{5}));
  18.             imageFill($this->workingImage,0,0,$color);
  19.  
  20.             ImageCopy(
  21.                 $this->workingImage,
  22.                 $this->newImage,
  23.                 ($maxWidth - $this->currentDimensions['width']) / 2,
  24.                 ($maxHeight - $this->currentDimensions['height']) / 2,
  25.                 0,
  26.                 0,
  27.                 $this->currentDimensions['width'],
  28.                 $this->currentDimensions['height']
  29.             );
  30.             $this->newImage = $this->workingImage;
  31.         $this->currentDimensions['width'] = $maxWidth;
  32.         $this->currentDimensions['height'] = $maxHeight;
  33.         }
  34.     }