基于数组中的数据创建SQL查询

时间:2019-06-24 05:35:27

标签: php mysql sql arrays

我正在尝试寻找一种方法来简化与我们的数据库通信的现有功能。该函数当前具有多个参数(最多15个),并且每次添加或更新记录时都需要所有参数。

我具有以下PHP函数(简体):

function addSomethingToDB($var1, $var2, $var3, $var4...) {

    # Do SQL Injection checks
    ...

    $query = 'INSERT INTO `table` (`var1`,`var2`,`var3`,`var4`) VALUES ($var1, $var2, $var3, $var4)';

    # OR

    $stmt = $db->prepare('INSERT INTO `table` (`var1`,`var2`,`var3`,`var4`) VALUES (?,?,?,?)');
    $stmt->bind_param('ssss', $var1, $var2, $var3, $var4);

}

如果您有多个变量,以上代码显然会变得很混乱。如果不是所有变量都需要,则很难处理。因此,我尝试了第二种情况,即我有一个main / required参数,后跟一个数组,或者我只是有一个数组作为参数。

function addSomethingToDB($var1, array $attributes) {}

这里的目标是允许数组具有更灵活的方法,以防将来需要扩展SQL查询或基于可选值构建SQL查询。

例如:

如果未提供Var2和Var4,则数组将如下所示:

{
    'var1': 'Var1_Value',
    'var3': 'Var3_Value'
}

,SQL将是:

$query = 'INSERT INTO `table` (`var1`,`var3`) VALUES ($var1, $var3);

如您所见,在上述情况下,该查询仅适用于必要的值。

我想尝试实现的是基于提供的值构建SQL查询。我首先假设要使用IF ELSE语句或SWITCH。这给了我一些奇怪的东西,如下:

function getlogs($type, $id='') {

    $types = array('client_log', 'system_log', 'user_log', 'api_log', 'project_log', 'lead_log');

    if (in_array($type, $types)) {

        if ('client_log' == $type) {
            if (!empty($id)) {
                $query = 'SELECT * FROM `logs` WHERE `client_id` = ' . $id . ' AND `type` = "client_log"';
            } else {
                $query = 'SELECT * FROM `logs` WHERE `type` = "client_log"';
            }
        } elseif ('project_log' == $type) {
            if (!empty($id)) {
                $query = 'SELECT * FROM `logs` WHERE `project_id` = ' . $id . ' AND `type` = "project_log"';
            } else {
                $query = 'SELECT * FROM `logs` WHERE `type` = "project_log"';
            }
        } elseif ('user_log' == $type) {
            if (!empty($id)) {
                $query = 'SELECT * FROM `logs` WHERE `staff_id` = ' . $id . ' AND `type` = "staff_log"';
            } else {
                $query = 'SELECT * FROM `logs` WHERE `type` = "staff_log"';
            }
        } elseif ('lead_log' == $type) {
            if (!empty($id)) {
                $query = 'SELECT * FROM `logs` WHERE `client_id` = ' . $id . ' AND `type` = "lead_log"';
            } else {
                $query = 'SELECT * FROM `logs` WHERE `type` = "lead_log"';
            }
        } else {
            $query = 'SELECT * FROM `logs` WHERE `type` = ' . $type;
        }

        $logs = Config::$db->query($query);
        return $logs->fetch_all(MYSQLI_ASSOC);


    } else {
        return 'invalid log type';
    }

    $stmt->close();

}

以上不是我想编写的代码,这是一个类似的示例,其中调用了与日志类型相关的查询。但这是一堆令人不悦的混乱局面。另外,以上代码未使用数组,这是我希望使用的数组。

最后,我希望编写的代码主要与更新现有记录有关。因此,假设我们有一个用户。用户具有电子邮件以及密码和地址。根据上面的代码(第一个),每次用户更新其字段中的任何一个字段时,我们都会更新电子邮件,密码和地址。我想避免这种情况。

我的假设是我必须做类似的事情:

# 1. Loop Array using maybe For or Foreach
# 2. Have a whitelisted array of allowed values.
# 3. Append to query if an Array value exists.
# 4. Run query.

我担心我的问题出在第3点。如果不经过很多凌乱的IF ELSE语句,我似乎无法弄清楚如何构建查询。

现在,到此为止,我当然已经在SO周围进行搜索以找到类似的问题,但是,与SQL和数组相关的搜索几乎完全与在单个SQL查询中添加“多行”或类似内容相关。

1 个答案:

答案 0 :(得分:2)

您可以通过使用数组来实现此目的,其中的键是列名并包含值

$columns = [
      'field1' => 'value1', 
      'field2' => 'value2', 
      'field3' => 'value3', 
      'field4' => 'value4'
];
addSomethingToDB($columns);
function addSomethingToDB($cols){

    # Do SQL Injection checks

    $query = "INSER INTO `tablename` ( ".implode(",",array_keys($cols))." )  VALUES ( '".implode("','",array_values($cols))."' )";
}