PHP フレームワーク DbRepository.php 作成

2018年5月8日

みなさんこんにちは!タカモリです。

今日も引き続きデータベース関連のクラスということで、今回はDbRepositoryクラスっていうのを作っていきたいと思います。

このクラスでは、前回のDbManagerクラスで指定したデータベースに、DbRepositoryクラスの子クラスから受け取ったINSERT文やSELECT文などの命令文を実行するという処理をやっていきます。なのでこのクラスは抽象クラスです。

抽象クラスとは、子クラスがないとインスタンス化することができないクラスのことで、必ず子クラスを作成しなければならないクラスです。

この場合抽象クラスのことを親クラスという言い方をするらしいですね。親クラスと子クラスの役割分担としては、大体どの場面でも使う処理については、親クラスに記載しておき、その場面によって違う処理については子クラスで定義する。というような形です。

具体的には、例えばこのフレームワークの場合、後に作成する掲示板アプリにおいて各ページに対応した○○Repositoryクラスというのをモデルとしてそれぞれ作成するのですが、そのページによってデータベースに対して行いたい命令文っていうのは変わってきますよね。

このページでは、ユーザーが入力したものをデータベースに保存したい!であったり、逆にこのページでは、データベースに入っているデータを一覧として表示させたい!といった具合です。

この場合、データベースに入力するにはINSERT文を、データベースからデータベースを取得するにはSELECT文を使用することなるのですが、データベースにクエリを発行する点というのは全く同じです。

なので、データベースに命令文を発行するという処理を、親クラスであるこのDbRepositoryクラスに定義し、子クラスには、INSERT文やSELECT文を親クラスに渡す処理というのをそれぞれ定義しています。渡す処理といっても子クラスでは親クラスのメソッドが使用できますので、そのメソッドの引数に命令文と、入れたいデータの内容や抜き取りたいデータを引数で渡すだけです。

 

というわけで!今回のsrcがこちら!

これで全部!今回のクラスは前回のDbManagerクラスより短いのでかなり気楽だ!

というわけでさっそくコンストラクタから!

・__construct()メソッド

前回話したかもしれないが、コンストラクタはこのクラスがインスタンス化された時点で実行されるメソッドだ!ただし、このクラスは抽象クラスなのでこのクラスをそのままインスタンス化することはできないので、このクラスの子クラスがインスタンス化された時点で実行されることになる!

インスタンス化されるタイミングについては前回の記事を読んでほしい!

コンストラクタの引数$conにはDbManagerクラスで指定されたデータベースでのPDOのインスタンスが入る。これをそのまま次のsetConnextion()メソッドに引数として渡す。

・setConnection()メソッド

このメソッドでは上述したコンストラクタから受け取った値をプロパティ$conに代入する。

・execute()メソッド

このメソッドが今回のクラスで一番の肝となるであろうか。executeとは調べてみると「実行」という意味らしい。このメソッドには引数に2つの値を引き受けることができるようになっており、第一引数には、命令文、第二引数には値が入るようになっている。

これはパーフェクトphpのものをそのまま流用するが、具体的な引数はこのように指定される。

これは子クラスのメソッドの処理部分なのだが、execute()メソッドにこのように引数で渡される。

第一引数の$splでは、INSERT文を用意する。

INSERT INTOでは、user(user_name, password, created_at)のように、データベースのテーブル名とカラムを指定し、VALUESでは:コロンから始まるプレースホルダと呼ばれる変数のようなものを用意する。

なおプレースホルダとは準備済みという意味らしい

このプレースホルダは値が変わってもかまわないので何度でも使えるようになっている。

第二引数のarray()では、プレースホルダに対して実際に入れる値を用意する。この最後の$nowについては今回は関係がないので割愛するが、要は時間をcreated_atに代入するということだ。

ここで話をexecute()メソッドに戻すが、まず引数で受け取った命令文$sqlについてはprepareに引数として渡す。

このprepara()メソッドでの戻り値はPDOステートメントクラスのインスタンスらしい。

仕組みについては正直よくわからない。それはさておきそれを$stmtに代入しPDOステートメントクラスのインスタンスの、execute()メソッドに値を引数として渡すと、これで実際に命令文がデータベースに渡されるわけだ。

このprepara()メソッドとexecute()メソッドを使用した方法?のことをプリペアドステートメントというらしい。

この方法を利用すると、プレースホルダに入る値がエスケープされて文字列に変わる為、セキュリティ向上に繋がるということだ。

なおこのメソッドでは戻り値でPDOステートメントクラスのインスタンスを返すようになっている。

・fetch()メソッド/fetchAll()メソッド

INSERET文の場合はデータの追加のみなのでどのデータをどのように入れようが、値で自由に決めれるわけなのだが、データの取得の場合は、レコード一行の取得なのか、テーブルまるごと取得するのかなど、取得方法が異なる場合があり、それに対応するのがこの2つのメソッドだ。

まずは、ここに引数となる $sql $params の値を調べる為、先ほどと同様に子クラスをのぞいてみることにする。

これは、fetch()メソッドのものであるが、先ほどのINSERT文とほぼ同じである。$sqlにはINSERTの代わりにSELECTが呼ばれており、user_nameのカラムが指定されている。

ではfetch()メソッドに戻って、子クラスの$user_nameにタカモリという値が入っていたとすると先ほど上で話したexecute()メソッドでは、SELECT文でタカモリという行がリソース型で取得されているPDOのインスタンスを返すわけだが、これに対してfetch()メソッドではfetch(PDO::FETCH_ASSOC)メソッドを、fetchAllメソッドではfetchAll(PDO::FETCH_ASSOC)メソッドを実行する。

すると、先ほどはリソース型で取得されていたタカモリのデータが、連想配列で取得できるようになるわけだ。

というわけで、これにて今回のクラスはこれでおしまいだ!俺の知識不足で意味わからないところもあるかもしれないが、これからもっと勉強して知識を増やしていこうと思うので、応援よろしくお願いします!!