どーも!marusukeです!
前回の記事(【Laminas】リポジトリクラスのファクトリを作る!)の続きで、リポジトリクラスのfindAllPostsメソッドの内容を実装していきます!
以下の3つの手順で進めていきます。
- コンストラクターにAdapterInterfaceを注入する準備をする
- メソッドにクエリなどを実装する
- DBから取得したデータを使えるものにする
コンストラクターにAdapterInterfaceを注入する準備をする
/module/Blog/src/Model/LaminasDbSqlRepository.phpに以下の内容を実装します。
namespace Blog\Model;
use InvalidArgumentException;
use RuntimeException;
use Laminas\Db\Adapter\AdapterInterface;
use Laminas\Db\Sql\Sql;
class LaminasDbSqlRepository implements PostRepositoryInterface
{
/**
* @var AdapterInterface
*/
private $db;
/**
* @param AdapterInterface $db
*/
public function __construct(AdapterInterface $db)
{
$this->db = $db;
}
/**
* {@inheritDoc}
*/
public function findAllPosts()
{
}
/**
* {@inheritDoc}
* @throws InvalidArgumentException
* @throw RuntimeException
*/
public function findPost($id)
{
}
}
簡単に説明すると、use文でLaminas\Db\Adapter\AdapterInterfaceを呼び出し、__construct(AdapterInterface $db)部分で、コンストラクターに注入するために型の制限をかけています。$this->db = $db;でこのクラス内で、$this->dbを呼び出し、利用可能な状態にしています。
$this->dbは、後に出てくるSqlインスタンスの引数になります。
これで、コンストラクターにAdapterInterfaceを注入する準備が出来ました!
メソッドにクエリなどを実装する
次は、LaminasDbSqlRepositoryクラス内のメソッドに、SQLiteからデータを取得するためのクエリを実装します。
- Sqlコンポーネントを使い、クエリ部分を実装する。
- 取得した結果を、ハイドレーターで配列からオブジェクトに変換するインスタンスを作る。
- 作成したインスタンスに取得した結果を注入し、オブジェクトにする。
- use文で、ハイドレーターなど必要なコンポーネントを呼び込む。
findAllPostsメソッドの内容は以下になります。
public function findAllPosts()
{
// 1. Sqlコンポーネントを使い、クエリ部分を実装する。
$sql = new Sql($this->db);
$select = $sql->select('posts');
$statement = $sql->prepareStatementForSqlObject($select);
$result = $statement->execute();
// $resultが正しくない型の時、空の配列を返す。
if (! $result instanceof ResultInterface || ! $result->isQueryResult()) {
return [];
}
// 2. ハイドレーターで配列からオブジェクトに変換するインスタンスを作る。
$resultSet = new HydratingResultSet(
new ReflectionHydrator(),
new Post('', '')
);
// 3. 作成したインスタンスに取得した結果を注入し、オブジェクトにする。
$resultSet->initialize($result);
return $resultSet;
}
上から説明していきます。
1、Sqlコンポーネントを使い、クエリ部分を実装する。
PDOの形ですが、簡単に説明します。
$sql = new Sql($this->db);について
Sqlコンポーネントは、引数にDBを接続するための設定情報($this->db)を必要とします。
$select = $sql->select(‘posts’);について
今回は、selectオブジェクトを作成し、postsテーブル内の全データを取得します。引数はテーブル名です。
$statement = $sql->prepareStatementForSqlObject($select);について
selectオブジェクトをprepareStatementForSqlObjectに注入し、prepareオブジェクトを作成します。
$result = $statement->execute();について
prepareオブジェクトを実行します。
2. ハイドレーターで配列からオブジェクトに変換するインスタンスを作る。
$resultSet = new HydratingResultSet();について
HydratingResultSetは、第一引数にハイドレーターを、第二引数に空のPostオブジェクトを渡すことで、データベースから取得した$resultをPostオブジェクト型に変換するインスタンスを作ることが出来ます。
ちなみに$resultは、データベースから取得したデータを配列で格納しており、その配列内からデータを取り出すためには、resultsetというインスタンスが必要になります。(今回はHydratingResultSet)
3. 作成したインスタンスに取得した結果を注入し、オブジェクトにする。
$resultSet->initialize($result);について
HydratingResultSetのinitializeメソッドに$result(データベースから取得した配列データ)を注入し、view側に$resultSetを渡します。
4. use文で、必要なコンポーネントを呼び込む。
use Laminas\Hydrator\ReflectionHydrator;
use Laminas\Db\ResultSet\HydratingResultSet;
上記2つをLaminasDbSqlRepository.phpのuse文がまとまって記載されている箇所に追加します。
これで、findAllPostsメソッドは、データベースから全ての投稿を取得することができるようになりました。
現時点での、LaminasDbSqlRepository.phpの内容です。
namespace Blog\Model;
use InvalidArgumentException;
use RuntimeException;
use Laminas\Db\Adapter\AdapterInterface;
use Laminas\Db\Sql\Sql;
use Laminas\Hydrator\ReflectionHydrator;
use Laminas\Db\ResultSet\HydratingResultSet;
class LaminasDbSqlRepository implements PostRepositoryInterface
{
/**
* @var AdapterInterface
*/
private $db;
/**
* @param AdapterInterface $db
*/
public function __construct(AdapterInterface $db)
{
$this->db = $db;
}
/**
* {@inheritDoc}
*/
public function findAllPosts()
{
$sql = new Sql($this->db);
$select = $sql->select('posts');
$statement = $sql->prepareStatementForSqlObject($select);
$result = $statement->execute();
if (! $result instanceof ResultInterface ||
! $result->isQueryResult()) {
return [];
}
$resultSet = new HydratingResultSet(
new ReflectionHydrator(),
new Post('', '')
);
$resultSet->initialize($result);
return $resultSet;
}
/**
* {@inheritDoc}
* @throws InvalidArgumentException
* @throw RuntimeException
*/
public function findPost($id)
{
}
}
これで、findAllPostsメソッドが完成しました!
お疲れ様でした!次は、このリポジトリのリファクタリングと、findPostメソッドの実装をしていきます!
コメント