如果我想从数据库获取客户的电子邮件地址,则以下情况很糟糕,因为$ 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 :-(
答案 0 :(得分: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
函数的方式。
答案 1 :(得分: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:在查询中使用变量之前不要忘记清理变量
答案 2 :(得分:0)
首先...
你真的应该分离从actuall对象获取客户对象的逻辑......我建议查看存储库/外观模式的例子。
EG。 CustomerCollectionInstance-> getCustomer($ id)返回客户实体。
你的例子非常简单,所以与仅提取电子邮件和所有字段的区别应该是微不足道的。如果您的对象是大量的,请说一个可能有500个订单的客户。订单应该分成自己的对象,当组装实体对象时,不应该加载繁重的对象,而是在它们的位置有代理对象,当访问时,然后查询db以获取该数据。
例如。
您在CustomerCollection上调用getCustomer ...
CustomerCollection返回加载了基本数据的CustomerEntity,并使用CustomerOrderCollectionProxy对象设置customerOrders。
您调用CustomerEntity-> getOrders()返回CustomerOrderCollectionProxy对象
一旦你调用了CustomerOrderCollectionProxy,它将首先检查它是否已经从数据库中加载了所需的数据......如果没有,它将组装一个真正的CustomerOrderCollection并委托对该对象的所有调用你需要的日期。
请参阅代理模式以获取示例。