在foreach循环中丢失数据

时间:2016-05-06 12:47:03

标签: php mysql multidimensional-array

在这个项目中苦苦挣扎 - 我有一个多维关联数组,正在解析它以提取表名,字段名和数据以插入到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(项目)......”声明。

4 个答案:

答案 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已经指出的那样。