将多维php数组插入mysql数据库

将多维php数组插入mysql数据库,php,mysql,multidimensional-array,Php,Mysql,Multidimensional Array,我有一个来自csv的数组,其结构与此类似: $array = array( array('name', 'age', 'gender'), array('Ian', 24, 'male'), array('Janice', 21, 'female') ); 我想将它插入一个MySQL表,其中第一个数组的项目(姓名、年龄、性别)是列标题,随后的每个数组都是表中的一行 有谁能建议最好的方法吗 $fields = implode(',', array_shift($array

我有一个来自csv的数组,其结构与此类似:

$array = array(
    array('name', 'age', 'gender'),
    array('Ian', 24, 'male'),
    array('Janice', 21, 'female')
);
我想将它插入一个MySQL表,其中第一个数组的项目(姓名、年龄、性别)是列标题,随后的每个数组都是表中的一行

有谁能建议最好的方法吗

$fields = implode(',', array_shift($array)); // take the field names off the start of the array

$data = array()
foreach($array as $row) {
    $name = mysql_real_escape_string($row[0]);
    $age = (int) $row[1];
    $gender = mysql_real_escape_string($row[2]);
    $data[] = "('$name', $age, '$gender')";
}

$values = implode(',', $data);

$sql = "INSERT INTO yourtable ($fields) VALUES $values";
$result = mysql_query($sql) or die(mysql_error());
这将生成一个查询字符串,如:

INSERT INTO yourtable (name, age, gender) VALUES ('Ian', 24, 'male'), ('Janice', 21, 'female'), etc....

假设数组中的值是可信的安全的

$count = count($array);
$keys = $array[0];

for($i = 1; $i < $count; $i++)
{
   $query = "INSERT INTO tablename (" . implode(",", $keys) . ") VALUES ('" . implode ("','", $array[$i]) . "');";
   $query = str_replace(',)', ')', $query);
   mysql_query($query);
}
$count=count($array);
$keys=$array[0];
对于($i=1;$i<$count;$i++)
{
$query=“INSERT INTO tablename(“.implode(“,”,$keys)。”)值(“”)”。implode(“,”,“,”,$array[$i])。“;”;
$query=str_replace(',),'),$query);
mysql\u查询($query);
}

对于此阵列,您可以执行以下简单操作:

$array = csv_array(); // this is your array from csv

$col_name = $array[0][0];
$col_age = $array[0][1];
$col_gender = $array[0][2];

for($i = 1; $i < count($array); $i++){
    //this is where your sql goes
    $sql = "INSERT INTO `table` ($col_name, $col_age, $col_gender) 
    VALUES($array[$i][0], $array[$i][1], $array[$i][2])";

    $db->query($sql);
}
$array=csv_array();//这是csv中的阵列
$col_name=$array[0][0];
$col_age=$array[0][1];
$col_gender=$array[0][2];
对于($i=1;$iquery($sql);
}

您应该清理输入,我在示例中没有这样做。如果不能保证数组结构相同,则必须执行其他操作。

以下代码可以工作,但它假定所有嵌套数组的长度相同,换句话说,每个嵌套数组包含第一个嵌套数组中定义的所有属性的值

$array = array(
    array('name', 'age', 'gender' ),
    array('Ian', 24, 'male'),
    array('Janice', 21, 'female')
);

$fields = implode(', ', array_shift($array));

$values = array();
foreach ($array as $rowValues) {
    foreach ($rowValues as $key => $rowValue) {
         $rowValues[$key] = mysql_real_escape_string($rowValues[$key]);
    }

    $values[] = "(" . implode(', ', $rowValues) . ")";
}

$query = "INSERT INTO table_name ($fields) VALUES (" . implode (', ', $values) . ")";
只要所有其他嵌套数组具有相同的长度,此解决方案将适用于第一个嵌套数组中定义的任意数量的属性。对于上面的阵列,输出将为:

INSERT INTO table_name (name, age, gender) VALUES (Ian, 24, male), (Janice, 21, female)

有关演示,请参见,但请注意,我删除了codepad.org上对mysql\u real\u escape\u string()的调用,因为它们不允许该函数。在您自己的代码中,您应该使用它。

您可以这样做:

$rows = array(
    array('name', 'age', 'gender'),
    array('Ian', 24, 'male'),
    array('Janice', 21, 'female')
);

$columns = array_shift($rows);

$rows = array_map(function($row) {
    /*
     * TODO: escape column values
     */

   return '"' . implode('", "', $row) . '"';
}, $rows);

$sql = 'INSERT  INTO ...
                (' . implode(', ', $columns) . ')
        VALUES  (' . implode('), (', $rows) . ')';
由于mysql(扩展名)将在insert上“转换”您的值,所以您不需要注意列类型:如果列定义为integer,则在数据库中,它将作为integer插入,即使您引用了值(例如:年龄)


请注意我在源代码中标记的TODO:插入值而不转义它们是非常不安全的(SQL注入)。

我的解决方案在两个步骤中

  • 将数组值保存为简单DB表中数据的序列化表示形式

  • 将数组值保存在单独的表字段中

  • 工作示例:

    $array = array(
        0 => array ( "name", "age", "gender"),
        1 => array ( "Ian", "24", "male"),
        2 => array ( "Janice", "21", "female")
    );
    
    foreach($array as $key1 => $value1){
        foreach($value1 as $key2 => $value2){
            // assuming the first element (0) in the array is the header value and the header value is a valid array key
             if($key1 > 0){
                  $items[$key1-1][ $array[0][$key2] ] = $value2;
             }
        }    
    }
    
    // 1. store values as serialized representation
    foreach ($items as $key => $value) {
        $sql = "INSERT INTO datatable SET data = ".mysql_real_escape_string(serialize($value))."";
        echo $sql.PHP_EOL;
    }
    
    // 2. auto create fields in database and store values
    foreach ($array[0] as $key1) {
        $sql = "ALTER TABLE forms ADD '".$key1."' TEXT NOT NULL";
        echo $sql.PHP_EOL;
    }
    foreach ($items as $key1 => $value1) {
        foreach($value1 as $key2 => $value2){
            $sql = "INSERT INTO datatable SET ".$key2." = '".mysql_real_escape_string($value2)."'";
            echo $sql.PHP_EOL;
        }
    }
    

    阵列

    $arrayData = array(
         array(
            'name' => 'Paul',
            'age' => 28,
            'gender' => 'male',
    
    
        ),
         array(
    
            'name' => 'Rob',
            'age' => 23,
            'gender' => 'male',
    
    
        )
    );
    
     foreach($arrayData as $data){
    
            $query = "INSERT INTO persons (name,gender,age)
            VALUES ('$data[name]', '$data[gender]',  $data[age])";
    
            //echo $query;die;
                mysql_query($query) or die(mysql_error());
                //exit;
        }
    

    最好的方法是在PDO库的帮助下使用准备好的语句和事务。PDO是PHP中任何DB交互的最简单选择

    准备好的语句快速、简单,它们提供了参数绑定,可以保护您免受SQL注入的副作用

    DB事务确保插入所有数据或根本不插入任何数据。它们还可以显著提高此类任务的性能

    下面是一个示例代码:

    // create new connection to MySQL using PDO class
    $pdo = new \PDO("mysql:host=$host;dbname=$db;charset=$charset", $user, $pass, [
        \PDO::ATTR_ERRMODE => \PDO::ERRMODE_EXCEPTION,
        \PDO::ATTR_EMULATE_PREPARES => false
    ]);
    
    $array = array(
        array('name', 'age', 'gender'),
        array('Ian', 24, 'male'),
        array('Janice', 21, 'female')
    );
    
    // discard the header row (1st row) from the array
    array_shift($array);
    
    // start transaction
    $pdo->beginTransaction();
    
    // prepre SQL statemenet with 3 placeholders
    $stmt = $pdo->prepare('INSERT INTO csv_table(name, age, gender) VALUES(?,?,?)');
    foreach ($array as $row) {
        $stmt->execute($row);
    }
    
    // end transaction
    $pdo->commit();
    
    标题行呢? 正如您在上面的代码中看到的,我正在丢弃标题行。由于SQL表是严格的,我需要事先知道列的名称。如果要将CSV中的列与模式中的列动态匹配,则需要添加一些逻辑,以查看硬编码的列列表(您也可以从
    信息\u模式
    )获取此信息,并将其与CSV中的列名称匹配

    代码可以按如下方式进行调整。迭代CSV中的列名,如果代码中未定义任何列,则引发异常。如果验证了所有列,则
    内爆()

    $array = array(
        array('name', 'age', 'gender'),
        array('Ian', 24, 'male'),
        array('Janice', 21, 'female')
    );
    
    $table_columns = ['age', 'gender', 'name'];
    
    // Validate CSV header row (1st row) against your schema columns
    $header = array_shift($array);
    foreach ($header as $col_name) {
        if (!in_array($col_name, $table_columns, true)) {
            throw new \Exception('Incorrect column name specified in CSV file');
        }
    }
    
    // start transaction
    $pdo->beginTransaction();
    
    // prepre SQL statemenet with 3 placeholders
    $stmt = $pdo->prepare('INSERT INTO csv_table('.implode(',', $header).') VALUES(?,?,?)');
    foreach ($array as $row) {
        $stmt->execute($row);
    }
    
    // end transaction
    $pdo->commit();
    

    将多数组插入SQL的最直接方法可能是:

    $queryIn = "INSERT INTO table (resultsArray) values (" . print_r($multiArray, true) . "')";
    

    这是可行的。

    引用字段名会将其转换为字符串,不再将其视为字段名。否则,大多数情况下看起来都很好。你知道为什么我在内爆()的代码中会收到“无效参数传递”警告吗?@chentudou你确定你复制了好的代码吗?我在发帖前试过了,效果很好。此外,正如您所看到的,如果有多于(或少于)3个字段,则此代码也可以工作。我再次尝试。。。内爆警告已经消失,但它说SQL语法中有一个错误。我会继续努力,可能是我的错误。@AurelioDeRosa:你把参数换成了内爆。已编辑。一个问题可能是变量,$name$age$gender每次都会不同,并且它们的数量也会不同,因此我能否从第一个数组中获取变量名?类似于计算第一个数组中的元素,然后增加它。因此,只要数组中的第一行包含字段名,第二行、第三行等,变量就可能类似于-$data[0][$x]。。行具有值,则此函数将处理任意数量的行。直到PHP的内存限制以及查询字符串增长到超过mysql的最大允许数据包限制的任何点。@MarcB我想他说的是不同的字段数,而不是行数。@Aurelio:啊。明白了。在这种情况下,不,这段代码只包含3个字段。是的,对不起,我可能不清楚。因为我并不总是知道字段的编号和标题。所以我认为奥雷里奥的代码可以做到这一点。感谢使用“内爆”将它们放入数据库中后,如何将它们分解为以前的原始数组?我目前正在处理相同的问题“字段列表”中的未知列“Ian”。这是您的输出。代码不起作用