このクラスを拡張する必要がありますか? (PHP)
-
02-07-2019 - |
質問
PHPでORMを作成していますが、基本的にデータベーステーブルに対応するオブジェクトを作成するクラス 'ORM'を持っています(ActiveRecordパターンと同じ/同じ機能を目指しています。)ORMそれ自体が「データベース」を拡張し、データベース接続をセットアップします。
だから、私は呼び出すことができます:
$c = new Customer();
$c->name = 'John Smith';
$c->save();
ORMクラスはこの機能を提供し(クラスプロパティを設定し、save()、find()、findAll()などのメソッドを提供します)、CustomerはORMを拡張します。ただし、将来、顧客(または私が作成する他のモデル)に追加のパブリックメソッドを追加する可能性があるため、これによりORMを拡張する必要がありますか?
ここではあまり情報を提供していませんが、300行以上のコードを投稿するのではなく、あいまいな説明で理解できることを願っています。
解決
ここでの他の答えに同意します-追加のメソッドを子孫クラスに入れます。また、それにアスタリスクを追加します:追加のメソッドでクラスを拡張するたびに、拡張で達成しようとしていることを考え、それを一般化して親クラスに戻すことができるかどうかを考えます。例:
// Customer.class.php
function getByName($name) {
// SELECT * FROM `customer` WHERE `name` = $name
}
// ** this could instead be written as: **
// ORM.class.php
function getByField($field, $value) {
// SELECT * FROM `$this->table` WHERE `$field` = $value
}
他のヒント
「ORM」の外部の新しいクラスにビジネスロジックを配置することは確かに正しく考えられています。私にとっては、ORMクラスを単純に拡張する代わりに、新しい値オブジェクトクラスでカプセル化して、データベース設計の自由度を高め、クラスを純粋なビジネスオブジェクトと見なすようにします。
いいえ。継承の代わりに構成を使用する必要があります。次の例を参照してください。
class Customer {
public $name;
public function save() {
$orm = new ORM('customers', 'id'); // table name and primary key
$orm->name = $this->name;
$orm->save();
}
}
および ORM
クラスは、 Database
を拡張しないでください。この使用例では、再び構成が最適です。
はい、ビジネスロジックを下位クラスに配置します。これは、ほとんどのデータアクセスレイヤー生成フレームワークで見られる非常に一般的なパターンです。
ORMクラスを絶対に拡張する必要があります。異なるものは異なるクラスのオブジェクトでなければなりません。顧客は製品とは大きく異なり、単一のORMクラスで両方をサポートすることは不必要に大きくなり、OOPの目的を完全に打ち負かすことになります。
別の便利なことは、保存前、保存後などにフックを追加することです。これらは、ORM拡張クラスがより多様になるにつれて、柔軟性を高めます。
PHPの知識が限られているため、これが関連しているかどうかはわかりませんが、多くのビジネスオブジェクトを作成しようとしている場合、これは非常に時間がかかるプロセスです。おそらく、 CakePHP などのフレームワークを検討する必要があります。これは、ビジネスロジックを作成中の場合に便利です。
ここでは間違いなく、継承を伴う正しい方向に沿って考えています。
ORMを構築するためだけに(または他の人が物事を処理する方法が気に入らないために)ORMを構築する場合は、それ以外の場合、ほとんどのデータベーススキーマから直接コードを作成します。それはあなたの時間を節約します。 CoughPHP は現在、私のお気に入りです。
Pork.dbObject でこのように解決しました。それをチェックアウトして、私がすでにやった頭脳崩壊のいくつかを手に入れてください:P
class Poll extends dbObject // dbObject is my ORM. Poll can extend it so it gets all properties.
{
function __construct($ID=false)
{
$this->__setupDatabase('polls', // db table
array('ID_Poll' => 'ID', // db field => object property
'strPollQuestion' => 'strpollquestion',
'datPublished' => 'datpublished',
'datCloseDate' => 'datclosedate',
'enmClosed' => 'enmclosed',
'enmGoedgekeurd' => 'enmgoedgekeurd'),
'ID_Poll', // primary db key
$ID); // primary key value
$this->addRelation('Pollitem'); //Connect PollItem to Poll 1;1
$this->addRelation('Pollvote', 'PollUser'); // connect pollVote via PollUser (many:many)
}
function Display()
{
// do your displayíng for poll here:
$pollItems = $this->Find("PollItem"); // find all poll items
$alreadyvoted = $this->Find("PollVote", array("IP"=> Pork.dbObject でこのように解決しました。それをチェックアウトして、私がすでにやった頭脳崩壊のいくつかを手に入れてください:P
<*>
この方法では、データベースまたはORM機能はすべてPollオブジェクトから抽象化されることに注意してください。知る必要はありません 。フィールド/マッピングを接続するためのsetupdatabaseのみ。 addRelationを使用して、関係を他のdbObjectに接続します。
また、dbObjectクラスでさえSQLについてはあまり知りません。選択/結合クエリは、特別なQueryBuilderオブジェクトによって構築されます。
SERVER['REMOTE_ADDR'])); // find all votes for current ip
}
この方法では、データベースまたはORM機能はすべてPollオブジェクトから抽象化されることに注意してください。知る必要はありません 。フィールド/マッピングを接続するためのsetupdatabaseのみ。 addRelationを使用して、関係を他のdbObjectに接続します。
また、dbObjectクラスでさえSQLについてはあまり知りません。選択/結合クエリは、特別なQueryBuilderオブジェクトによって構築されます。