我需要找到一个很好的解决方案,将一个数据库模型映射到另一个第三方模型。
代码目前必须执行以下操作:
'HomePhone' => $customer['details']['phone']['home']
例如。
可以想象,如果多次使用$customer['details']['phone']['home']
,如果数据库发生变化(如此),修改密钥就变成了一场噩梦。
所以我希望有一个用于映射的配置,例如
$map = [
'HomePhone' => 'customer.details.phone.home'
]
这样,我可以简单地使用$map['HomePhone']
,只需要更改数据模型的一个位置,例如将其更改为customer.details.homephone
如果这是配置项的结构,我如何在上面的作业中使用customer.details.phone.home
并将其展开到[customer][details][phone][home]
?
这种想法是否有效,还是有更好的方法? 感谢
答案 0 :(得分:1)
一般来说,如果您有一些数据,并且想要获得一个特定的数据 out ,那么您可以编写一个选择器。好消息是,你正走在正确的道路上 - 只有你只是试图解决它有点不正确......
// some data
$customer = [
// ...
'details' => [
// ...
'phone' => [
// ...
'home' => '0123456789'
]
]
];
// a selector
function customerHomePhone($customer) {
return $customer['details']['phone']['home'];
}
现在,只要您需要在代码中访问此属性,就可以使用
执行此操作<span>Home Phone: <?php echo customerHomePhone($customer) ?></span>
这样做的好处绝对是巨大的。
尝试从$customer
获取数据的人不需要了解 的结构。
如果数据变得非常复杂,有数百个字段和几十个嵌套级别会怎么样?要查看引用对象以重新学习如何访问需要阅读的字段,这可能会非常令人沮丧。
我永远记得customerHomePhone($customer)
,但要记住它会更难......
$customer['details']['phone']['home']
&#34;它是detail
单数还是details
复数?等等,是的,我认为phones
是多元化的,但detail
是单数的......该死的!&#34;
这也意味着您有自由更改存储家庭电话数据(或任何数据)的位置 - 无论如何 你想要改变它 - 以及所有你要做的就是在你的应用中更新一个位置。
假设您将其更改为存储为...
$customer['contacts']['home_phone']
...您所要做的就是将customerHomePhone
更新为...
function customerHomePhone($customer) {
return $customer['contacts']['home_phone'];
}
或$customer
甚至可能会发生更大的变化。也许您将使用stdClass
而不是数组,因此选择器变为......
function customerHomePhone($customer) {
return $customer->details->phone->home;
}
没关系。只要选择器指向您正在使用的任何数据结构中的正确值,您的应用程序的其余部分就会受到更改的影响并继续完美运行。
当然,构建其他选择器也是有意义的......
function customerDetails($customer)
return $customer['details'];
}
function customerPhones($customer) {
return customerDetails($customer)['phone'];
}
function customerHomePhone($customer) {
return customerPhones($customer)['home'];
}
您想了解有关数据抽象的更多信息吗?看看这些链接:
也许您不喜欢功能性方法,或者使用现有应用程序可能更好地使用OOP凝胶。 class
对于数据抽象而言是OOP的金锤 - 或者对此事的任何抽象。
class Customer {
private $data;
public function __construct(array $data) {
$this->data = $data;
}
// maybe we only use details internally, thus private
private function details() {
return $this->data['details'];
}
public function first_name() {
return $this->details()['first_name'];
}
public function last_name() {
return $this->details()['last_name'];
}
public function full_name() {
return $this->first_name() . ' ' . $this->last_name();
}
}
$customer = ['details' => ['first_name' => 'N', 'last_name' => 'K']];
$c = new Customer($customer);
echo $c->full_name(); //=> 'N K'
这可能看起来很多,但这只是因为您的$customer
数据非常复杂。如果您的客户数据持平,您仍然希望使用数据抽象,但您可以通过更简单的方式实现...
class Customer {
private $data;
public function __construct(array $data) {
$this->data = $data;
}
public function __get($key) {
return array_key_exists($key, $this->data) ? $this->data[$key] : null;
}
public function full_name() {
return $this->first_name . ' ' . $this->last_name;
}
}
// flat data
$customer = ['first_name' => 'N', 'last_name' => 'K'];
$c = new Customer($customer);
echo $c->full_name(); //=> 'N K'