我今天下午一直在搜索我的用例的可行解决方案。我还没找到。
用例:将数组转换为一种格式,在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 children, Remove key from associative array, Iterating over an array, Flatten array和其他人。我可能在代码中如此深入,以至于我失去了对数据的看法。这是因为我用PHP工作了很长时间,所以我的技能需要刷新。非常感谢您的帮助。
答案 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的对象关系映射器库。它将使这些操作更简单,更安全。