php

时间:2016-08-18 07:35:06

标签: php

我需要找到一个很好的解决方案,将一个数据库模型映射到另一个第三方模型。

代码目前必须执行以下操作:

'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]

这种想法是否有效,还是有更好的方法? 感谢

1 个答案:

答案 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

也许您不喜欢功能性方法,或者使用现有应用程序可能更好地使用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'