1

如果我想从数据库中获取客户的电子邮件地址,则以下内容很糟糕,因为 $row 将为表中的每个字段包含一个元素customer

$result = mysqli_query ('SELECT * FROM customer WHERE custid = 1');
$row = mysqli_fetch_array ($result, MYSQLI_ASSOC);

这被认为更好,因为 $row 将包含电子邮件地址的单个元素,这就是我们所需要的:

$result = mysqli_query ('SELECT email FROM customer WHERE custid = 1');
$row = mysqli_fetch_array ($result, MYSQLI_ASSOC);

我正在尝试将相同的逻辑应用于对象。如果“客户”对象有 50 个属性/字段,那么当您只需要访问一个时填充所有 50 个属性是否很常见?

下面是一个客户类和对象的基本示例,如果我们想要做的只是获取客户的电子邮件地址,而不是他们的所有其他详细信息(在此示例中,“客户”对象有 5 个属性,但实际上有可能更多):

class Customer {

    private $custid;
    private $firstname;
    private $lastname;
    private $email;
    private $dateadded;

    public function getCustomer ($id) {
        $result = mysql_queryi ('SELECT * FROM customer WHERE custid = ' . $id);
        $row = mysqli_fetch_array ($result, MYSQLI_ASSOC);
        foreach ($row as $key => $value) {
            if (isset ($this->$key)) {
                $this->$key = $value;
            }
        }
    }
}

$customer = new Customer ();
$customer->getCustomer (1); // All I wanted is the email address, but now I have everything :-(
4

3 回答 3

1

您可以为您的getCustomer函数创建第二个参数,该参数接受要查询的字段数组

public function getCustomer ($id, $fields=array('*')) {
    $fields = implode(',', $fields);
    $result = mysql_queryi("SELECT {$fields} FROM customer WHERE ...");
    // ...

用法

// get entire customer
$customer->getCustomer(1);

// just get the email field
$customer->getCustomer(1, array('email'));

// get full name
$customer->getCustomer(1, array('firstname', 'lastname'));

奖金:

我建议在你的模型中存储你的字段有点不同

class Customer
    private $_data;

    public function getCustomer($id, $fields=array('*')) {
        // ...
    }

    // PHP magic set method
    // calling $this->foo = 'bar' results in $this->_data['foo'] = 'bar'
    public function __set($key, $value) {
        return $this->_data[$key] = $value;
    }

    // PHP magic get method
    // calling $this->foo results in $this->_data['foo']
    public function __get($key) {
        return array_key_exists($key, $this->_data)
            ? $this->_data[$key]
            : null
        ;
    }
}

这样你就可以摆脱所有静态定义的实例变量;例如, private $custid;, private $firstname;,private ...

相反,所有字段都将存储在$this->_data私有关联数组中。

这样做的好处是您甚至不必更改getCustomer函数的编写方式。

了解有关 PHP 魔术方法的更多信息

于 2012-11-26T19:36:50.073 回答
0

您可以创建一个获取电子邮件地址的方法:

public function getCustomerEmail ($id) {
    $result = mysql_queryi ('SELECT email FROM customer WHERE custid = ' . (int)$id);
    $row = mysqli_fetch_array ($result, MYSQLI_ASSOC);
    foreach ($row as $key => $value) {
        if (isset ($this->$key)) {
            $this->$key = $value;
        }
    }
}

PS:不要忘记在查询中使用它们之前清理你的变量

于 2012-11-26T19:35:33.873 回答
0

首先...
您确实应该将用于从实际对象中获取客户对象的逻辑分开...我建议查看存储库/外观模式以获取示例。

例如。CustomerCollectionInstance->getCustomer($id) 返回一个客户实体。

您的示例非常简单,因此与仅提取电子邮件和所有字段的区别应该是微不足道的。如果您的对象很大,比如说一个可能有 500 个订单的客户。订单应该被分成自己的对象,当实体对象被组装时,重的对象不应该被加载,而是在它们的位置有代理对象,当访问时查询数据库以获取该数据。



例如。

  • 您在 CustomerCollection 上调用 getCustomer ...

  • CustomerCollection 返回一个加载了基本数据的 CustomerEntity,并且使用 CustomerOrderCollectionProxy 对象设置了 customerOrders。

  • 您调用 CustomerEntity->getOrders() 返回 CustomerOrderCollectionProxy 对象

  • 一旦您调用 CustomerOrderCollectionProxy,它将首先检查它是否已从数据库加载所需的数据......如果没有,它将组装一个真正的 CustomerOrderCollection 并将所有调用委托给该对象,该对象现在具有您需要的日期。



有关示例,请参见代理模式。

于 2012-11-26T20:06:01.563 回答