Rodhos Soft

備忘録を兼ねた技術的なメモです。Rofhos SoftではiOSアプリ開発を中心としてAndroid, Webサービス等の開発を承っております。まずはご相談下さい。

データベース操作

レコード追加

テンプレー側にフォームを用意

<?= $this->Form->Create($entity, ['url'=>['action'=>'addRecord']]) ?>
<fieldset>
<?= $this->Form->text("name") ?>
<?= $this->Form->text("title") ?>
<?= $this->Form->textarea("content") ?>
</fieldset>
<?= $this->Form->button("送信") ?>
<?= $this->Form->end() ?>

コントローラにaddRecord追加

<?php

namespace App\Controller;

class BoardsController extends AppController {
  public function index() {
    $data = $this->Boards->find('all');
    $this->set('data', $data);
    $this->set('entity', $this->Boards->newEntity());/* 空のものをセット*/
  }

  public function addRecord() {
    if ($this->request->is('post')) {
      $board = $this->Boards->newEntity($this->request->data);
      $this->Boards->save($board);
    }

    return $this->redirect(['action' => 'index']);
  }
}

?>

request_dataの中身確認

中身をprintしてみる

  public function addRecord() {
    if ($this->request->is('post')) {
      $board = $this->Boards->newEntity($this->request->data);
      $this->Boards->save($board);
    }

    $this->autoRender = false;
    echo "<pre>";
    print_r($this->request->data);
    echo "</pre>";

//    return $this->redirect(['action' => 'index']);
  }

結果、
このような連想配列が入っていることがわかった。

Array
(
    [name] => hoge
    [title] => hello
    [content] => I have a pen.
)

レコードの検索

特定レコード表示をfindを使って実装する。index.ctpに以下を追加

<h2>検索</h2>
<?= $this->Form->Create($entity, ['url'=>['action'=>'index']]) ?>
<fieldset>
<?= $this->Form->text("id") ?>
</fieldset>
<?= $this->Form->button("送信") ?>
<?= $this->Form->end() ?>

コントローラのindexを修正

  public function index() {

    $this->set('entity', $this->Boards->newEntity());

    if ($this->request->is('post')) {
      $data = $this->Boards->find('all',
        ['conditions' => ['id' => $this->request->data['id']]]
      );
    } else {
      $data = $this->Boards->find('all');
    }
    $this->set('data', $data);
  }

find

第1引数

all 全レコード
list レコードのリスト(表示用のフィールドだけ入っている)
threaded スレッド状レコード(ネストされたエンティティを扱う際に必要)

第2引数

conditions 条件設定
fields 取得するフィールド名を配列として用意
recursive 再帰的に取得する深度
order 取得順
limit 上限
offset 取得開始位置
page 取得ページ数

like 検索

テンプレートをidからtitleに書き換え

<h2>検索</h2>
<?= $this->Form->Create($entity, ['url'=>['action'=>'index']]) ?>
<fieldset>
<?= $this->Form->text("name") ?>
</fieldset>
<?= $this->Form->button("送信") ?>
<?= $this->Form->end() ?>

コントローラもlikeを使ったものにかきかえ

  public function index() {

    $this->set('entity', $this->Boards->newEntity());

    if ($this->request->is('post')) {
      $data = $this->Boards->find('all',
        ['conditions' =>
          ['name like' => "%{$this->request->data['name']}%"]
        ]
      );
    } else {
      $data = $this->Boards->find('all');
    }
    $this->set('data', $data);
  }

これでその文字を含むnameの検索になった。

findで取得したQueryを調べる。

コントローラにindexを生やして出力させてみた。

public function findtest() {
    $query = $this->Boards->find('all');

    $this->autoRender = false;
    echo "<div>";
    echo "数";
    echo "<pre>";
    print_r($query->count());
    echo "</pre>";
    echo "</div>";

    echo "<div>";
    echo "first";
    echo "<pre>";
    print_r($query->first()->toArray());
    echo "</pre>";
    echo "</div>";

    echo "<div>";
    echo "last";
    echo "<pre>";
    print_r($query->last()->toArray());
    echo "</pre>";
    echo "</div>";

    echo "<div>";
    echo "max_id";
    echo "<pre>";
    print_r($query->max('id'));
    echo "</pre>";
    echo "</div>";

    echo "<div>";
    echo "min_id";
    echo "<pre>";
    print_r($query->min('id'));
    echo "</pre>";
    echo "</div>";


  }

結果は

数
4
first
Array
(
    [id] => 1
    [name] => poi
    [title] => asdasd
    [content] => fawefsfawefaewf
)
last
Array
(
    [id] => 1
    [name] => poi
    [title] => asdasd
    [content] => fawefsfawefaewf
)
max_id
Cake\ORM\Entity Object
(
    [id] => 1
    [name] => poi
    [title] => asdasd
    [content] => fawefsfawefaewf
    [[new]] => 
    [[accessible]] => Array
        (
            [*] => 1
        )

    [[dirty]] => Array
        (
        )

    [[original]] => Array
        (
        )

    [[virtual]] => Array
        (
        )

    [[errors]] => Array
        (
        )

    [[invalid]] => Array
        (
        )

    [[repository]] => Boards
)
min_id
Cake\ORM\Entity Object
(
    [id] => 1
    [name] => poi
    [title] => asdasd
    [content] => fawefsfawefaewf
    [[new]] => 
    [[accessible]] => Array
        (
            [*] => 1
        )

    [[dirty]] => Array
        (
        )

    [[original]] => Array
        (
        )

    [[virtual]] => Array
        (
        )

    [[errors]] => Array
        (
        )

    [[invalid]] => Array
        (
        )

    [[repository]] => Boards
)

firstとlastがおなじになっている。
これは$data->$first とやったことでqueryの内容が変わってしまったことを意味する。

そうならないようにすると(取り直した)

  public function findtest() {
    $query = $this->Boards->find('all');
    $count = $query->count();
    $max_id = $query->max('id');
    $min_id = $query->min('id');

    $first = $this->Boards->find('all')->first();
    $last = $this->Boards->find('all')->last();

    $this->autoRender = false;
    echo "<div>";
    echo "数";
    echo "<pre>";
    print_r($count);
    echo "</pre>";
    echo "</div>";

    echo "<div>";
    echo "first";
    echo "<pre>";
    print_r($first->toArray());
    echo "</pre>";
    echo "</div>";

    echo "<div>";
    echo "last";
    echo "<pre>";
    print_r($last->toArray());
    echo "</pre>";
    echo "</div>";

    echo "<div>";
    echo "max_id";
    echo "<pre>";
    print_r($max_id);
    echo "</pre>";
    echo "</div>";

    echo "<div>";
    echo "min_id";
    echo "<pre>";
    print_r($min_id);
    echo "</pre>";
    echo "</div>";


  }

確かに正常に検索結果がでている。

数
4
first
Array
(
    [id] => 1
    [name] => poi
    [title] => asdasd
    [content] => fawefsfawefaewf
)
last
Array
(
    [id] => 4
    [name] => hoge
    [title] => hello
    [content] => I have a pen.
)
max_id
Cake\ORM\Entity Object
(
    [id] => 4
    [name] => hoge
    [title] => hello
    [content] => I have a pen.
    [[new]] => 
    [[accessible]] => Array
        (
            [*] => 1
        )

    [[dirty]] => Array
        (
        )

    [[original]] => Array
        (
        )

    [[virtual]] => Array
        (
        )

    [[errors]] => Array
        (
        )

    [[invalid]] => Array
        (
        )

    [[repository]] => Boards
)
min_id
Cake\ORM\Entity Object
(
    [id] => 1
    [name] => poi
    [title] => asdasd
    [content] => fawefsfawefaewf
    [[new]] => 
    [[accessible]] => Array
        (
            [*] => 1
        )

    [[dirty]] => Array
        (
        )

    [[original]] => Array
        (
        )

    [[virtual]] => Array
        (
        )

    [[errors]] => Array
        (
        )

    [[invalid]] => Array
        (
        )

    [[repository]] => Boards
)

昇順、降順

orderを使う。

  public function findtest() {
    $query = $this->Boards->find('all');
    $query->order(['name' => 'ASC', 'id' => 'DESC']);


    $this->autoRender = false;
    echo "<div>";
    echo "<pre>";
    print_r($query->toArray());
    echo "</pre>";
    echo "</div>";

  }

動的FInderで検索 findBy___()

以下のようにキャメル記法でフィールド名をByの後に書く。

  public function findtest() {
    $query = $this->Boards->findById('1');

    $this->autoRender = false;
    echo "<div>";
    echo "<pre>";
    print_r($query->toArray());
    echo "</pre>";
    echo "</div>";

  }

2つの条件をorで結びたい場合

    $query = $this->Boards->findByIdOrName('1',"poi");

andも同様。

削除

<h2>削除</h2>
<?= $this->Form->Create($entity, ['url'=>['action'=>'deleteRecord']]) ?>
<fieldset>
<?= $this->Form->text("id") ?>
</fieldset>
<?= $this->Form->button("送信") ?>
<?= $this->Form->end() ?>


コントローラに

use \Exception;
use Cake\Log\Log;

を追加しつつ、以下を追加

  public function deleteRecord() {
    if ($this->request->is('post')) {
      try {
        $entity = $this->Boards->get($this->request->data['id']);
        $this->Boards->delete($entity);
      } catch (Exception $e) {
        Log::write('debug', $e->getMessage());
      }
    }
    $this->redirect(['action' => 'index']);
  }

IDがプライマリーキーなのでエンティティがgetで得られる。
Logはレベルを指定して出力できる。

debug デバッグ
info 情報
notice 注意
warning 警告
error 例外
critical 危険
alert 直ちに対処すべき
emergency システム停止級

条件の範囲を消したい時、例えばnameがhogeのものすべてを消す場合、

$this->Boards->deleteAll(['name' => 'hoge']);

レコードの更新

saveで良い。

index側

<h2>編集</h2>
<?=$this->Form->create($entity,
['url'=>['action'=>'editRecord']]) ?>
<fieldset>
  <p><?= 'ID =' . $entity->id ?></p>
  <?=$this->Form->hidden("id") ?>
  <?=$this->Form->text("name") ?>
  <?=$this->Form->text("title") ?>
  <?=$this->Form->text("content") ?>
</fieldset>
<?=$this->Form->button("送信") ?>
<?=$this->Form->end() ?>

コントローラ側

  public function index($id = null) {

    $this->set('entity', $this->Boards->newEntity());

    if ($id != null) {
      try {
        $entity = $this->Boards->get($id);
        $this->set('entity', $entity);
      } catch (Exception $e){
        Log::write('debug', $e->getMessage());
      }
    }

    $data = $this->Boards->find('all')->order(['id'=>'DESC']);
    $this->set('data', $data->toArray());
  }

  public function editRecord() {

// putに注意
    if ($this->request->is('put')) {
      try {
        $entity = $this->Boards->get($this->request->data['id']);
        $this->Boards->patchEntity($entity, $this->request->data);
        $this->Boards->save($entity);
      } catch (Exception $e) {
        Log::write('debug', $e->getMessage());
      }
    }
    $this->redirect(['action' => 'index']);
  }

これでboards/index/1のようにアクセスして編集できる。



PHPフレームワーク CakePHP 3入門