在多个表的相同列中插入相同的元数据时,如何减少重复代码


How do I reduce repetitive code when inserting the same metadata into identical columns over multiple tables?

我的目标:

  • 遵循数据库规范化
  • 能够跟踪我的表中的更改
  • 能够从给定的时间点,例如上个月
  • 分离正在处理数据的代码,以便输入可以来自HTML表单,也可以来自另一种语言(Ruby/perl)的脚本

为了实现这一点,我选择了一个数据库设计,就像这个答案中描述的那样:

StackOverflow:是否有MySQL选项/功能来跟踪记录更改的历史?

但是,当用户更新多个字段时,必须将相同的元数据插入到包含相同列的多个表中,这样我的代码就会变得重复。

示例:

用户通过HTML表单提交数据。PHP在Propel ORM的帮助下处理如下数据。

function insertEvent($name, $venueId, $user, $date, $id = 0) {
    //validation and formatting..
    //if id == 0, new event, 
    //else, this is an update, archive the old database row on successful processing and maintain a common id as a parent
    //...
    $event = new Event();
    $event->setName($name); 
    $event->setVenueId($venueId); 
    $event->setUser($user); //1
    $event->setValidFrom($date); //1
    $event->setValidUntil(null); //1 
    $event->save(); 
    // ...
}
function insertEventPhonenumber($phonenumber, $pid, $user, $date, $id = 0) {
    //...
    $event_phonenumber = new EventPhonenumber();
    $event_phonenumber->setPid($pid); //2
    $event_phonenumber->setPhonenumber($phonenumber);
    $event_phonenumber->setUser($user); //2
    $event_phonenumber->setValidFrom($date); //2
    $event_phonenumber->setValidUntil(null); //2 
    $event_phonenumber->save(); 
    // ...
} 
function insertEventArtistId($artistId, $pid, $user, $date, $id = 0) {
    //...
    $event_artistId = new EventArtistId();
    $event_artistId->setPid($pid); //3
    $event_artistId->setArtistId($artistId);
    $event_artistId->setUser($user); //3
    $event_artistId->setValidFrom($date); //3
    $event_artistId->setValidUntil(null); //3
    $event_artistId->save(); 
    // ...
}

我的问题:

在我的完整代码中,受影响的表比示例中的三个表还要多。

标记为//1、//2和//3的数据输入通常是相同的。

在我的胃里,我不喜欢这样。我一直在尝试使用诸如"SQL中的公共列在多个表上插入查询"之类的查询和各种措辞的搜索引擎,但没有发现任何与我的问题直接相关的内容。

我觉得这种做法不好吗?

如何最大限度地减少代码中的重复?

你想去掉所有这些函数吗?如果是这样,您可以使用call_user_func来消除大部分代码。

<?php
class MyApp {

     static function insert($name, $params) {
         $ob = new $name();
         foreach($params as $k=>$v) {
            $op = array($ob,"set".ucfirst($k));
            //if (is_callable($op)) {
                call_user_func($op,$v);
            //}
         }
         $ob->save();
     } 
}
MyApp::insert(
    "EventArtistId",
    array(
        "pid"=>$_REQUEST['pid'],
        "artistId"=>$_REQUEST['artistId'],
        "user" => $_REQUEST['user'],
        "validFrom" => $_REQUEST['date'], // may need to convert date
        "validUntil" => isset($_REQUEST['validUntil']) ? $_REQUEST['validUntil'] : null,
    )
);
// More cool
// MyApp::insert($_REQUEST['action'],$_REQUEST['params']);
?>