【问题标题】:PHP Object Extension QuestionPHP 对象扩展问题
【发布时间】:2010-11-06 11:04:30
【问题描述】:

所以我有一个项目类如下:

类项目 { 私人 $db; 私人 $data = 数组( 'AltItem1' => 空, 'AltItem2' => 空, 'BaseUOM' => 空, 'Category1' => 空, 'Category2' => 空, 'Category3' => 空, 'Category4' => 空, 'Iden' => 空, 'IsHCS' => 空, 'ItemDesc' => 空, 'ItemNmbr' => 空, '项目类型' => 空, 'MSDS' => 空, 'NoteText' => 空, '非库存' => 空, 'PrcLevel' => 空, 'TipPrice' => 空, 'DTM_UpdType' => 空, 'DTM_UpdDateTime' => 空, 'DTM_DownloadDateTime' => 空, 'DTM_UploadDateTime' => 空 ); 公共函数 __construct(mysqli $db, $id = null){ $this->db = $db; if(!empty($id)){ $id = (int)$id; $this->populate($id); } } 公共函数 __get($key) { if(array_key_exists($key, $this->data)){ 返回 $this->data[$key]; } error_log("无效键 '$key'"); 返回空值; } 公共函数 __set($key, $value) { if(array_key_exists($key, $this->data)){ $this->data[$key] = $value; 返回真; } 返回假; } 公共函数填充($id) { $sql = sprintf( "从 ItemMaster WHERE id = 中选择 %s?", 内爆(“,”,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() 或 die('exec'); $stmt->store_result(); 如果($stmt->num_rows == 1) { $params = 数组(); foreach($this->data as $key => $val){ $params[] = &$this->data[$key]; } call_user_func_array(array($stmt, 'bind_result'), $params); $stmt->fetch(); $返回=真; } 别的{ user_error("没有为 id '$id' 返回行"); $返回=假; } 返回 $return; } 公共函数插入() { $params = $this->数据; $values = 数组(); foreach($params 作为 $param){ $values[] = "?"; } $sql = sprintf( "插入重复 (%s) 值 (%s)", 内爆(“,”,array_keys($params)), 内爆(“,”,$值) ); $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->执行(); $stmt->store_result(); $result = $stmt->result_metadata(); } 公共函数更新() { $sql = "更新重复设置"; $params = 数组(); foreach($this->data as $key => $value){ $params[] = "$key = ?"; } $sql .= implode(", ", $params) 。 "哪里 id = ?"; $stmt = $this->db->stmt_init(); $stmt->prepare($sql) or die ("Could not prepare statement:" . $stmt->error); $params = $this->数据; $params[] = $this->data['id']; $types = str_repeat("s", count($params)); array_unshift($params, $types); call_user_func_array(array($stmt, "bind_param"), $params); $stmt->执行(); $stmt->store_result(); $result = $stmt->result_metadata(); } }

我的问题是,用我拥有的数据结构扩展此类的最佳方法是什么?我基本上想要购物车中的物品的另一个类。所以一些额外的字段会是数量、购物车 id 等。或者有没有更好的方法可以在不扩展类的情况下做到这一点?

另一方面,假设我有另一个变量 $price 不直接存储在数据库中。所以我将它设为公共变量,但我必须使用辅助方法来访问它,不是吗?如果是这样的话,我的 $data 数组是不是这类项目的最佳解决方案?

提前致谢。

【问题讨论】:

    标签: php class oop object extension-methods


    【解决方案1】:

    我不能 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 属性,您不必重新声明所有字段。您只需将孩子的新字段添加为新的私有成员。

    所以我不确定这是否会让你的生活更轻松,但我认为这将是我的方法。

    【讨论】:

    • 我喜欢这个想法,唯一的问题是我刚刚添加到原始问题中的插入和更新方法。它们有点奇怪,但它们使查询变得容易得多。有什么方法可以将您保存变量的方法与我的插入和更新方法联系起来。当然,我可以为包含每个变量进行一个巨大的长查询,但是只要它们有这个 $data 变量,我的插入和更新方法就可以对我的所有类全面工作。你怎么看?
    【解决方案2】:

    如果你需要细节,我帮不了你太多,但就逻辑而言:

    从纯粹的面向对象设计的角度来看,我认为最好的解决方法是创建一个 Cart 类来跟踪项目。它基本上可以是一个适当排序列表的包装类(特定于语言,我不太了解 PHP =P)。

    我没有看到让商品跟踪其所在的购物车的特定理由 - 在大多数情况下,让购物车保持跟踪更有意义。 (就现实世界的建模而言:物品是否会跟踪他们可能在或可能不在的购物车?不。但购物车基本上只是物品的容器。)

    我不太确定您在第二个问题中要问什么——请您详细说明一下吗? 抱歉,我无法提供更多帮助。

    大卫

    【讨论】:

    • 感谢大卫的建议。这是基本前提。我有一个带有一系列物品的购物车类。但是对于这些物品,我还需要存储数量。现在要将购物车存储在数据库中,我还需要存储所有物品及其数量。这就是此类扩展的用武之地。链接到购物车的项目仅用于关系数据库,使我的查询更容易。也许我会跳过 cart-item 类,让这一切都由 cart 类管理......不过感谢您的帮助!
    猜你喜欢
    • 2011-06-05
    • 1970-01-01
    • 2011-03-23
    • 1970-01-01
    • 2016-08-26
    • 2017-06-02
    • 1970-01-01
    • 2011-06-17
    • 1970-01-01
    相关资源
    最近更新 更多