I'm creating an ORM in PHP, and I've got a class 'ORM' which basically creates an object corresponding to a database table (I'm aiming for similar to/same functionality as an ActiveRecord pattern.) ORM itself extends 'Database', which sets up the database connection.
我正在用PHP创建一个ORM,并且我有一个类'ORM',它基本上创建了一个对应于数据库表的对象(我的目标是与ActiveRecord模式类似/相同的功能。)ORM本身扩展'数据库',用于设置数据库连接。
So, I can call:
所以,我可以打电话:
$c = new Customer();
$c->name = 'John Smith';
$c->save();
The ORM class provides this functionality (sets up the class properties, provides save(), find(), findAll() etc. methods), and Customer extends ORM. However, in the future I may be wanting to add extra public methods to Customer (or any other model I create), so should this be extending ORM or not?
ORM类提供此功能(设置类属性,提供save(),find(),findAll()等方法),Customer扩展ORM。但是,将来我可能想要向Customer(或我创建的任何其他模型)添加额外的公共方法,那么这是否应该扩展ORM?
I know I haven't provided much information here, but hopefully this is understandable on a vague explanation, as opposed to posting up 300+ lines of code.
我知道我没有在这里提供了大量的信息,但希望这是一个模糊的解释可以理解的,而不是张贴了300个多行代码。
8 个解决方案
#1
3
I agree with the other answers here - put the additional methods into a descendant class. I'd also add an asterisk to that though: each time you extend the class with extra methods, think about what you are trying to achieve with the extension, and think about whether or not it can be generalised and worked back into the parent class. For example:
我同意这里的其他答案 - 将其他方法放入后代类中。我也会为它添加一个星号:每次使用额外的方法扩展类时,请考虑使用扩展程序尝试实现的内容,并考虑是否可以将其推广并重新使用到父类中。例如:
// 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
}
#2
2
You're certainly thinking correctly to put your business logic in a new class outside your 'ORM'. For me, instead simply extending the ORM-class, I'd rather encapsulate it with a new, value object class to provide an additional degree of freedom from your database design to free you up to think of the class as a pure business object.
您当然正在考虑将您的业务逻辑放在“ORM”之外的新课程中。对我来说,只是简单地扩展ORM类,我宁愿用一个新的值对象类封装它,以便为数据库设计提供额外的*度,使您可以将该类视为纯业务对象。
#3
2
Nope. You should use composition instead of inheritance. See the following example:
不。您应该使用组合而不是继承。请参阅以下示例:
class Customer {
public $name;
public function save() {
$orm = new ORM('customers', 'id'); // table name and primary key
$orm->name = $this->name;
$orm->save();
}
}
And ORM
class should not extend Database
. Composition again is best suited in this use case.
而ORM类不应该扩展Database。组合物再次最适合此用例。
#4
1
Yes, place your business logic in a descendant class. This is a very common pattern seen in most Data Access Layers generation frameworks.
是的,将您的业务逻辑放在后代类中。这是大多数数据访问层生成框架中常见的模式。
#5
0
You should absolutely extend the ORM class. Different things should be objects of different classes. Customers are very different from Products, and to support both in a single ORM class would be unneeded bloat and completely defeat the purpose of OOP.
你绝对应该扩展ORM类。不同的东西应该是不同类的对象。客户与产品非常不同,并且在单个ORM类中支持两者都将是不必要的膨胀并完全违背OOP的目的。
Another nice thing to do is to add hooks for before save, after save, etc. These give you more flexibility as your ORM extending classes become more diverse.
另一件好事是在保存之前,保存之后添加钩子等。随着您的ORM扩展类变得更加多样化,这些为您提供了更大的灵活性。
#6
0
Given my limited knowledge of PHP I'm not sure if this is related, but if you're trying to create many business objects this might be an incredibly time consuming process. Perhaps you should consider frameworks such as CakePHP and others like it. This is nice if you're still in the process of creating your business logic.
鉴于我对PHP的了解有限,我不确定这是否相关,但如果您尝试创建许多业务对象,这可能是一个非常耗时的过程。也许您应该考虑像CakePHP这样的框架和其他类似的框架。如果您仍在创建业务逻辑,那么这很好。
#7
0
You're definitely thinking along the right lines with inheritance here.
你肯定在这里考虑继承权。
If you're building an ORM just for the sake of building one (or because you don't like the way others handle things) than go for it, otherwise you might look at a prebuilt ORM that can generate most of your code straight from your database schema. It'll save you boatloads of time. CoughPHP is currently my favorite.
如果你只是为了构建一个ORM而构建一个ORM(或者因为你不喜欢别人处理事物的方式)而不是为了它,那么你可能会看到一个可以直接生成大部分代码的预构建ORM。您的数据库架构。它会为你节省大量的时间。 CoughPHP目前是我的最爱。
#8
0
I have solved it like this in my Pork.dbObject. Make sure to check it out and snag some of the braincrunching I already did :P
我在Pork.dbObject中解决了这个问题。一定要检查出来并抓住我已经做过的一些braincrunching: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"=>$_SERVER['REMOTE_ADDR'])); // find all votes for current ip
}
Note that this way, any database or ORM functionality is abstracted away from the Poll object. It doesn't need to know. Just the setupdatabase to hook up the fields / mappings. and the addRelation to hook up the relations to other dbObjects.
请注意,这样,任何数据库或ORM功能都会从Poll对象中抽象出来。它不需要知道。只是用于连接字段/映射的setupdatabase。和addRelation将关系连接到其他dbObjects。
Also, even the dbObject class doesn't know much about SQL. Select / join queries are built by a special QueryBuilder object.
此外,即使dbObject类对SQL也不太了解。选择/连接查询由特殊的QueryBuilder对象构建。
#1
3
I agree with the other answers here - put the additional methods into a descendant class. I'd also add an asterisk to that though: each time you extend the class with extra methods, think about what you are trying to achieve with the extension, and think about whether or not it can be generalised and worked back into the parent class. For example:
我同意这里的其他答案 - 将其他方法放入后代类中。我也会为它添加一个星号:每次使用额外的方法扩展类时,请考虑使用扩展程序尝试实现的内容,并考虑是否可以将其推广并重新使用到父类中。例如:
// 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
}
#2
2
You're certainly thinking correctly to put your business logic in a new class outside your 'ORM'. For me, instead simply extending the ORM-class, I'd rather encapsulate it with a new, value object class to provide an additional degree of freedom from your database design to free you up to think of the class as a pure business object.
您当然正在考虑将您的业务逻辑放在“ORM”之外的新课程中。对我来说,只是简单地扩展ORM类,我宁愿用一个新的值对象类封装它,以便为数据库设计提供额外的*度,使您可以将该类视为纯业务对象。
#3
2
Nope. You should use composition instead of inheritance. See the following example:
不。您应该使用组合而不是继承。请参阅以下示例:
class Customer {
public $name;
public function save() {
$orm = new ORM('customers', 'id'); // table name and primary key
$orm->name = $this->name;
$orm->save();
}
}
And ORM
class should not extend Database
. Composition again is best suited in this use case.
而ORM类不应该扩展Database。组合物再次最适合此用例。
#4
1
Yes, place your business logic in a descendant class. This is a very common pattern seen in most Data Access Layers generation frameworks.
是的,将您的业务逻辑放在后代类中。这是大多数数据访问层生成框架中常见的模式。
#5
0
You should absolutely extend the ORM class. Different things should be objects of different classes. Customers are very different from Products, and to support both in a single ORM class would be unneeded bloat and completely defeat the purpose of OOP.
你绝对应该扩展ORM类。不同的东西应该是不同类的对象。客户与产品非常不同,并且在单个ORM类中支持两者都将是不必要的膨胀并完全违背OOP的目的。
Another nice thing to do is to add hooks for before save, after save, etc. These give you more flexibility as your ORM extending classes become more diverse.
另一件好事是在保存之前,保存之后添加钩子等。随着您的ORM扩展类变得更加多样化,这些为您提供了更大的灵活性。
#6
0
Given my limited knowledge of PHP I'm not sure if this is related, but if you're trying to create many business objects this might be an incredibly time consuming process. Perhaps you should consider frameworks such as CakePHP and others like it. This is nice if you're still in the process of creating your business logic.
鉴于我对PHP的了解有限,我不确定这是否相关,但如果您尝试创建许多业务对象,这可能是一个非常耗时的过程。也许您应该考虑像CakePHP这样的框架和其他类似的框架。如果您仍在创建业务逻辑,那么这很好。
#7
0
You're definitely thinking along the right lines with inheritance here.
你肯定在这里考虑继承权。
If you're building an ORM just for the sake of building one (or because you don't like the way others handle things) than go for it, otherwise you might look at a prebuilt ORM that can generate most of your code straight from your database schema. It'll save you boatloads of time. CoughPHP is currently my favorite.
如果你只是为了构建一个ORM而构建一个ORM(或者因为你不喜欢别人处理事物的方式)而不是为了它,那么你可能会看到一个可以直接生成大部分代码的预构建ORM。您的数据库架构。它会为你节省大量的时间。 CoughPHP目前是我的最爱。
#8
0
I have solved it like this in my Pork.dbObject. Make sure to check it out and snag some of the braincrunching I already did :P
我在Pork.dbObject中解决了这个问题。一定要检查出来并抓住我已经做过的一些braincrunching: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"=>$_SERVER['REMOTE_ADDR'])); // find all votes for current ip
}
Note that this way, any database or ORM functionality is abstracted away from the Poll object. It doesn't need to know. Just the setupdatabase to hook up the fields / mappings. and the addRelation to hook up the relations to other dbObjects.
请注意,这样,任何数据库或ORM功能都会从Poll对象中抽象出来。它不需要知道。只是用于连接字段/映射的setupdatabase。和addRelation将关系连接到其他dbObjects。
Also, even the dbObject class doesn't know much about SQL. Select / join queries are built by a special QueryBuilder object.
此外,即使dbObject类对SQL也不太了解。选择/连接查询由特殊的QueryBuilder对象构建。