ActiveRecordパターンを実装しようとしています。
オブジェクトの永続性におけるアプローチは、すべてのサブクラスが拡張する共通の祖先クラスを提供することBasicEntity
です。これにより、特定のデータスキーマに基づいてクエリが構築されます。
class BasicEntity
{
protected $tablename;
protected $schema;
public function update()
{
$fields = "";
$placeholders = "";
foreach($this -> schema as $field => $type)
{
// you join the fields here to get something like ('username', 'email', 'enabled', 'createdAt', 'password')
// then you write your PDO statement providing placeholders like (:?, :?, :?, :?, :?)
// you'll have to bind parameters based on their $type [int, string, date]
}
$query = sprintf(
"UPDATE %s SET VALUES(%s) = %s",
$this -> tablename,
$fields,
$placeholders
);
// execute statement here, handle exceptions, and so...
}
}
したがって、User
クラスは次のようになります。
class User extends BasicEntity
{
protected $id;
protected $username;
protected $email;
protected $password;
protected $enabled;
protected $createdAt;
public function __construct()
{
$this -> tablename = '_user';
$this -> schema = array(
'id' => 'int',
'username' => 'string',
'email' => 'string',
'password' => 'string',
'enabled' => 'int',
'createdAt' => 'datetime'
);
}
}
そしてあなたのAdmin
クラス:
class Admin extends User
{
protected $additionalProperty;
public function __construct()
{
parent::__construct();
$this -> schema['additionalProperty'] = 'string';
}
}
を呼び出すupdate()
と、クラススキーマに基づいて適切なクエリが作成されます。このアプローチは、次のことに気付くため、複雑度の低いレベルで機能します。
- [同じテーブル上で]エンティティを拡張する場合は、そのようなクラスフィールドがない行に対しても空のテーブルフィールドを提供する必要があります[この場合
additionalProperty
]。
- スキーマが変更された場合(たとえば、変数名を変更した場合)、スキーマをクラスコンストラクターにハードコーディングする必要があり、保守が困難になります。
- エンティティ間の関係を処理する場合は、多くの個別のクエリを記述してパフォーマンスを低下させない限り、すべてのSELECTステートメントに適切な結合を記述するのは非常に困難です。
最初の問題を解決するには、オブジェクトの構成が必要なので、メインテーブルをあまり大きくしないでください[AdditionalPropertyList
たとえば、外部エンティティへの参照を取得するだけです]。
2番目を解決するには、スキーマを外部ファイルに保持するか、インラインアノテーションを使用する必要があります。
3番目を解決するには、独自のORM [ Object Relational Mapping ]を作成するか、既存のORMに切り替える必要があります。
とにかく、学習のメリットから、私は巨人の肩の上に立って、スケーラブルで保守可能なアプリケーションを構築することを計画している場合は、フレームワークを選択します。