所以我有一个项目类如下:
class Item { private $db; private $data = array( 'AltItem1' => null, 'AltItem2' => null, 'BaseUOM' => null, 'Category1' => null, 'Category2' => null, 'Category3' => null, 'Category4' => null, 'Iden' => null, 'IsHCS' => null, 'ItemDesc' => null, 'ItemNmbr' => null, 'ItemType' => null, 'MSDS' => null, 'NoteText' => null, 'NonStock' => null, 'PrcLevel' => null, 'TipPrice' => null, 'DTM_UpdType' => null, 'DTM_UpdDateTime' => null, 'DTM_DownloadDateTime' => null, 'DTM_UploadDateTime' => null ); public function __construct(mysqli $db, $id = null){ $this->db = $db; if(!empty($id)){ $id = (int)$id; $this->populate($id); } } public function __get($key) { if(array_key_exists($key, $this->data)){ return $this->data[$key]; } error_log("Invalid key '$key'"); return null; } public function __set($key, $value) { if(array_key_exists($key, $this->data)){ $this->data[$key] = $value; return true; } return false; } public function populate($id) { $sql = sprintf( "SELECT %s FROM ItemMaster WHERE id = ?", implode(", ", array_keys($this->data)) ); $stmt = $this->db->stmt_init(); $stmt->prepare($sql) or die ("Could not prepare statement:" . $stmt->error); $stmt->bind_param('i', $id); $stmt->execute() or die('exec'); $stmt->store_result(); if($stmt->num_rows == 1) { $params = array(); foreach($this->data as $key => $val){ $params[] = &$this->data[$key]; } call_user_func_array(array($stmt, 'bind_result'), $params); $stmt->fetch(); $return = true; } else{ user_error("No rows returned for id '$id'"); $return = false; } return $return; } public function insert() { $params = $this->data; $values = array(); foreach($params as $param){ $values[] = "?"; } $sql = sprintf( "INSERT INTO recurrence (%s) VALUES (%s)", implode(", ", array_keys($params)), implode(", ", $values) ); $stmt = $this->db->stmt_init(); $stmt->prepare($sql) or die ("Could not prepare statement:" . $stmt->error); $types = str_repeat("s", count($params)); array_unshift($params, $types); call_user_func_array(array($stmt, "bind_param"), $params); $stmt->execute(); $stmt->store_result(); $result = $stmt->result_metadata(); } public function update() { $sql = "UPDATE recurrence SET "; $params = array(); foreach($this->data as $key => $value){ $params[] = "$key = ?"; } $sql .= implode(", ", $params) . " WHERE id = ?"; $stmt = $this->db->stmt_init(); $stmt->prepare($sql) or die ("Could not prepare statement:" . $stmt->error); $params = $this->data; $params[] = $this->data['id']; $types = str_repeat("s", count($params)); array_unshift($params, $types); call_user_func_array(array($stmt, "bind_param"), $params); $stmt->execute(); $stmt->store_result(); $result = $stmt->result_metadata(); } }
我的问题是,以我的方式使用数据结构扩展此类的最佳方法是什么?我基本上想要一个购物车中的物品的另一个类。所以一些额外的字段将是数量,购物车ID等。或者有更好的方法来做到这一点而不扩展类?
另一方面,我说有另一个变量$ price不能直接存储在数据库中。所以我把它变成了一个公共变量,但我不得不制作帮助方法来访问它不是吗?如果是这种情况,我的$ data数组是这类项目的最佳解决方案吗?
提前致谢。
答案 0 :(得分:2)
我不是100%确定您可能正在使用的私有$data
变量的用法,因此我的倾向是采用稍微不同的方法。
不是将所有数据字段分组到对象的单个私有变量中,而是将每个字段设置为私有变量,即:
class Item
{
private $db;
private $AltItem1;
private $AltItem2;
...
etc.
这样可以立即解决您公开数据字段的问题,因为您可以简单地将这些字段声明为公共成员。公共成员不需要getter和setter,因此您不必担心......您可以通过$this->price
(内部)或$item->price
(外部)访问它们。为您节省一些代码。而且,您可以快速修改populate()
功能来设置所有新属性,因为您只需要设置$this->$$key
而不是$this->data[$key]
。
现在,通过使用__set()
和__get()
,您似乎希望能够访问私有$data
成员,甚至可以访问对象外部。没有理由你不能通过将每个字段单独声明为私有来继续这样做。 __set()
和__get()
将以完全相同的方式运作,您只需要进行微调,即:
public function __get($varname)
{
if ($this->$varname !== null) return $this->varname;
error_log("Invalid key '$key'");
return null;
}
作为最后的奖励,扩展课程变得更容易,因为如果要覆盖$data
属性,则不必重新声明所有字段。您只需将子项的新字段添加为新的私有成员。
所以我不确定这是否会让你的生活更轻松,但我认为这将是我的方法。
答案 1 :(得分:1)
如果您需要具体信息,我无法帮助您,但就逻辑而言:
从纯粹面向对象的设计角度来看,我认为最好通过创建Cart类来跟踪项目来解决这个问题。它基本上可以是适当排序列表的包装类(特定于语言,我不太了解PHP = P)。
我没有看到让物品跟踪其所在车辆的特殊原因 - 在大多数情况下,让车辆保持跟踪更有意义。 (在现实世界的建模方面:物品是否记录了他们可能或可能不在的购物车?Nah。但推车基本上只是物品的容器。)
我不太确定你在第二个问题中提到了什么 - 你能详细说明吗? 对不起,我无法提供更多帮助。
大卫