在这个项目中苦苦挣扎 - 我有一个多维关联数组,正在解析它以提取表名,字段名和数据以插入到mysql数据库中。在array2query函数中,如果key:value是顶级对,则$ tablename设置为'project',否则$ tablename = array name(丢弃array [0]数组名称)。数据不是即将到来的用户,它来自json文件中的API调用。实现将使用PDO写入mysql db。
我在$ sql上收到一个未声明的变量通知。如果我在函数内部声明它,它会在foreach循环中重置为空,并且我丢失了已构建的$ sql字符串的一部分(所有'项目'表名数据)。
我还需要丢弃$ element为null或空但不是0或'false'的数据,我似乎找不到干净利落的方法。
如何在不丢失现有字符串的情况下正确处理NOTICE?
<?php
error_reporting(E_ALL);
//read the json file contents
$data = file_get_contents('c:\wamp64\www\json\test.json');
$data1 = preg_replace('/("\w+"):(-?\d+(\.\d+)?)/', '\\1:"\\2"', $data);
$array1 = json_decode($data1, true);
function array2query(array $array1, $tableName = ''){
$sql=""; // not declaring variable results in NOTICE; declaring results in $sql being reset to "" during foreach loop
foreach ($array1 as $key => $element) {
if (is_array($element)) {
// if key is integer then skip - it is the first level of array, keep the $tablename
$key = is_int($key) ? $tableName : $key;
array2query($element, $key);
} else {
if ($tableName === '') {
$tableName = 'project';
}
$sql .= 'INSERT INTO ' . $tableName . ' (' . rtrim($key, ',') . ') VALUES (' . rtrim($element, ',') . ');';
// }
}
}
echo $sql; //dump to screen; missing non-nested values from tablename 'project'
return $sql;
}
$array_query=array2query($array1);
感谢您关注此事。测试数据为http://pastebin.com/iSvqCMxb
编辑: 来自echo的屏幕转储:
INSERT INTO Contacts (ContactType) VALUES (Sales);
INSERT INTO Contacts (ContactAddressId) VALUES (ec4539c0-9012-4b4f-a590-bee11cc91109);
INSERT INTO Contacts (ExportId) VALUES ();
INSERT INTO Vendors (VendorId) VALUES (c3abfde4-4390-4e09-aa5f-60284613c8c5);
INSERT INTO Vendors (Name) VALUES (Fabrication Specialists);
INSERT INTO Vendors (ShortName) VALUES (Fabspec);
这缺少所有“INSERT INTO(项目)......”声明。
答案 0 :(得分:0)
array2query($element, $key);
替换为
$sql .= array2query($element, $key);
答案 1 :(得分:0)
如果要通过递归调用函数来创建字符串,则必须使用引用而不是return语句通过参数返回值。
更改您的功能签名:
function array2query(array $array1, &$sql, $tableName = '')
然后使用将收集SQL语句的变量调用该函数:
$sql = '';
$array_query=array2query($array1, $sql);
请记住也要更改递归调用:
if (is_array($element)) {
$key = is_int($key) ? $tableName : $key;
array2query($element, $sql, $key);
}
希望这有帮助,我现在无法真正测试它。
答案 2 :(得分:0)
,似乎生成的数组中缺少信息(从回显的代码行中推断出来:INSERT INTO Contacts (ExportId) VALUES ();
)。
另外我相信你在字符串值中插入sql语句时缺少撇号,例如,这行代码:
INSERT INTO Vendors (ShortName) VALUES (Fabspec);
应该是这行代码:
INSERT INTO Vendors (ShortName) VALUES ('Fabspec');
建议的解决方案:
由于我无权更改文件'c:\wamp64\www\json\test.json'
中的信息格式,因此我只能进行一种解决方法,以便在代码的元素中没有可用数据时,代码可以正常工作。阵列。
首先,我将通过替换这行代码来解决撇号问题:
$sql .= 'INSERT INTO ' . $tableName . ' (' . rtrim($key, ',') . ') VALUES (' . rtrim($element, ',') . ');';
使用此代码:
$column = rtrim($key, ',');
$value_inserted = rtrim($element, ',');
$ap = ""
switch ($column)
{
case ('Name')
$ap = "'";
break;
case ('ShortName')
$ap = "'";
break;
//create a case for all the situations where
//the specific column stores string values
default:
{
if ($value_inserted == "")
{
$value_inserted = 0;
}
}
}
$sql .= 'INSERT INTO ' . $tableName . ' ($column) VALUES ('$ap.$value_inserted.$ap');';
前面的代码将在sql语句中插入值的两端插入一个撇号,当有问题的列需要一个字符串时。
switch语句的默认部分仅在字符串不是相关列的数据类型时执行,因此我有机会使用此部分代码来验证$inserted_value
内的值是否为overflow-y: auto
是空的(这应该是导致你的错误的原因)。在这些情况下,我放置了一个零,但是你可以放置你链接的任何值。
如果这对您有用,请告诉我。
答案 3 :(得分:0)
@Mad Dog是对的,存在问题(至少是递归问题)。
这段代码可以正常工作,使用数据数据的一小部分:
$sql="";
function array2query(array $array1, $tableName = '', &$sql){
//$sql=""; // not declaring variable results in NOTICE; declaring results in $sql being reset to "" during foreach loop
foreach ($array1 as $key => $element) {
if (is_array($element)) {
// if key is integer then skip - it is the first level of array, keep the $tablename
$key = is_int($key) ? $tableName : $key;
array2query($element, $key, $sql);
} else {
if ($tableName === '') {
$tableName = 'project';
}
$sql .= 'INSERT INTO ' . $tableName . ' (' . rtrim($key, ',') . ') VALUES (' . rtrim($element, ',') . ');' . "\r\n";
}
}
//echo $sql; //dump to screen; missing non-nested values from tablename 'project'
return $sql;
}
$rez = $array_query=array2query($array1, '', $sql);
echo '<pre>';
print_r($rez);
echo '</pre>';
然后,您还需要引用您的SQL值,正如@Webeng已经指出的那样。