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 エラー対処法 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』には後のレコードが格納されます。

 

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

cakePHPの初期設定をおぼえよう

まず、cakephpって何なの?

cakePHPとはwebアプリケーション(Webの仕組み・機能を使ったインターネット、もしくはイントラネット上で提供されるアプリケーションソフトウェア)
です。基本的に初心者が学ぶ、HTML,CSS,Javascript,PHPのあとに学ぶのかなと思います。今回は、CakePHPで始めに覚えておくべき用語を紹介しておきます。

<覚えておくべき用語>
cakePHPをcakephp.org からダウンロードしたあと下記のようなフォルダが落とされております。

ここの appフォルダの中にあります Model,View,Controllerフォルダはそれぞれデータ、見た目、かけはしを意味するフォルダとなります。

これらの基本的なことを覚えたあとにCOC(Convention over Configurationの意)を学びます。これは設定ファイルや作成したり、規約(書き方のルールなど)を事前に作成しておくことです。

使い始める前に、いくつか設定しなければいけません。

<tmpフォルダから書き込み権限をあたえる>

CakePHPは一時ファイル等を/app/tmpディレクトリに作成するため、tmpディレクトリ以下に書き込み権限を与えておく必要があります。

ssh等でシェルを利用可能であれば下記のようにchmodコマンドを利用し,
/app/tmpディレクトリ以下のパーミッションを707に変更します。

# chmod -R 707 /var/www/html/cakephp/app/tmp

シェルが利用できない場合はFFFTP等のFTPクライアントを利用してパーミッションを変更してください。

 

とりあえず、ここまで覚えていれば大丈夫でしょう!

次は、開発手順を書いていきたいと思います。