デザイナーのためのCakePHP入門

5月 2nd, 2008 admin

対象

プログラマがCakePHP(1.2)を押し付けてきてひどい目に遭っているコーディング担当用
PHPが< ?phpで始まり、?>で終わるということぐらいは知っているということにします。

拡張子

CakePHPで使われるデザインが書かれたファイル(以下テンプレート)の拡張子は.thtmlと.ctpがあります。.htmlだったら便利なんですけどね。プログラマからの嫌がらせだと思ってください。
Dreamweaver CS3で.thtml(CakePHP)の拡張子を編集できるようにするTIPS (what a bringdown)
STUDIO KINGDOM Blog � DreamWeaverでCakePHP開発を行う際の設定(.thtml)

編集すべきファイルの場所

ファイルは/app/viewsとかにあります。さすがにこの場所はプログラマに教えてもらいましょう。(プロジェクトによっては場所が違いますので)

テンプレート・・・/app/views/*
スタイルシート・・・/app/webroot/css
画像・・・/app/webroot/img
Javascript・・・/app/webroot/js

webrootにおいては上記の4つのディレクトリ以外は基本的に自由にファイルを配置したりディレクトリを作っても大丈夫です。ただし画像やスタイルシートを上記の4つ以外に入れたいという場合はプログラマに相談してください。

テンプレートの編集

view.gif
ここからは/app/views以下のテンプレートの編集の話です。CakePHPでは1つのページをいくつかのテンプレートを組み合わせて表示させています。
使われるのは「レイアウト」「メインのテンプレート(コンテント)」「エレメント」の3つです。
DreamWeaver使いの人なら
・レイアウト = テンプレートファイル
・コンテント = 普通のファイル
・エレメント = ユーティリティー
と考えてもらっていいと思います。

レイアウト

/app/views/layoutというディレクトリがあると思います。ここにはレイアウトファイルといってテンプレートの大枠部分が入っています。ヘッダやフッタ部分ですね。

エレメント

/app/views/elementsというディレクトリには各ページで共通のパーツが入っています。メインメニューや、カレンダーなどの表示部分をココに入れておくことが多いです。

helpers,scaffolds,errors

この3つは最初から用意されているディレクトリですので無視して大丈夫です。

それ以外

普通のページ用のテンプレートです。ブログでいうなら記事の表示部分に相当します。

どのファイルを編集すればいいのか

どのページがどのファイルかわからない場合は、編集したいページのURLをみてみてください。

http://example.com/users/edit/1

だった場合は

http://example.com/フォルダ名/ファイル名.ctp/1

ということになります。今回の場合は
/app/views/users/edit.ctp(もしくはedit.thtml)を編集するということです。
たまに違う場合もありますが、フォルダも違うということは滅多にないと思うので同じフォルダのそれっぽい名前のファイルを開いてみてください。

まとめ

これでCakePHPを使った開発の概要がわかってもらえたかと思います。なんだか素朴にPHPを編集していたときと比べるとかなり違っていますが、レイアウトやエレメントは使いこなすことでデザイナーの人にもメリットがある仕組みだと思います。次回は具体的なソースの編集Tipsなどを書く予定です。

PHPで画像の縮小+キャッシュ

4月 29th, 2008 admin

いつもはphpThumbというのを使っていて、これは十分に強力で便利なんですけど重厚すぎる感じがするのでライトな感じのものをいろいろ組み合わせて作ってみました。

やりたいこと

  • 縮小画像をPHPで自動生成したい
  • 毎回自動生成するのは嫌だからキャッシュしたい

手順

便利なライブラリを入手

Gen-X-Design | Ian Selby » PHP Thumbnailer Class v2.0
これは画像縮小用のライブラリ。ファイルを1つインクルードするだけで使える。しかもサンプルコードが超簡単。

ファイルの配置+ファイル作成

PHP Thumbnailerをダウンロードしたら下図のように配置します。.htaccessとcacheフォルダも作ります。cacheは書き込み可能にしておいてください。これらはPHP THumbnailerにキャッシュ機能を追加するために使います。
tree2.jpg

使ってみます。

./img/csnagoya.jpgってファイルを400x300に縮小して表示したいと仮定して、こんな感じでHTMLを書きます。(cacheにはこんなファイルはありませんが気にしなくて大丈夫です)

index.html

HTML:
  1. <img src="./img/thumb/cache/400x300_csnagoya.jpg" alt="" />

.htaccess

CODE:
  1. <ifmodule mod_rewrite.c>
  2. RewriteEngine on
  3. RewriteCond %{REQUEST_FILENAME} ^.*$
  4. RewriteCond %{REQUEST_FILENAME} !-f
  5. RewriteRule ^.*/([0-9]+)x([0-9]+)_(.*)(jpg|gif|pnd)$ /img/thumb/show_image.php?width=$1&height=$2&filename=../img/$3$4 [R]
  6. </ifmodule>

.htaccessをこんな感じにします。んで、次が最後です

show_image.php

PHP:
  1. $filename = 'cache/'.$_GET['width']."x".$_GET['height']."_".basename($_GET['filename']);
  2.  
  3. include_once('thumbnail.inc.php');
  4. $thumb = new Thumbnail($_GET['filename']);
  5. $thumb->resize($_GET['width'],$_GET['height']);
  6. $thumb->save($filename,100);
  7. $thumb->show();
  8. $thumb->destruct();

以上で終わりです。これで一回目のアクセスのときにcache以下に400x300_csnagoya.jpgというファイルが作られて、二回目以降のアクセスにはキャッシュを読みに行くという構成になりました。phpThumbではキャッシュを読むときもphpを読み込む必要があったりしますが、この方法ならphpを読み込まずしてキャッシュを表示できるので高速です。

注意

  • ファイル数が多いときには注意(cache内をディレクトリで分けたり)
  • cacheが勝手に消えない

参考サイト

画像もDBに格納して管理する ―扱いがめんどうなLOB(ラージオブジェクト)は使わない方法

PHPのfgetcsvでMacのやつやSJISのやつを扱うとき

4月 27th, 2008 admin

PHPにはCSVを処理してくれるfgetcsvという便利な関数があって、これを使えばダブルクォーテーションとかの処理は考えなくていいようになります。ただし

  • CRの改行コードに対応していない
  • SJISだと、いわゆる5C問題にひっかかる

という問題があるので、CSVファイルを扱うときはいきなりfgetcsvで読み込むのでなくいったんファイルを作成して、それを読み直すのがよいと思います。以下がファイルを読み込んで改行コードと文字コードを変換してfgetcsvで読み直すサンプルです。

コード

PHP:
  1. $file = file_get_contents("アップロードされたファイルのパス");
  2. $file = ereg_replace("\r\n|\r|\n","\n",mb_convert_encoding($file,"UTF-8","SJIS-win"));
  3. $fp = tmpfile();
  4. fputs($fp,$file);
  5. fseek($fp,0);
  6.  
  7. while($o = fgetcsv($fp,1024)){
  8.   //処理
  9. }

CakePHPで検索機能の実装を少し楽する

4月 22nd, 2008 admin

  • 検索
  • ページング
  • ソート

この3つさえなければ僕はWebアプリが大好きです。

CakePHP1.2での簡単なやり方

CakePHP1.2ならLIKE文なんかをある程度作ってくれるのでWHER 1=1 AND...とか書かなくてOKで少しうれしいです。

コード

usernameとpasswordが入ったUserモデルとuser_idとかnameとかname_ruby,tel_mobileとかが入ったProfileモデルに対してAND検索をする例。

/admin_index.ctp

PHP:
  1. <h2>ユーザの検索</h2>
  2. <form action="<?php echo $html->url('/admin/users/index'); ?>" method="get">
  3. <table>
  4.     <tr>
  5.         <th width="20%">ログインID</th>
  6.         <td>
  7.             <?php echo $form->input('Words/username', array('size' => '20','label'=>false));?>
  8.         </td>
  9.     </tr>
  10.     <tr>
  11.         <th>名前</th>
  12.         <td>
  13.             <?php echo $form->input('Words/name', array('size' => '30','label'=>false));?>
  14.         </td>
  15.     </tr>
  16.     <tr>
  17.         <th>フリガナ</th>
  18.         <td>
  19.             <?php echo $form->input('Words/name_ruby', array('size' => '30','label'=>false));?>
  20.         </td>
  21.     </tr>
  22.     <tr>
  23.         <th>携帯電話番号</th>
  24.         <td>
  25.             <?php echo $form->input('Words/tel_mobile', array('size' => '15','label'=>false));?>
  26.         </td>
  27.     </tr>
  28. </table>
  29. <?php echo $form->submit('検索');?>

/users_controller.php

PHP:
  1. function admin_index() {
  2.         //検索ワードがあるかどうか
  3.         $conditions = null;
  4.         if(isset($this->params['url']['data']['Words'])){
  5.             $this->data['Words'] = $this->params['url']['data']['Words'];
  6.             $like = $this->_create_like_conditions($this->params['url']['data']['Words']);
  7.             $conditions = array('and' => $like);
  8.         }
  9.         $this->User->recursive = 0;
  10.         $this->set('users', $this->paginate($conditions));
  11.     }
  12.  
  13.     function _create_like_conditions($data){
  14.         $like = array();
  15.         foreach($data as $k=>$v){
  16.             $like[$k] = 'like %'.$v.'%';
  17.         }
  18.         return $like;
  19.     }

まとめ

likeのところは、or,not,in,between,regexp,<>にも対応しています。また今回はand検索でしたがもちろんorでもいけます。

みんなには嫌われているけど現場では他に選択肢がないため大活躍なジャックバウワーのような存在「PHP+CakePHP」、今日も助かったよ!

ロリポップをPHPとGmailでお手軽バックアップする

4月 19th, 2008 admin

ロリポップのファイルをバックアップするために任意のディレクトリをzipで圧縮してメールでGmailに送るスクリプトを書いた。
別にGmailでなくてもいいのだけどGmailなら6Gぐらい容量があるし、ゴミ箱に自動で入るように設定しておけば30日ごとに勝手に消してくれるので非常にお手軽なのです。

コード

メールの送信にphpmailerというのを使っています

PHP:
  1. <?php
  2.  
  3. //ライブラリ読み込み
  4. require("./PHPMailer/class.phpmailer.php");
  5.  
  6. //バックアップするディレクトリを指定
  7. $backup_dir = "../photo"; //この場合はphotoディレクトリ以下をバックアップ
  8. //ファイル名を指定
  9. $new_file = "domain.com.zip";
  10.  
  11. //送り先
  12. $to = "任意のメールアドレス@gmail.com";
  13. $subject = "domain.com backup";
  14. $body = "";
  15. $from = "任意のメールアドレス@gmail.com";
  16. $fromname = "domain.com";
  17. $attachfile = "./domain.com.zip";
  18.  
  19.  
  20. mb_language("japanese");
  21.  
  22. system("zip -r $new_file $backup_dir");
  23.  
  24.  
  25.  
  26. $mail = new PHPMailer();
  27. $mail->CharSet = "iso-2022-jp";
  28. $mail->Encoding = "7bit";
  29.  
  30. $mail->AddAddress($to);
  31. $mail->From = $from;
  32. $mail->FromName = mb_encode_mimeheader(mb_convert_encoding($fromname,"JIS","EUC-JP"));
  33. $mail->Subject = mb_encode_mimeheader(mb_convert_encoding($subject,"JIS","EUC-JP"));
  34. $mail->Body  = mb_convert_encoding($subject,"JIS","EUC-JP");
  35.  
  36.  
  37. $mail->AddAttachment($attachfile);
  38.  
  39. if (!$mail->Send()){
  40.     echo("メールが送信できませんでした。エラー:".$mail->ErrorInfo);
  41. }
  42.  
  43. unlink($new_file);
  44. ?>

まとめ

  • ロリポップは安いのにsystem関数使えて凄い、PHPのzip用のライブラリも入ってます
  • rmコマンドは使わせてもらえないらしい、unlink関数でファイルは消す
  • 現在Zipで送ってるだけなのでセキュリティ的にアウト、暗号化するのが望ましい
  • 定期的に実行するためにwebcronのようなサイトを使う(もしくは他サーバから、もしくは1日の最初の訪問者とかに踏ませる)
  • Gmailのほうでここからのメールはゴミ箱に直行の設定をしよう
  • Gmailで転送設定しておけば簡単に二重化ができる!
  • Gmailの規約は要確認

参考サイト

phpmailer
http://phpmailer.codeworxtech.com/
PHPで日本語メールを送る - 応用編 (添付ファイル、HTMLメール) - EC studio 技術ブログ
http://techblog.ecstudio.jp/tech-tips/mail-japanese-advance.html