【CakePHP Core : ORM】TableRegistry について

本記事は、[Fusic Advent Calendar その２](https://qiita.com/advent-calendar/2019/fusic-2)の20日目の記事です。


## はじめに
CakePHP Coreを少しずつ読んで整理しています。
簡単に使った機能が実際にはどう作られたかをコードを見ながら勉強しています。 
弊社内にはTamelで情報共有やっていますが、そこに書いているのを皆さんにも共有しようと思って書きました。


## 概要
Cake\ORM\TableRegistryはcakephp 3.0.0から追加されました。
TableRegistryはテーブルをインスタンスでセーブし、それをまた提供してくれる役割を果たしています。また生成した全てのテーブルのインスタンスたちはTableRegistryにまとめって管理しています。
※ 最近にはTableLocatorを利用して、テーブルのインスタンスや設定などをまとめて管理しています。  

テーブルのインスタンスを生成する前、テーブルごとにConfigを設定する必要があります。サービスが起動し、初めてテーブルのインスタンスを生成する時、設定したConfigの内容を基にインスタンスが生成されるからです。 
※もしテーブルのインスタンスが生成された後、configの設定を修正したら、修正された部分は自動に反映されないので別の処理が必要になります。

```
TableRegistry::getTableLocator()->setConfig($alias, $config(options));

// Prior to 3.6.0
TableRegistry::config('Users', ['table' => 'my_users']);
```
TableRegistryは主にテーブル情報を持ってきて使います。
下の例通りすると、テーブル情報持ってきて使えます。

```
$table = TableRegistry::getTableLocator()->get('Users', $config);
```
他の機能は下の参考しましょう。

## 構成
**1) property**

```
protected static $_locator;
protected static $defaultLocatorClass = 'Cake\ORM\Locator\TableLocator';
```

**2) method**

```
public static function locator(LocatorInterface $locator = null) {};
public static function getTableLocator() {};
public static function setTableLocator(LocatorInterface $tableLocator) {};
public static function config($alias = null, $options = null) {};
public static function get($alias, array $option = []) {};
public static function exists($alias) {};
public static function set($alias, Table $object) {};
public static function remove($alias) {};
public static function clear() {};
public static function __callStatic($name, $arguments) {};
```
## 機能の 説明
**説明を始める前に**
※ 3.6.0以降からTableRegistyのメソッドのほとんどの機能がTableLocator に委任されています。それで今TableRegistyで実際使われるメソッドは `getTableLocator()` と `setTableLocator(LocatorInterface $tableLocator)`  くらいと思います。  
もしTableRegistryの内部の動きを詳しく理解したいならTableRegistryよりTableLocatorを見るのがいいと思います。現在のTableRegistryはほどんどがdeprecationWaringのメッセージを出した後、TableLocatorをまた呼んで処理しています。
 
![dd.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/390132/643f6be7-88c6-c0f7-c839-c3220a0f3239.jpeg)
↑こんな感じです。

**説明**
**1) property**
`protected static $_locator;`
: TableLocatorインスタンスを持ってる変数です。    
`protected static $defaultLocatorClass = 'Cake\ORM\Locator\TableLocator';` 
:TableLocator Classファイルの位置を持っています。
カスタマイズしたTableLocatorを別に用意しないとこれを使ってTableLocatorインスタンスを作ります。  

**2) method**

 ```
public static function getTableLocator() {};
public static function setTableLocator(LocatorInterface $tableLocator) {};
```
上のメソッドはsingleton patternで作られています。singleton patternはSW設計パターンの一種です。
singleton patternはインスタンスをただ一つだけ作れるように設計されているし、インスタンスを生成した後からは生成したインスタンスを共有して機能を提供するように設計されてるパターンです。
 
テーブルのインスタンスたちをまとめて管理するTableLocatorインスタンスは複数のインスタンスが要らないのでそう設計されているとおもいます。
逆にテーブルのインスタンスたちを管理してるTableLocatorが複数あるのが内部の設定もばらばらになるかもしれないし、管理しにくいと思いますね。  
一応 singleton patternの特徴としてインスタンスを一つだけ生成して管理するので、Memoryの節約の効果もあると言いますが、ここにはそんなに影響はないと思います。  


```
public static function config($alias = null, $options = null) {};
: テーブルのインスタンスの設定を変更してくれます。

public static function get($alias, array $option = []) {};
: TableRegistryから欲しいテーブルのインスタンスをもらう時使います。

public static function exists($alias) {};
: TableRegistryにテーブルインスタンスがあるかどうかを確認する時使います。

public static function set($alias, Table $object) {};
: TableRegistryにテーブルのインスタンスを追加する時使います。

public static function remove($alias) {};
: TableRegistryで管理している特定のテーブルインスタンスを削除する時使います。

public static function clear() {};
: TableRegistryの内容全てを消すとき使います。
```
上のメソッドは3.6.0以前のバージョンまでは使ってもいいですが 3.6.0からはTableLocatorを利用して使うことをおすすめしています。