CakePHPでVirtualFieldsを使う

virtualfieldsは任意のSQL表現をつくり、モデルのフィールドとして割り当てることができます。作成したフィールドは保存することができません。find関数等で他の引数と渡すとエラーになりますので注意が必要です。その場合は渡す前に空にもどしましょう。その他データベースにバーチャルフィールドと同じ名前があるとエラーを引き起こします。

バーチャルフィールドの作り方
モデルAにバーチャルフィールドを作成します。

1:モデルAのバーチャルフィールドを追加します。

$this->virtualFields = array(
  ‘rank’ => ‘sum(User.rate)’,
  );

2:フィールドに追加します。

  $fields = array(
   ’conditions’ => array(‘User.agecheck’ => 1),
‘fields’ => array(
‘User.id’,
‘User.rate’
‘User.rank’
)
);

$res = $this->ModelA->find(‘all’, $fields);

ザックリかきすぎてしまった。
また今度書き直そう・・・ではっ!

cakephp パスワードリマインダー機能の実装

cakephpでパスワードリマインダー機能を追加しました。あまり探してなかったので、フローとメモを記しておきます。

準備:

・Controller

UsersController.php

・Model

User.php

EmailSend.php

PasswordRemind.php

・View

forgot_password.ctp

reset_password.ctp

=========================================

流れ

①【forgot_password.ctp】 

*Controllerに渡すデータ値 

ユーザーネーム(メールアドレス)

これらをFormヘルパー:createの’action’ => ‘forgot_password’,で渡しています

================================================

②【UsersController.php】

*あるユーザーネームだけ取得します

function forgot_password(){

// フォームからポストされたデータがあるかどうか
if ($this->request->is(‘post’)) {
// 登録されているメールアドレスが存在するかどうか
$username = !empty($this->request->data[‘User’][‘username’])?$this->request->data[‘User’][‘username’]:”;  
$user_id = $this->User->userNameExists($username);  ・・・・・①

if(!empty($user_id)){ ・・・・②
// 存在すればURLを作成し、メール送信し、リセットパスワードを送信
//アクチベーション用のURLを作成
$url =
DS . strtolower($this->name) . // コントローラ
DS . ‘reset_password’ . // アクション
DS . $this->User->getPasswordRemindHash($user_id);
$url = Router::url( $url, true);
$this->EmailSend->sendPasswordRemindMail($username, $url, ‘forgot_password’);

$this->Session->setFlash(__(‘入力されたメールアドレス宛にパスワードリセットURLが記載されたメールを送信しました。メールを確認し記載されたURLにアクセスしてパスワードを新しいパスワードに更新してください。’));
return $this->redirect(array(‘controller’ => ‘users’,’action’ => ‘forgot_password’ ));
}else{
// 存在しなければ
$this->Session->setFlash(__(‘このメールアドレスは登録されていません。’));
}
}

=========================================================

①はModelのUser.phpにて、ユーザーIDでユーザー名(メールアドレス)が存在するかどうかを取得しています。

public function userNameExists($username) {
$result = $this->find(‘first’, array(
‘fields’ =>array(
$this->alias.’.id’,
),
‘conditions’ => array(
$this->alias.’.username’ => $username,
$this->alias.’.retired’ => false, ・・・・これは削除されていないよって意味だよ。削除されているユーザーを取得することはないのでここで指定しているんだよ。
),
‘recursive’ => -1, //Userのみ取得する
));
// 存在すればIDを返し、存在しなければfalseを返す
return !empty($result[‘User’][‘id’])?$result[‘User’][‘id’]:false;
}

*find関数 

*三項演算子 (条件式)?trueの時:falseの時;

===========================================================

【ここ重要!】

②はModel/User.phpのgetPasswordRemindHashアクションで

始めにユーザーネーム(メールアドレス)を取得し、次にハッシュ値を生成し、

そのユーザーネームに対するURLにハッシュをくっつけてます。

$this->log(“———-function getPasswordRemindHash–“.__FILE__.__LINE__.”\n”);
// ユーザIDの有無確認
if ($this->exists($user_id)) {
// 更新日時を取得しハッシュ化
$result = $this->find(‘first’, array(
‘conditions’ => array(
‘User.id’ => $user_id,
‘User.retired’ => false,
),
‘fields’ => array(
‘User.username’,
),
‘contain’ => array(),
‘recursive’ => -1, //Userのみ取得する
));
//modifiedによりハッシュを作成する。
$hash = $this->PasswordRemind->makeHash( $result[‘User’][‘username’]);
$this->PasswordRemind->saveHash($user_id, $hash);
return $hash;
}else{
//ユーザーが存在しなければfalse
return false;
}

====================================================

Model/PasswordRemind.php にて

public function makeHash($email = ”) {
//現在時刻とemailによりハッシュを作成する。
return Security::hash( $email . date(‘Y-m-d H:i:s’), ‘sha1’, true);
}

public function saveHash($user_id, $hash) {
$this->create();
$savedata = array(
‘user_id’ => $user_id,
‘hash’ => $hash,
‘created’ => date(‘Y-m-d H:i:s’), // 一応明示的に現在時刻をいれてあげる
);
return $this->save($savedata);
}

========================================================-

さあ、ここでEmailを送るのだが、いくつか注意点があります。(てか、いくつかエラーがでた)

ここではModel/EmailSend.php でメール送信を行っていますが、

まず、ソースは

function sendPasswordRemindMail($Email, $url, $template = null){

// メール送信

$email = new CakeEmail(‘password_remind’);
try {
$email->config(‘password_remind’);
// メーラー情報の削除 cake phpで作成されたことがバレバレになってしまうため。
$email->addHeaders(array(‘X-Mailer’ => false));
$email->emailPattern(‘/^[-+.\\w]+@[-a-z0-9]+(\\.[-a-z0-9]+)*\\.[a-z]{2,6}$/i’);
$email->to(array($Email));
$email->viewVars(compact(‘Email’));
$email->viewVars(compact(‘url’));
$email->template(‘refresh_password’, ‘default’);
$email->subject(Configure::read(‘MAIL_SUBJECT_HEADER’).Configure::read(‘MAIL_SUBJECT.password_remind’));

$result = $email->send();
$this->log(‘登録メール送信’.__FILE__.__LINE__);
} catch(Exception $e) {
try {
// “”で囲む処理を入れる
$arr = explode(‘@’,$Email);
$arr[0] = ‘”‘ .$arr[0] .'”‘ ;
$mail = $arr[0].’@’.$arr[1];

debug($e->getMessage());
$email->config(‘password_remind’);
// メーラー情報の削除 cake phpで作成されたことがバレバレになってしまうため。
$email->addHeaders(array(‘X-Mailer’ => false));
// “を許可する
$email->emailPattern(‘/^[-“+.\\w]+@[-a-z0-9]+(\\.[-a-z0-9]+)*\\.[a-z]{2,6}$/i’);
# $email->to(array($request_data[‘User’][‘username’]));
$email->to(array($mail));
$email->viewVars(compact(‘Email’));
$email->viewVars(compact(‘url’));

$email->template(‘refresh_password’, ‘default’);
$email->subject(Configure::read(‘MAIL_SUBJECT_HEADER’).Configure::read(‘MAIL_SUBJECT.password_remind’));

$result = $email->send();
$this->log(‘登録メール送信’.__FILE__.__LINE__);
} catch(Exception $e) {
debug($e->getMessage());
}
}
}

ですが、テンプレート指定や送信内容(POSTとかホストとか・・)は調べれば出てきます。

私がエラーで困っていた場所は、メールサーバーの部分で起きていた。

メールシステムの簡単なおさらい

 
どうやら開発で混乱している? ようなので……
 

ポート番号??

 
ポート番号ってのはTCP/IPに出てくる仕組みの一つで、
通信相手としてIPアドレスだけじゃなくてポート番号も指定することで
通信相手(プログラム)を特定する。
電話にたとえると家に掛けて『○○さんお願いします』と言うようなもの。
 
メールの送信(配送)に関係するポートはこの3つ
 
25 SMTP 通常のメール配送に使うポート メールサーバー間のメールのやり取りは今でもここが基本
587 submission SPAM対策で25番のかわりに使われるポート PCからサーバーにメールを渡すとき使う 通常は暗号化されないがオプションで暗号化も可能(STARTTLS)
465 SMTP over SSL 暗号化したSMTP通信を行うときのポート PCからサーバーにメールを渡すとき使う 常に暗号化される
 

サーバーどこ?

 
メールサーバー mail.parafamily.net
パラファミリー顧客の使うメール機能を一手に引き受けるサーバー
ポートは 25 587 465 が空いている
25 このサーバーで管理するメールアドレス宛のメールのみ受け取る
(ただしサーバー内部から接続して送信すると、外部サーバーへもメールを出せる)
465 SMTP認証が通った場合のみメールを受け取る
587 暗号化(STARTTLS)利用可能、SMTP認証が通った場合のみメールを受け取る
 
それ以外のサーバー(cs1とか)
これらのサーバーでもSMTPは動作しているが、送信専用である
25 サーバー内部からしか接続を受け付けない 外部サーバーへもメールを出せる
 
というわけで、WebシステムからSMTPでメールを出したい場合は、
localhost:25 へ接続してメールを出すのがよい。
(メールサーバーを経由しようとすると認証が必要なため面倒)

ここは処理とかじゃなく、メールサーバーも関係してくるので注意して欲しい。(泣)

========================================================

さて、ここで第一段階がおわりました。第二段階は送られたURLがリンクできるか、

パスワードと確認用パスワードが一致し、登録できるかの処理をいたします。

=========================================================

【UserController.php】 function reset_password(){}

// ハッシュのチェック ただしまだ完了フラグ(falseにする)は立てない
//ハッシュ文字列の情報があったら、Formから取得する
if(empty($in_hash) and !empty($this->request->data[‘User’][‘in_hash’])) {
$in_hash = $this->request->data[‘User’][‘in_hash’];
}
$user_id = $this->User->PasswordRemind->checkHash($in_hash, null, false); ・・・①
//$user_id = $this->User->getUserName($user_id);
if (empty($user_id)) {
throw new NotFoundException(__(‘Invalid Page’));
}
//↑↑↑↑Postデータが渡されるのは、パスワードと確認用パスワードなので、user_idは先に取得しておく必要がある。
// ポストデータがあれば保存をする(保存ボタンが押された場合以下の処理がはしる)
if ($this->request->is(‘post’)) {

$password = null;
$password_confirm = null;
if(!empty($this->request->data[‘User’][‘password’])) {
$password = $this->request->data[‘User’][‘password’];
}
if(!empty($this->request->data[‘User’][‘password_confirm’])) {
$password_confirm = $this->request->data[‘User’][‘password_confirm’];
}
$save = array(
‘id’ => $user_id,
‘password’ => $password,
‘password_confirm’ => $password_confirm,
);

$fieldList = array(
‘id’,
‘password’,
‘password_confirm’,
);

$this->User->id = $user_id;
//保存する
if($this->User->save($save,true,$fieldList)){
//保存成功したらハッシュを削除させるためにチェックを回す
$this->User->PasswordRemind->checkHash($in_hash);
$this->Session->setFlash(__(‘パスワードの更新に成功しました’));
// パスワード変更したんだから、ログイン画面がいいと思う
return $this->redirect(array(‘controller’ => ‘users’,’action’ => ‘login’));
}else{
$this->Session->setFlash(__(‘パスワードの更新に失敗しました’));
$errors = $this->User->validationErrors;

}
// これしちゃだめ→ unset($this->request->data[‘User’]);
} else {
// メールのURLからアクセスしたとき(POSTではない)
$this->request->data[‘User’][‘in_hash’] = $in_hash;
// 画面に$this->Form->hidden(‘in_hash’);を作る。
}
}

①ではcheckHashアクションで

================================================================

public function checkHash($hash, $time = null, $checking = true) {
if(empty($time)){
// 指定された時間がなければ
// 30分前の時間を取得
$time = date(‘Y-m-d H:i:s’, strtotime(date(‘Y-m-d H:i:s’) . ‘ -30minute’));
}
$hash = $this->find(‘first’, array(
‘fields’ => array(
‘PasswordRemind.id’,
‘PasswordRemind.user_id’,
),
‘conditions’ => array(
‘PasswordRemind.hash’ => $hash,
‘PasswordRemind.deleted’ => false,
‘PasswordRemind.created >’ => $time, //指定された時間よりも新しいhashの中で存在するかどうかのチェック
),
‘contain’ => array(),
));
// 存在すればUser_idを返し、存在しなければfalseを返す
if(!empty($hash[‘PasswordRemind’][‘id’])){
if($checking){
// checkingがtrueならば、同時に削除フラグを立てる
$savedata = array(
‘id’ => $hash[‘PasswordRemind’][‘id’],
‘deleted’ => true,
);
$this->save($savedata);
}
return $hash[‘PasswordRemind’][‘user_id’];
}else{
return false;
}
}

=============================================================

以上になります。第二段階のポイントはsave();ではなく、saveFields();関数で、

必要なデータやカラムを取得しているところとcheckHashアクションで保存前は、

削除フラグを立てず、保存した後に削除フラグをたてる(始めはfalseで、保存時にtrueにする)ところがポイントです。

Cakephp エラー対処法 warning: missing argument ~ 

warning: missing argument ~ というのは、

定義された引数と、呼び出す引数が違いますよというエラーです。

例えば、

 

function f_name ($x, $y) {
 echo $x . "ok";
 echo $y . "ok";
}

と定義して、呼び出すときに

f_name($y);

だとエラーになってしまいます。

こういうときは、初期値をにすればいいでしょう。

function name($x = null){
 if($y){
  処理1
 }else{
  処理2
 }
}

Cakephp Modelのテストケース作成

あるユーザーが職業選択ができて、そのラジオボタンを削除したり追加したりできるような仕様ががあった場合のテストケースを作成しました。そこでcakephp2のModelにtestSave()とtestDelete()を作成しました。

Fixtureに登録しているユーザーデータに基づいて記述してみました。

public function testSave(){

// もともとid=4まである、4件Fixtureに書いてある
$result = $this->MstJobType->find(‘count’);
$this->assertEquals(4, $result);

// idが4番まであったら、次に登録するデータは5番になるはず
// まだ登録していないので5番のデータが取れないチェック
$result = $this->MstJobType->find(‘first’, array(
‘conditions’ => array(
‘MstJobType.id’ => 5,
),
‘contain’ => false
));
$expected = array(); // 結果とれない!
$this->assertEquals($expected, $result);

// 5番になるデータを登録する
$update = array(
// MstJobTypeに登録するための項目(画面と同じだからadd.ctp/edit.ctpをチェック)
‘MstJobType’ => array(
‘name’ => ‘公務員’,
‘slug’ => ‘civilworker’,
‘deleted’ => 1
)
);
$this->MstJobType->create(); // 初期化(おまじない)
$this->MstJobType->save($update); // 保存

// 5番のデータが作成されたので、データが取れる
$result = $this->MstJobType->find(‘first’, array(
‘conditions’ => array(
‘MstJobType.id’ => 5,
),
‘contain’ => false
));
$expected = array(
‘MstJobType’ => array(
‘id’ => 5,
‘slug’ => ‘civilworker’,
‘deleted’ => true,
‘name’ => ‘公務員’,
)
);
unset($result[‘MstJobType’][‘created’]); // 作成時間:実行した時間が登録されちゃうと比較できないので、検索結果から消しておく
unset($result[‘MstJobType’][‘modified’]); // 更新時間:これも同じ
$this->assertEquals($expected, $result);

// テーブルの中身が1件増えたので5件になってる
$result = $this->MstJobType->find(‘count’);
$this->assertEquals(5, $result);
}

/**
* testDelete
* @return void
*/
public function testDelete() {
// 今あったものが無くなる(削除される)テスト
// 削除されていないデータがテーブルの中に2件ある(Fixtureに記載されているデータの件数)
$result = $this->MstJobType->find(‘count’, array(
‘conditions’ => array(
‘MstJobType.deleted’ => false
)
));
$this->assertEquals(2, $result);

// Fixtureに記載されているあるデータが取得できるかチェック
$result = $this->MstJobType->find(‘first’, array(
‘conditions’ => array(
‘MstJobType.id’ => 3,
)
));
$expected = array(
‘MstJobType’ => array(
‘id’ => 3,
‘name’ => ‘会社員’,
‘slug’ => ‘employee’,
‘created’ => ‘2015-02-22 15:35:03’,
‘modified’ => ‘2015-02-22 15:35:03’,
‘deleted’ => false
),
‘User’ => array()
);
$this->assertEquals($expected, $result);

// このもともとあった↑データを削除する
$this->MstJobType->id = 3;
$this->MstJobType->delete();

// 今削除されたものがちゃんと取得できなくなったかのチェック
// 最初に実行したfindと同じ条件で再度チェックする
$result = $this->MstJobType->find(‘first’, array(
‘conditions’ => array(
‘MstJobType.id’ => 3,
)
));
$expected = array(
‘MstJobType’ => array(
‘id’ => 3,
‘name’ => ‘会社員’,
‘slug’ => ‘employee’,
‘created’ => ‘2015-02-22 15:35:03’,
‘deleted’ => true
),
‘User’ => array()
);
unset($result[‘MstJobType’][‘modified’]); // 更新時間:削除されたときの実行時間が登録されてしまうので、消しておく
$this->assertEquals($expected, $result);

// 削除されていないデータは、テーブルの中に1件になった
$result = $this->MstJobType->find(‘count’, array(
‘conditions’ => array(
‘MstJobType.deleted’ => false
)
));
$this->assertEquals(1, $result);
}

【注意点】

*削除されていないデータ、つまりdeleted=>falseの数を変更すること。
*削除対象のデータに対して ’User’ => array();を追加することで、
その職業で登録されているユーザーデータも削除されるという感じで
必ず記述する(array()の中は何も書かなくていい)。

*実際に削除されたということを記述するにはdeleted=>falseから
deleted=>trueに変更して、現在の削除されていないデータ(deleted=>false)は
1件になったので$this->assertEquals(1, $result);と記述する。

テストケースの要点 Cakephp

テストケースは、開発したプログラミングに対して、意図しない動作をしないかを確認する作業です。

テストケースの書き方は

例えば

/Model/Articles.phpの
       * article名のみ取得する
public function getArticleName($article_id = null) {
$result = $this->find(‘first’, array(
‘conditions’ => array(
$this->alias.’.id’ => $article_id,
$this->alias.’.deleted’ => false,
),
‘fields’ => $this->alias.’.title’,
‘contain’ => array(),
));
return $result;
}

処理のテストケースを作成します。

===========================

補足

実行方法(teraterm)

・・・app]

全てのページを検証する場合

./Console/cake testsuite app AllTests

一つのページを検証する場合

./Console/cake testsuite app Model/Article

あるページの関数を検証する場合(debug(変数)等の中身おを調べたいとき)

./Console/cake testsuite app Model/Article –filter getArticleName(関数名)

==================================

検証する論理値(仮定しなければいけないこと)

実行する処理(今回は記事のタイトルを取得する)に対して、仮定することはいくつかあります。

①id(個人データ)があったら、そのタイトル名(Articleのtitle)を取得できるか

②削除済みのタイトルは取れない

③存在しないタイトルは取れない場合(削除されていない場合)

【実際のテストケース】

Model/Article.php

/**
* testGetTheAge method
*
* @return void
*/
public function testArticleName(){
// 存在しないタイトルは取れない
$result = $this->Article->getArticleName(99999999);
$compare = array(); //debug($result)
$this->assertEquals($compare, $result);
// 削除済みのタイトルは取れない
$result = $this->Article->getArticleName(6);
$compare = array();
$this->assertEquals($compare, $result);
// タイトルが取れる 
$result = $this->Article->getArticleName(3);
$compare = array(
‘Article’ => array(
‘title’ => ‘うぁーがんばろー’,
)
);
$this->assertEquals($compare, $result);
}

======================

【補足②】

始めに

@return void(->何も返さないよ) とか

@return array(->配列の返すよ)

など、返り値を設定しておきます。

*deletedの考え方

deleted = 削除済みのものを取ってくる

type P = false =>0、true=>1

*debug()関数に関して

debug()関数は取得したいデータを取ってきたい場合

実行したときにそのデータ処理が取得できます。

 

======================

Fixture(テストケースのデータ格納場所)の追加に関して

Fixtureに情報(データ)を格納したら、AllTestsをするとき、

そのときにでたエラーを修正していきます。

========================

このように、実行したい処理が何をしている処理なのか

(データを取得したいのか、削除したデータを取ってきたいのか、IF文で別々に処理しているのか、空の場合の処理なのか)

など、考えた上で、

テストケースは10パターンほど考えます。多ければ多いほどよいです。

このようにもし何かの不具合が見つかったら、何処が悪かったのかを検証できるので

基本的なことですがしっかりと見につけていけたらいいですね。

findメソッドの引数

findメソッドは、sqlでいうselect文にあたるメソッドです。その名の通りデータの検索を行います.  メソッドに引数を与えて,処理を色々と変えてきます。

【find関数の引数について】

第1引数

  • find(‘all’) : 条件に該当するデータ全てを取得します.
  • find(‘first’) : 条件に該当するデータの最初の1レコードを取得します.
  • find(‘list’) : 条件に該当するデータをidとラベルが対になった形で取得します.
  • find(‘count’) : 条件に該当するデータの件数を取得します.

*条件を指定しない場合は,これだけでも利用できます

第2引数

  • conditions : データの検索条件を指定します.すごくよく使うので後述します.
  • fields : どのフィールドのデータを取得するかを指定します.
  • order : ソートの仕方を指定します.
  • limit : データを取得する件数を指定します.
  • offset : データ検索を何件目から行うかを指定します.

*よく使うのはcondisions(where句に相当する), order(order by句に相当する),limit(limit句に相当する)の三つだと思います.

condisionsの書き方について

array(
‘conditions’ => array(
     ‘モデル名.id’ => 1
}
}
というような形で記述すれば良いです.
public function index(){
            $this->set(‘data’,$this->Board->find(‘first’,array(
                ‘conditions’ => array(‘Board.id’ => 48))
                ));
        }
という感じで記述するとidが48のものを取得します.find(‘first’)を使ってますが,idが48のデータは1つしかありえないので,firstで一件だけ取得する書き方の方が効率的です.
メインのfind関数以外にも、たくさんのコントローラーメソッドがあります。それらはまた次回にします。

CakePHP ~FormHelper~

FormHelperの説明を記載しておきます。これは、すばやくフォームを作成してくれるのでとても便利な機能です。

最初に使うメソッドは、create()です。

書き方は

FormHelper::create(string $model = null, array $options = array())

です。いろいろ書くとわけがわからなくなるので、今日はこのcreate()オプションについて説明します。

echo $this->Form->create('User', array('type' => 'get'));

create()には、多くのオプションがあります。

出力結果は、

<form id=”UserAddForm” method=”get” action=”/users/add”>

になります。

《オプション》

・【$options['type'] 】

 このキーは生成するフォームのタイプを指定します。 有効な値は ‘post’, ‘get’, ‘file’, ‘put’, ‘delete’ です。

・【$options[‘action’]】

このキーは現在のコントローラーにおいて、特定のアクションに 対してフォームデータを送り込むことができます。

【$options['url']】

現在のコントローラー以外にフォームデータを渡したい 場合、$options 配列の ‘url’ キーを使ってフォームアクションの URL を指定します。指定された URL は作成中の CakePHP アプリケーションに 対する相対値を指定できます。

今日は、ここまでですが、同時にinput要素を作る方法input()についても説明しなければいけませんが、こちらはまた書きたいと思います。

CakePHP コントローラーの使い方

CakePHPでは、Model-View-Controller(MVC)というアーキテクチャーを導入しています。

使い方ですが、、、

モデルはデータベースアクセスに関する機能ですから、データベースを使わなければ不要です。ビューは、テンプレートとして画面表示を作成しておくものですが、これも「PHPの関数で無理やり画面表示を書きだしてしまう」なら、なくても大丈夫です。

しかし、コントローラーに関しては【なし】で済ませることができません。コントローラーでページの処理を行うのですから。これがないと、そもそもページそのものが存在できません。したがって、まず最初は「コントローラーを作って、ページを表示する」ということからやっていくことにしましょう。

コントローラーは、CakePHPの「app」フォルダの中にある「Controller」というフォルダの中に作成します。ここにPHPのスクリプトファイル(拡張子が.phpのファイル)を用意しておくと、自動的にそれらをコントローラーのスクリプトだと認識します。

注意したいのは「そのためには、決められた形でファイル名を付けないといけない」という点です。また、CakePHPでは命名規則を非常に重視しています。名前を元にコントローラーの名前などを割りだすので、適当な名前をつけると理解してくれません。

 

アプリケーション名Controller.php

 

「アプリケーション名」というのは、作成する「MVC」がワンセットになったプログラムのかたまりのこと、と考えてください。

*大文字小文字までかっちり同じ名前でないとダメ!!ですよ!!

*キャメル記法=>複数の単語を一つのテキストにつなげたような名前の場合、各単語の最初の文字目だけを大文字にする

そして、

CakePHPには【命令規則】というものがあります。ここはしっかり理解する必要がありますので、

それは次の機会に・・・・

CakePHP:find関数;nullってなに?<IS NULL>と<NOT NULL>の書き方

初心者にはなかなか理解しづらい「null」。

そもそも「null」とは、

「NULLは特殊な値です.NULLは 「列名 = NULL」 や 「列名 <> NULL」 といった通常の比較演算子を用いた方法では検索することができません. NULLを対象として検索するにはIS NULL演算子,もしくはIS NOT NULL演算子を使用します.」

そして、

NULL値はデータが存在しないことを表す値です。大文字と小文字のどちらも使用できます。

NULLはデータが存在しないということなので、文字列における空文字”や数値における0とは異なります。

プログラムで使う変数は宣言をした時に領域が確保されます。

そのあと、変数が持っているアドレスが0.0.0.0の状態がnullです。

あ。これはちょっと広義的になってしまうので・・・・説明はここまでで・・・・

現在、CakePHPでプログラミングをしているので、

今回は

CakePHPのfind条件に「null」「not null」を使う方法を記述しておきます。

上記で記述したとおり、「NULLを対象として検索するにはIS NULL演算子,もしくはIS NOT NULL演算子」を使用すると書きました。これはそれぞれ書き方が違います。

<IS NULL>の場合

$data = $this->Model->find( 'all',
    array(
        'conditions' => array('Model.id' => NULL),
        'fields'     => null,
        'order'      => null,
        'recursive'  => 1,
    )
);

SQLでいうところの、IS NULL の方法。
単純に、 conditions に配列で指定するだけです。

これで WHERE Model.id IS NULL というSQLとなります。

<NOT NULL>の場合

NOT NULL の場合は、ちょっとだけひねって、”NOT”の2次元配列で条件を作成。

$data = $this->Model->find( 'all',
    array(
        'conditions' => array(
            'NOT' => array(
                'Model.id' => NULL)
        ),
        'fields'     => null,
        'order'      => null,
        'recursive'  => 1,
    )
);

カラムにNULL値を持つ事が出来ないように設定する方法になり、

これで、WHERE Model.id IS NOT NULL というSQLとなります。

とりあえずここまでにしますのが、

あと基本的に書き方が同じなfind条件での「IN」、「NOT IN」演算子の使い方については次回にしたいと思います。

 

それでは。。

CakePHP find関数について

findメソッドは、$this->モデル名->find(‘検索タイプ’,’オプション値’);でモデルからデータを取り出します。

検索タイプは、標準で下記の値が用意されています。

1、all  条件に合致する全てのデータを取り出します。

2、first 最初に見つかったデータのみを取り出します。

3、 list 指定したフィールドのデータをリスト化して取り出します。

4、 threaded  そのレコードの親子関係を解析し、子レコードを階層で取得することが出来ます。

5、 neighbours 該当レコードの隣り合ったレコードの情報を取得できます。連想配列で『prev』キーの値は該当レコードの前のレコード、『next』には後のレコードが格納されます。

 

他には オプション値 にもいくつかありますが、それはのちほど・・・