#10 データベース検索 -where-

今回からデータベースの検索を行っていく。

まず Controller から作成する。

「Heroes」コントローラーに「find」アクションを追記

「HeroesController」に、「find」アクションを追加する。

■場所
\htdocs\chococake\src\Controller
■ファイル名
HeroesController.php

<?php
namespace App\Controller;

use App\Controller\AppController;

/**
* 
*/
class HeroesController extends AppController
{
  public function add()
  {
    if ($this->request->is('post')) {
      $hero = $this->Heroes->newEntity();
      $hero = $this->Heroes->patchEntity($hero, $this->request->data);

      if ($this->Heroes->save($hero)) {
        return $this->redirect(['action' => 'index']);
      }
    }
  }

  public function index()
  {
    $this->set('heroes', $this->Heroes->find('all'));
  }

  public function edit($id = null)
  {
    $hero = $this->Heroes->get($id);
    if ($this->request->is(['post', 'put'])) {
      $hero = $this->Heroes->patchEntity($hero, $this->request->data);
      if ($this->Heroes->save($hero)) {
        return $this->redirect(['action' => 'index']);
      }
    } else {
      $this->set('hero', $hero);
    }
  }

  public function delete($id = null)
  {
    $hero = $this->Heroes->get($id);
    if ($this->request->is(['post', 'put'])) {
      if ($this->Heroes->delete($hero)) {
        return $this->redirect(['action' => 'index']);
      }
    } else {
      $this->set('hero', $hero);
    }
  }

  // 今回追記分:findアクション
  public function find()
  {
    $heroes = [];
    if ($this->request->is('post')) {
      $find = $this->request->data['find'];
      $heroes = $this->Heroes->find()
        ->where(['name like ' => '%' . $find . '%']);
    }
    $this->set('heroes', $heroes);
  }

}

解説

$heroes = [];

heroes という変数を配列で準備。

if ($this->request->is('post')) {

is メソッドで「POSTされていたら」という条件を設定。

$find = $this->request->data['find'];

data メソッドで post された値を変数 $find に格納。

$heroes = $this->Heroes->find()

以前、HeroesController に index アクション追加した際、find(‘all’) ですべてのエンティティー表示させた。

find はデータ検索を行うメソッド。

find を使用することで Query オブジェクトを作成する。Query を使用して、複雑な検索を行うことができる。

->where(['name like ' => '%' . $find . '%']);

where メソッドは以下の形式で使用する。

->where( 条件文, 値 );

$find にフォームで送信された検索ワードが格納されるので、今回の条件文は以下のようになる。

name like '%検索ワード%'

「検索ワードを name カラムに含むレコードをすべて検索する」という意味となる。

「like」は LIKE 検索と呼ばれ、テキストを含む検索をする際に用いられる。

「%」をつけることで、「検索ワード%」が検索ワードで始まるもの、「%検索ワード」で検索ワードで終わるものという意味。

$this->set('heroes', $heroes);

$heroes に格納された検索結果を View に渡している。

ビューテンプレートのファイル作成

ビューテンプレートファイルに検索画面を表示させる記述をする。

■場所
\htdocs\chococake\src\Template\Heroes
■ファイル名
find.ctp

<h1>検索</h1>

<!-- フォーム開始タグ -->
<?= $this->Form->create() ?>

<!-- フォームの入力内容をグループ化するタグ -->
<fieldset>
  <!-- 各入力フィールドのinputタグ -->
  <?= $this->Form->input('find') ?>
</fieldset>

<!-- 検索ボタンのタグ -->
<?= $this->Form->button('検索') ?>

<!-- フォーム終了タグ -->
<?= $this->Form->end() ?>

<!-- 検索結果表示部分 -->
<table>
  <thead>
    <tr>
      <th>id</th>
      <th>名前</th>
      <th>超人強度</th>
      <th>出身地</th>
    </tr>
  </thead>
  <tbody>
  <?php foreach ($heroes as $hero): ?>
    <tr>
      <td><?= h($hero->id) ?></td>
      <td><?= h($hero->name) ?></td>
      <td><?= h($hero->power) ?></td>
      <td><?= h($hero->country) ?></td>
    </tr>
  <?php endforeach; ?>
  </tbody>
</table>

解説

<?= $this->Form->input('find') ?>

find という検索ワードを入力用の input を1つ準備。

<?php foreach ($heroes as $hero): ?>

上記 Controller で検索結果が格納された heroes を View に渡していた。

その $heroes から順に値を取り出し、検索されたエンティティーの内容を繰り返して表示させる。

以下URLにアクセスすると検索画面が表示される。
http://localhost/chococake/heroes/find

検索画面が表示される。

前回、データを削除したため、データを追加する。

csv ファイルをダウンロードし、データベースにインポートする。

インポート後、<input> を空欄で「検索」ボタンを押下すると、以下のように全件のデータが表示される。

CakePHP の一覧