人気ブログランキング |
タグ:CakePHP ( 19 ) タグの人気記事
(CakePHP)命名規約の単数形、複数形を自動的に変換してくれるサイト
CakePHPはファイル名や、コントローラ名、モデル名、ビュー名、テーブル名などに規約が定められています。
規約については、ここここに細かいことが書かれています。

そして、めんどいのは単数形、複数形の規約があることです。
英語の心得がない自分にはこれは非常にハードルが高いです。

CakePHP 規約ワードメーカーはCakePHPの単語変化関数を用いて入力された単語を規約に従ったファイル名や、コントローラ名、モデル名、ビュー名、テーブル名に変換してくれるサービスです。

CakePHPの開発には欠かせませんね。
by jehoshaphat | 2008-12-20 22:41 | PHP開発
(cakePHP)Formヘルパーのselectボックス(時,分)表示 Warning array_merge()が出た。
cakePHPで時や分を独立で表示したいときはFormヘルパーの hourメソッド や minuteメソッド が使えます。
定義、使い方は下記の通りです。(cakePHPポケットリファレンスより引用)

時選択タグ表示
FromHelper::hour( $fieldName , $format24Horus = false , $selected = null ,
$attibutes = array() , $showEmpty = true )
$fieldName :[string] 入力を受け付ける要素("モデル名.フィールド名"の形式)
$format24Horus :[boolean]true:24時間表記
$selected :[string] 初期選択値
$attibutes :[array] 要素の属性
$showEmpty :[boolean]空のoption要素を出力するかどうか。(文字列指定するとその文字が空要素の内容になる)

分選択タグ表示
FromHelper::minute( $fieldName , $selected = null ,
$attibutes = array() , $showEmpty = true )
$fieldName :[string] 入力を受け付ける要素("モデル名.フィールド名"の形式)
$selected :[string] 初期選択値
$attibutes :[array] 要素の属性
$showEmpty :[boolean]空のoption要素を出力するかどうか。(文字列指定するとその文字が空要素の内容になる)

で、これに従って、下記のように、Formヘルパーで時間と、分を選択させるSelectボックスを表示させました。
<!-- ViewのCTPファイル-->
<?php echo $form->hour('Missionary.time', true , 0 , null , false )?>
<?php echo $form->minute('Missionary.time', 0 , null , false )?>

で、こうすると下記のような警告が出てきました。

Warning (2): array_merge() [function.array-merge]: Argument #1 is not an array [CORE\cake\libs\view\helpers\form.php, line 1141]

なんじゃ、こりゃと思って、いろいろ調べると、CakePHPクッキングにて答えが載せられてました。

どうやら、1.2のRC3以降では引数の $attibutes に null を渡していたのがまずいようです。これを下記のように array() にするとOKでした。

<!-- ViewのCTPファイル-->
<?php echo $form->hour('Missionary.time', true , 0 , array() , false )?>

<?php echo $form->minute('Missionary.time', 0 , array() , false )?>


ちなみに、cakePHPポケットリファレンスの例では $attibutes に null を渡しているので、これ見ながら作ってる人は要注意です。(まあポケットリファレンスのほうは1.2のベータ版で評価してるっぽいので、仕方ないのですが。。。)

CakePHP ポケットリファレンス (Pocket Reference)


by jehoshaphat | 2008-12-04 14:12 | PHP開発
(cakePHP)MySQL保存時に文字化けしないようにする。
こちらで見つけました。

具体的には app/config/database.php で
'encoding'=>'クライアントの文字コード'
を追加してやればいいみたいです。

こうすると内部的に SET NAMES を実行してくれるっぽいです。

ちなみに、普通のPHPやクライアントから使うときは
SET NAMES utf8
というようにSET NAMESでクライアントの文字コードを指定してやればいいようです。

が、このSET NAMESは脆弱性があるらしく、PHPからの使用はあまり進められてないようです。
変わりにPHP5.2.3から新たに追加された mysql_set_charset() を使うのがよろしいみたいです。
ここら辺の脆弱製がらみの情報はこちらこちら参照にしました。

まあ、といってもcakePHPの場合 SET NAMES使ってるわけで、自力でフレームワークのコア部分直してもいいんですが、そうするとバージョンアップ等で手間だし、勉強目的なので、しばらくはこのままで行きたいと思います。
by jehoshaphat | 2008-12-04 01:51 | PHP開発
(PHP)MySQLの関数を使おうとすると「Unable to load dynamic library」と怒られる

Windowsの開発環境上で、cakePHPでデータベースに保存するコントローラで下記のようなエラーが出ました。

[error] [client 127.0.0.1] PHP Fatal error: Call to undefined function mysql_connect() in C:(省略)\\cake\\libs\\model\\datasources\\dbo\\dbo_mysql.php on line 6

あれ? mysql_connect()が使えないのか?と思って、mysql_connect()だけ書いたPHPを置いて、PHP.iniでエラー表示を有効にして(display_errors = On)実行。

やはり Call to undefined function mysql_connect() となります。
Apacheの error.log を見てみるとPHPの起動時に下記のようになっていました。

PHP Warning: PHP Startup: Unable to load dynamic library 'D:\\Program Files\\PHP\\ext\\php_mysql.dll' - \x8ew\x92\xe8\x82\xb3\x82\xea\x82\xbd\x83\x82\x83W\x83\x85\x81[\x83\x8b\x82\xaa\x8c\xa9\x82\xc2\x82\xa9\x82\xe8\x82\xdc\x82\xb9\x82\xf1\x81B\r\n in Unknown on line 0

どうやら、php_mysql.dllがAapacheに読み込まれてないようです。

で、php.iniの extension_dir や extension=php_mysql.dll の設定も見直してみましたが問題なし。
(というより、インストーラでインストールしてるから問題あったら困るんですけどね。)

で、いろいろ探しているうちに、みつけたのがこちら
どうやら、MySQLのクライアントライブラリである libmysql.dll がWindowsのパスの通る場所においてないといけないみたいです。
自分の場合、libmysql.dll は既に、PHPのインストールフォルダ直下に用意されてました。
Sytem32にDLLおくのはいやなので、PHPのインストールフォルダに環境変数のPATHを通すことに。

注意点は環境変数でPHPのパスを通した後はOSを再起動すること。
自分の場合も再起動しないと反映されていませんでした。
by jehoshaphat | 2008-12-04 00:54 | PHP開発
(cakePHP)Qdmailを使った日本語メール送信
以前にフレームワークを使わないPHPで日本語を送る方法を書きました。
cakePHPにはフレームワークなんだから、メールくらい簡単に遅れるだろうと思ってましたが、どうやら標準のメール送信ライブラリではmail関数を使っているため日本語メールが送れないみたいです。

前と同じように mb_send_mail で送信しようかとも思いつつ、ググって見つけたのが Qdmail です。

非常に高機能かつ使いやすいライブラリで、様々なフレームワークに対応してますし、フレームワークがない環境でも動くように作られています。で、国産というのも魅力です。

こちらが公式ページになります。 http://hal456.net/qdmail/
使い方はこちらに載せられてますが、Qdmailで日本語のメール送信こちらを参考にさせてもらい導入してみました。。

ダウンロード後、qdmail.php を app/controllers/components/ 配下に配置します。

下記が使用例です。
メールのようのテキストテンプレートファイルを用意して指定された文字列を置換するような仕組みにしてます。(これもcakePHP使ってるならもっといい方法があるんでしょうけど。。。)

class MailsController extends AppController{
var $name = "Mails";
//どのコンポーネントを使うか定義

var $components = array('Qdmail');

/*
* 他のメソッドは省略
*/

 
/*
* メール送信用プライベートメソッド
*/

function _sendMail(){

 
//リセット
$this->Qdmail->reset();
//送信先指定
$this->Qdmail->to('yyy@xxxx.jp', 'お客様');
//送信元指定

$this->Qdmail->from('ddd@eee.jp', 'ネットショップ○○');
//件名指定
$this->Qdmail->subject('ご注文確認');

 
//メール本文テンプレート読み込み
$mailBody = file_get_contents("テンプレートファイル名");
 
////テンプレートに置換するデータ生成
//現在日時曜日取得

$array_week = array("日","月","火","水","木","金","土");
$week = $array_week[date("w")];
$date = date("Y/m/d H:i:s"). " " .$week ;
//製品情報

$where = array( "id" => $this->params['form']['product'] , "prd_del" => "0" );
$product = $this->Product->find( $where ); //指定されたidのデータをDBから抽出

//都道府県
$where = array( "id" => $this->Member->data['Member']['pref_id'] );
$pref = $this->Pref->find( $where ); //指定されたidのデータをDBから抽出

//ダイレクトメールをビューにセット
if ( $this->Member->data['Member']['mem_dmail'] == 0){

$dmail = '希望する';
}else{
$dmail = '希望しない';
}
//職種アンケート(DBから入力されたIDの値抽出)

$btype = $this->Businesstype->find( array("id"=>$this->Order->data['Member']['businesstypes_id'],"btyp_del" => "0" ));
//認知媒体アンケート(DBから入力されたIDの値抽出)

$know = $this->Know->find( array("id"=>$this->Order->data['Order']['know_id'] ,"know_del" => "0" ) );

//送信データと置換対象文字列定義。。

$sendData = array( "@date" => $date,
"@order_product" => $product['Product']['name'] ,
"@name" => $this->Member->data['Member']["name"],
"@mail" => $this->Member->data['Member']["mail"],
"@zip" => $this->Member->data['Member']['zip'] ,
"@pref" => $pref['Pref']['name'],
"@addr" => $this->Member->data['Member']["addr"],
"@tel" => $this->Member->data['Member']["tel"],
"@dmail" => $dmail ,
"@ctgb" => $btype['Businesstype']['name'] ,
"@know" => $know['Know']['name'],
);
//メール本文を置換。

$mailBody = strtr($mailBody ,$sendData );
 
//テキスト生成(?)
$this->Qdmail->cakeText($mailBody );
//cakePHP用にcakeTextというメソッドがあるらしいが、詳しい使い方が不明。。

//$this->Qdmail->cakeText( $content , $template , $layout , $org_charset , $target_charset, $enc , iso-2022-jp )
 
//送信
$this->Qdmail->send();
}

}

cakePHPのテンプレートファイルやレイアウトを指定して、もっと効率的にする方法(cakeText,cakeHtmlメソッド)があるようですが、ここら辺はまだ試してないので、普通に text メソッドで生成してます。
コントローラー内で一度ビューの内容をメモリ上に描画してそれの結果を変数に取得して送信する方法もあるようで、cakePHP メール送信はもうこれでいいでしょに書かれてました。
by jehoshaphat | 2008-11-11 19:46 | PHP開発
(cakePHP)コントローラからモデルにアクセス
久しぶりにcakePHPに開発に復帰しましたが、2週間ほど離れただけで早くもいろいろ忘れています。

今回バリデートの機能の豊富さを見越してcakePHPを1.2にバージョンアップさせました。
その時のメモはまた後日公開します。

ところでcakePHP1.2ではビューの入力に使ってたHtmlヘルパーの大半がFormヘルパーに移行されてます。
よく使うのは $form->input でしょう。これも大幅機能強化されたみたいで、日付の入力のセレクトボックスとかも1.1時代より簡単に使えるようになった気がします。(これについても後日)

で、日付入力セレクトボックス作ったのですが、この値は指定したモデルに下記のような配列で格納されてました。

Array
(
[year] => 1966
[month] => 11
[day] => 07
)


今、入力後に確認画面に飛ぶようなつくりにしているのですが、確認ビュー側で下記のようにしてやってもArrayと表示されるだけで値が取れません。

$form->value('Member.mem_birthday.year')


DBに保存するときもyyyyMMddという文字列で保存したいということでコントローラ側でデータを加工してから(単一の文字列にしてから)DBに渡すことにしました。

で、いきなりつまずいたのが、コントローラからモデルの中身にどやったらアクセスできるの? ということです。

cakePHPには debug() 関数たるものがあって、これで簡単に変数がのぞけます。
これを駆使した結果下記のようにしてコントローラからモデル(日付セレクトボックスの値)にアクセスできることが判明しました。


//ビューから送られてきた日付セレクトボックス( $form->input の "type" => "date" )でできたモデルに格納された値を取得。
debug( $this->data['Member']['mem_birthday']['year']);
debug( $this->data['Member']['mem_birthday']['month']);
debug( $this->data['Member']['mem_birthday']['day']);
 
//DBから拾ってきたモデル本体の値をとるには
debug( $this->Member->data['Member']['mem_birthday']['year'] );
debug( $this->Member->data['Member']['mem_birthday']['month'] );
debug( $this->Member->data['Member']['mem_birthday']['day'] );

上と下では意味が違うみたいなので注意。
上のほうはビューから送られてきたデータです。
下は本当のモデルです。
しかし、本当にこの方法でいいのかは不明です。

では確認画面として使ってるビューのほうでどうやれば取り出せるのか試してみました。
どうやら下記のようにするとうまくいくようです。
$form->value('Member.mem_birthday.year')

ドットで区切れば配列であっても見えるということですね。

これで確認画面から送られてきたモデルを加工し、配列から文字列に直してDBにセットすればOKというわけです。
by jehoshaphat | 2008-11-07 19:48 | PHP開発
(cakePHP) selectタグを作りたい
HTMLヘルパーで select タグを表示させる方法です。マニュアルには載ってませんでした。
ほぼリンク的感じですが、cakepPHP先輩方に感謝です。

HTMLヘルパーに selectTag というのがあるのでこれを使うようです。

HtmlHelper::selectTag (
$fieldName, // フィールド名。コントローラからは、$this->params['data']で取得できる。
$optionElements, // 選択項目の名称 'array("1","2","3")など。'
$selected = null, // 何番目が選択状態か(整数 or null)
$selectAttr = array(), // SELECTエレメントの属性'array('onChange'=>'return this.form.submit();', 'class' => 'cssclassname') など。'(これがよくわからん)
$optionAttr = null, // OPTIONエレメントの属性。$selectAttr と同じ方法。
$showEmpty = true, // 空項目を出力するか
$return = false // true にすると、echo ではなく、return でデータが返る。
)



要は $optionElements に選択項目、 $optionAttr に optionタグの value が入るといった感じみたいですね。

そしてModel側から$optionElementsを使うには
$this->モデル単数名->generateList()
でできるみたいです。
ただし、これは cakePHP 1.1 の場合で 1.2 からはgenerateList()が非推奨になっているため find('list') を使う方法が推奨されてます。

1.1で find('list') を使ってみましたが、SQLのエラーが出ました。やはり1.2からじゃないと使えない?

generateList()は結構癖があるようです。
引数としては
$this->Model->generateList($conditions, $order,$limit, $keyPath, $valuePath);
$coditions :検索条件
$order :ソートの指定
$limit :取り出す数
$keyPath :配列のキーにするフィールド
$valuePath :配列の値にするフィールド
この$keyPath と $valuePath は {n}.Model.field というように {n} が必要だそうです。
ということが、CakePHP Model::generateList メソッドの {n}に書かれてます。



ということで都道府県テーブル(prefs)からselectタグを表示する例です。( generateList()の場合 )

//****コントローラ側の記述****
//検索条件、ソート、取り出す数は指定しない。キーはid , 値はname
$prefs = $this->Pref->generateList("", "" , "" , "{n}.Pref.id", "{n}.Pref.name");
//ビューにセット
$this->set('prefs', $prefs);
 
//****ビュー側の記述****
//特に指定してないため初期値は空白値。結果は Member/pref_idに 入る。
<?php echo $html->selectTag('Member/pref_id', $prefs , null , null, null); ?>


参考:
SelectTag の使い方 cakePHPのフォーラムにて、selectTagの引数説明や取得方法について投稿されてます。

CakePHP HTMLヘルパーで select タグを表示する
selectTagについてかなりわかりやすく書かれてます。
モデルの指定列からselectタグを作るのに便利な方法 1.2でselectタグ作るときの方法について分かりやすく説明されてます。
find('list')に少々ハマる1.2でfind('list')を使うときの注意点です。
by jehoshaphat | 2008-10-23 14:54 | PHP開発
(PHP)cakePHPのインストール(ディレクトリの設定)
cakePHPのインストールにはまってしまったので、メモしときます。

レンタルサーバ上での運用を目的としているで、Cakeのインストールマニュアルの「3.4.3. 高度なセットアップ:その他のインストール方法」に当たるインストール方法です。

レンタルサーバの構成は下記の通りです。


/ (ルート直下はwebサーバからは参照されない)
/www.xxx.jp(webサーバで参照される場所。public_html)


ダウンロードしたcake_1.1.20.7692.zipを解凍します。

app と cake フォルダを/(ルート)直下にコピーします。
(フレームワークとはいえ、webサーバから参照される場所にはおかないほうがいいと思ったので、それの対策です。)

app/webroot/ がWebサーバからアクセスされる必要があるため、この配下のファイルを /www.xxx.jp 配下に移動します。

この時点でファイルの配置は下記のような構成になっています。


/
/app
/config
/controllers
/models
/plugins
/tmp
/vendors
/views
index.php
/cake
/config
/docs
/libs
/scripts
app_controller.php
app_model.php
basics.php
bootstrap.php
dispatcher.php
/vendors
/www.xxx.jp (配下のファイルは/app/webroot/から移動したもの)
index.php


あとは/www.xxx.jp/index.phpの修正です。
相対パスでROOT , APP_DIR , CAKE_CORE_INCLUDE_PATH を指定します。


if (!defined('ROOT')) {
//appの上のディレクトリ
define('ROOT', '..'.DS);
}
if (!defined('APP_DIR')) {
//ROOTからみてappがどこにあるか
define('APP_DIR', 'app');
}
if (!defined('CAKE_CORE_INCLUDE_PATH')) {
//これはindex.phpからみてcakeの上のディレクトリを指定。
define('CAKE_CORE_INCLUDE_PATH', '..'.DS);
}


また、Apacheを使用してる場合、moe_rewriteが有効になっていないといけません。
自分の開発環境のApacheは
#LoadModule rewrite_module modules/mod_rewrite.so
とmod_rewriteがコメントアウトされていたので、このコメントアウトを解除します。
LoadModule rewrite_module modules/mod_rewrite.so

さらに、ApacheのDocumentRootはcakePHPのwebroot(上記の設定だと/www.xx.jp)にしておかないといけません。
自分は開発環境のDocumentRootを触りたくなかったのでApacheのaliasでやっていましたが、見事に動きませんでした。
要注意点です。

Apacheがらみでもう一点。
デフォルトだとDocumentRootは
AllowOverride None
となっているので、
AllowOverride ALL
としましょう。


参考:
CakePHP のディレクトリ構成を変更する まさにcakePHPのディレクトリ環境についてかかれてます。助かりました。
by jehoshaphat | 2008-10-22 22:38 | PHP開発
(PHP)フレームワーク選定
久しぶりにPHPの開発をすることになり、フレームワークを使って開発することにしました。

しばらくPHP界から離れていた間に随分多くのフレームワークが出てきていました。
まさにPHPフレームワーク乱立世界です。

メジャーなものは下記にまとめています。
■cakePHP
Railsに似ている。
現時点で、人気がある。
小規模向け。
PHP4でも動く。
どうやらIBMがバックにいるから安心。

■symfony
Yahoo!でも使われている。
かなりの高機能。(故の複雑さもあるらしい)
重い。
大規模向け。

■Zend Framework
独立の強いコンポーネント指向。
コンポーネント指向ゆえにコードは結構書かないといけない。
Zendお墨付き。
軽い。


どのフレームワークにするのか結構悩みましたが、結局シェアが一番多いといわれているcakePHPにしました。
実はcakePHPをベースとした国産の「ちいたん」という世界最軽量(?)フレームワークも見つけてちょっとしたものを作るには非常に使えそうなきがしたのですが、とりあず今後のことも考えてcakeにしました。
自宅サーバでちゃちゃっと作るときにはちいたん、使ってみたいと思います。

以下に、比較サイトをまとめてみました。
PHPのMVCフレームワーク比較: Symfony CakePHP ZendFramework Ethna 4つのフレームワークについて率直な意見が書かれています。
PHPフレームワーク 9つの比較
Grafica Comparacion Frameworks 表形式でまとめられています。
PHPフレームワーク特集 CakePHP、symfony、Zend Frameworが比較
PHPフレームワークの比較 表形式でまとめられています。
New Year’s Benchmarks フレームワークのベンチマーク結果が出ています。
by jehoshaphat | 2008-10-22 17:30 | PHP開発