Php 积垢和乌德。如何处理这个问题?
请残酷地诚实,如果你必须的话,把我的作品撕碎 因此,我正在编写一个我最近制作的小型web应用程序。原因很简单,代码变得非常混乱,我想学习并应用更好的OO设计。这个应用程序应该做的只是简单的CRUD。 我有一个包含3个表的数据库,Php 积垢和乌德。如何处理这个问题?,php,mysql,oop,crud,Php,Mysql,Oop,Crud,请残酷地诚实,如果你必须的话,把我的作品撕碎 因此,我正在编写一个我最近制作的小型web应用程序。原因很简单,代码变得非常混乱,我想学习并应用更好的OO设计。这个应用程序应该做的只是简单的CRUD。 我有一个包含3个表的数据库,公司和合作伙伴,它们彼此之间没有任何关系,城市与公司和合作伙伴之间有1:n的关系。非常简单,真的。现在,我有几个问题,我将在我的文章的最后陈述。这里我只想解释一下: 我的第一种方法是创建company、partner和city类,从数据库中获取所有数据集,并从中创建对象:
公司
和合作伙伴
,它们彼此之间没有任何关系,城市
与公司和合作伙伴之间有1:n的关系。非常简单,真的。现在,我有几个问题,我将在我的文章的最后陈述。这里我只想解释一下:
我的第一种方法是创建company、partner和city类,从数据库中获取所有数据集,并从中创建对象:
class company {
private $id = null;
private $name = null;
private $city = null;
//many more attributes
function __construct( $id, $name, $city, [...] ) {
$this->id = $id;
$this->name = $name;
$this->city = $city;
//huge constructor
}
/*
* getters + setters here
*
* no need to paste the partner class as it looks just like this one
*
*/
}
这就是所有这些课程所做的。我从数据库中提取了每个数据集,构建了公司、合作伙伴和城市对象(这些类中的属性城市本身就是一个具有多个属性的对象),并将它们保存到两个数组arr_companys
和arr_partners
,然后它们保存了这些对象……这样工作很好
现在,我想要的是更新、插入、删除到数据库中,所有3个类(城市、公司、合作伙伴)都需要这个功能。我的方法是使用构造函数创建一个新类,该类基本上采用2个字符串的命令和对象,例如('update','company')
,然后它将直接在数据库中更新company,而不影响我的对象。这让我非常难过,因为我有这么好的构造对象,我不知道如何使用它们
问题:
- 有这么大的施工人员(我最大的一个施工人员)不好吗 28个参数
- 是否应该为数据库设置单独的类 操作还是最好有一个抽象类或 接口,并让子类自己处理更新、删除、插入
- 无论何时只要从数据库中写入、删除,还是应该只将这些更改应用于对象,然后仅在以后(例如会话结束时)对数据库执行命令,这是很常见的吗
- 我想像这样的应用程序以前一定做过很多次。这里的正确方法是什么?创建对象、处理对象、将其保存到数据库
- 我有很多问题,但我想很多问题我都不知道该怎么问
请注意,如果可能的话,我现在不想使用ORM
非常感谢您抽出时间 你所做的看起来很棒。您可以添加一个中间层,将业务对象映射到数据库(对象关系映射)。有很多对象关系映射api。查看wikipedia列表,查找可用于PHP的构造函数我认为一个包含28个参数的构造函数太多了,您应该让其他类管理一些属性,这些属性有一些共同点。您应该告诉我们您实例化了什么类型的其他属性,这可以帮助您找到一种方法来创建更常见的对象 我认为您还应该创建一个类来管理操作和数据库,就像带有delete、update等的DBHandler一样。。 在我看来,在调用函数之后直接修改数据库中的元组是很重要的
为什么??因为它可以避免冲突,比如你试图更新一个应该被删除的对象,例如,如果你在最后修改了你的数据库。你实际上是在编写你自己的ORM。所以,我不会打折换一个已经为你写的。自己滚动的好处是,您可以在编写时了解它是如何工作的。但缺点是其他人可能已经做得更好了。但是假设你想继续 一般建议:记住要把问题分解成越来越简单的部分。每个类应该只执行一个简单的函数。此外,您不必担心缓存更新。。。除非您的数据库可能位于调制解调器远程连接的另一端 具体建议如下: 我会将实体实例类设置为容纳数据,而不是进行大量数据加载。使用其他类和逻辑加载数据。我将只使用实体类的构造函数来填充属于该类(及其子类)的数据 一件简单的事情就是在实体类上使用静态方法来加载和保存数据。例如
class city {
private $id = null;
private $name = null;
function __construct( $id, $name ) {
$this->id = $id;
$this->name = $name;
}
// getters and setters
...
// ---------------------
// static functions
// ---------------------
public static function loadById($cityId) {
// pull up the city by id
$retval = new city(row["id"], row["name"]);
// close db connection
return $retval;
}
public static function loadByCustomerId($customerId) {
// pull up multiple cities by customer id
// loop through each row and make a new city object
// return a hash or array of cities
}
public static function update($city) {
// generate your update statement with $city->values
}
// other methods for inserting and deleting cities
...
}
因此,现在获取和更新城市的代码如下所示:
// loading city data
$city = city::loadById(1); // returns a city instance
$cities = city::loadByCustomerId(1); // returns an array of city instances
// updating city data
$city->name = "Chicago"; // was "chicago"
city::update($city); // saves the change we made to $city
静态方法并不是实现这一点的最佳方法,但它可以为您指明正确的方向。A会更好,但这超出了这个答案的范围。我发现,在遇到更简单的解决方案的问题之前,我常常看不到像存储库模式这样更复杂的解决方案的优点
- 使用setter(可以在内部添加验证逻辑,更好的可读性,不需要用null填充空字段)
- 为每个域类提供单独的类生成器(为其他对象占用一些内存)。java示例,希望您能够理解:
class CompanyBuilder {
private final Company c;
public CompanyBuilder() {
c = new Company();
} CompanyBuilder addId(String id){c.id = id;} // id should be package visible and class should be located in the same package with builder CompanyBuilder addName(String name){...} CompanyBuilder addCity(String city){...} Company build(){ return c;} } 类公司生成器{ 私人最终公司c; 上市公司生成器(){ c=新公司();
} CompanyBuilder addId(字符串id){c.id=id;} //id应该是包可见的,类应该与生成器位于同一个包中 CompanyBuilder地址名(字符串名){…} CompanyBuilder地址城市(字符串城市){…} 公司内部版本(){return c;} } - 混合解决方案具有组织链的方法(调试更差,可读性更好)。在java中,将使用以下方法:
class Company {
...
Company addId(String id){
this.id = id;
return this;
} Company addName(String name){...} ... } Usage: Company c = new Company().addId("1").addName("Name1"); 阶级公司{ ... 公司添加id(字符串id){ this.id=id; 返回此项;
}// Company.php class Company implements iDatabaseOperation public function delete() { // Lets use a DBO singleton/factory for DB access // Uses PDO, which is strongly recommended $dbo = Database::factory(Database::DATABASE_NAME); $dbo->beginTransaction(); try { $sql = "DELETE FROM " . " company " . "WHERE " . " id = :companyId " . "LIMIT 1"; $stmt = $dbo->prepare($sql); $stmt->bindValue(':companyId', $this->getId()); $stmt->execute(); $dbo->commit(); } catch (Exception $e) { $dbo->rollback(); error_log($e->getMessage(); $e = null; // Php's garbage collection sucks } } } // iDatabaseOperation.php interface iDatabaseOperation { public function delete(); public function update(); public function insert(); }