php - 减少多维数组以查询字符串

时间:2014-01-10 23:01:58

标签: php mysql sql arrays pdo

我今天下午一直在搜索我的用例的可行解决方案。我还没找到。

用例:将数组转换为一种格式,在PDO insert语句中,数组键是列,数组值是SQL值。如果此请求与其他请求重复,我道歉。我找不到一个适合我的方法。在我的示例中,父数组是Array[0],它插入到一个表中,Array[1]是子表。它们被迭代并插入到另一个表中,fk_user_id作为外键。

示例插入 $sth = $dbh->prepare("INSERT INTO $table ($colData) VALUES ($valData)");

因此,列为(key1, key2),VALUES为(:value1, :value2),依此类推。我有多维度和提取子节点等等各种问题。

示例数组:

[INFO] Array
(
    [0] => Array
        (
            [last_visit] => 1389393273.19
            [first_visit] => 1389313338.69
            [this_visit] => 1389393265.75
            [latitude] => 37.7858352661
            [longitude] => -122.406417847
            [opted_out] => 0
            [opted_in] => 0
            [user_id] => 1
            [locale] => en
            [device_maker] => unknown
            [device_model] => Simulator
            [os_platform] => iPhone OS
            [os_version] => 7.0.3
            [modified] => 1389393273.19
            [model_type] => tracker
        )
    [1] => Array
        (
            [0] => Array
                (
                    [view_count] => 1
                    [visit_timestamp] => 1389393265.63
                    [page_viewed] => home
                    [page_id] => 320
                    [fk_user_id] => 1
                    [model_type] => page
                )
            [1] => Array
                (
                    [view_count] => 2
                    [visit_timestamp] => 1389393265.64
                    [page_viewed] => contactView
                    [page_id] => 321
                    [fk_user_id] => 1
                    [model_type] => page
                )

        )
)

我尝试过的解决方案 Remove parent - keep childrenRemove key from associative arrayIterating over an arrayFlatten array和其他人。我可能在代码中如此深入,以至于我失去了对数据的看法。这是因为我用PHP工作了很长时间,所以我的技能需要刷新。非常感谢您的帮助。

2 个答案:

答案 0 :(得分:1)

我已经为您考虑了一个可能的解决方案,即正在考虑通过多维数组(无限量的儿童)行走。

该解决方案是一个基于递归的函数,它返回一个带有cols的数组(需要插入到db中),行和包含子节点的数组。

您可以循环输出数组或静态地使用它的某些元素。 看看吧。

<?php

$arr = array(
  'key1' => 'val1',
  'key2' => 'val2',
  'key3' => 'val3',
  'key4' => array(
    'subkey1' => 'subval1',
    'subkey2' => 'subval2',    
  )
);

function walkArray($input)
{
    // Define our output array
    $output = array(
      'keys' => '',
      'vals' => '',
      'children' => array(),
    );

    // We're looping trough the input array
    foreach($input AS $key => $value)
    {
      // If the current value is an array we reached the next dimension
      if(is_array($value))
      {
        // So we call walkArray() recursively with our current value
        // and assign the returned array to a new element in our $output's 'children' key 
        $output['children'][] = walkArray($value);
      }
      else
      {
        // We'll concatenate our keys and values...
        $output['keys'] .= $key . ', '; 
        $output['vals'] .= ':' . $value .', ';
      }
    }

    // And get rid of the trailing commas
    $output['keys'] = rtrim($output['keys'], ', ');
    $output['vals'] = rtrim($output['vals'], ', ');   

    // Eventually we return our output array
    return $output; 
}

?>

<pre>
  <?php
    print_r(walkArray($arr));
  ?>
</pre>

输出结果为:

Array
(
    [keys] => key1, key2, key3
    [vals] => :val1, :val2, :val3
    [children] => Array
        (
            [0] => Array
                (
                    [keys] => subkey1, subkey2
                    [vals] => :subval1, :subval2
                    [children] => Array
                        (
                        )

                )

        )

)    

答案 1 :(得分:0)

从安全的角度来看,以此方式动态地将表单输入映射到SQL列是一个可怕的想法。任何人都可以通过构造匹配的POST请求将任何数据转储到任何列中。

此外,通过将表单值直接插入到SQL字符串中,您很容易受到SQL注入的攻击。任何人都可以提交虚假的POST请求并执行任意SQL,这将暴露或破坏数据库中的任何表。

发出警告后,您想要的是使用PHP foreach

迭代第一条记录中的键

http://www.php.net/manual/en/control-structures.foreach.php

foreach ($main_record as $column_name => $column_value) {
   ...
}

在循环中,您必须在每次迭代中构建两个字符串。第一个包含列名(表名后面的逗号分隔列表)。第二个包含值。

之后,您将必须获取最后插入记录的ID,PDO具有该功能。然后,您将不得不为每个相关记录重复此技术。

如果您想要更好的解决方案,请考虑使用像Laravel这样的框架,其中包含一个名为Eloquent ORM的对象关系映射器库。它将使这些操作更简单,更安全。