Я пытаюсь создать инструкцию INSERT для каждой строки в объекте PHPExcel. Поскольку я изо всех сил пытался перебирать столбец (т. Е. Перейти к B1 C1 D1, получить значения и поместить их в массив), я решил получить все значения для каждого столбца и поместить их в многомерный массив, который выглядит так:
Array ( [foo] => Array ( [0] => 250 [1] => 247 [2] => 279 [3] => 249 ) [bar] => Array ( [0] => AM PROV [1] => AM PROV [2] => AM PENS [3] => AM PROV ) [schoo] => Array ( [0] => xxxx [1] => yyy [2] => zzz [3] => aaa ) )
Я хочу объединить каждый из массивов, чтобы все данные с индексом 0 находились в одном массиве и т. Д. Я создал общий инструмент, позволяющий вам выбирать столбцы, которые вы хотите получить из загруженной электронной таблицы. Он должен сначала объединить данные столбца в один массив, а затем он должен генерировать инструкции INSERT для каждого из массивов. Таким образом, конечный результат заключается в следующем:
INSERT INTO (foo, bar, schoo) VALUES (250, "AM PROV", "xxxx");
Вся помощь была оценена.
ОБНОВЛЕНИЕ: Привет всем, большое спасибо за ваши ответы. Мне, наконец, удалось заставить его работать с помощью итераторов строк и ячеек в соответствии с предложением Марка и он работает. Теперь у меня есть отдельная проблема, но я думаю, что это то, что я могу решить. Еще раз спасибо.
<?php $uberArray = array( "foo" => array( 0 => 250, 1 => 247, 2 => 279, 3 => 249, ), "bar" => array( 0 => "AM PROV", 1 => "AM PROV", 2 => "AM PENS", 3 => "AM PROV", ), "schoo" => array( 0 => "xxxx", 1 => "yyy", 2 => "zzz", 3 => "aaa", ) ); $yourMysqlLink = mysql_connect('localhost', 'user', 'pass'); mysql_query('SET NAMES utf8'); // Adjust according to your encoding $colNames = array_keys($uberArray); $stringCols = array('bar', 'schoo'); $sqlInsertStr = 'INSERT INTO `your_table` (`'.implode('`, `', $colNames)."`) VALUES \n"; $rows = array(); // Not really for iterating the first array, we just need a loop foreach ($uberArray[$colNames[0]] as $k => $v) { $vals = array(); foreach ($colNames as $v2) { $val = $uberArray[$v2][$k]; if (in_array($v2, $stringCols)) { $val = "'".mysql_real_escape_string($val, $yourMysqlLink)."'"; } $vals[] = $val; } $rows[] = "\t(".implode(', ', $vals).")"; } $sqlInsertStr .= implode(",\n", $rows).';'; echo '<pre style="clear:both;">'.$sqlInsertStr.'</pre>'; ;
Обратите внимание, что вам может потребоваться внести несколько корректировок по причинам производительности, если $uberArray
большой (например, разделение строки вставки на куски). Или вы можете преобразовать данные в CSV и использовать метод MySQL LOAD DATA INFILE
, что очень быстро.
Не уверен, что это то, чем вы были, но …
<?php # Given this array $arrays = array( 'foo' => array( 0 => 250, 1 => 247, 2 => 279, 3 => 249 ), 'bar' => array( 0 => 'AM PROV', 1 => 'AM PROV', 2 => 'AM PENS', 3 => 'AM PROV' ), 'schoo' => array( 0 => 'xxxx', 1 => 'yyy', 2 => 'zzz', 3 => 'aaa' ) ); # This code generates... $fields = array(); $inserts = array(); foreach ($arrays as $k => $v) { $fields[] = $k; } for ($i = 0; $i < count($arrays[$fields[0]]); $i++) { $vals = array(); foreach ($fields as $field) { $vals[] = $arrays[$field][$i]; } $inserts[] = 'INSERT INTO (' . implode(',', $fields) . ') VALUES ("' . implode('","', $vals) . '")'; } # This array /* $inserts = array( 'INSERT INTO (foo, bar, schoo) VALUES ("250", "AM PROV", "xxxx")', 'INSERT INTO (foo, bar, schoo) VALUES ("247", "AM PROV", "yyy")', 'INSERT INTO (foo, bar, schoo) VALUES ("279", "AM PENS", "zzz")', 'INSERT INTO (foo, bar, schoo) VALUES ("249", "AM PROV", "aaa")' ); */ var_dump($inserts);
Изменить: Хотя я думаю, что вам не хватает имени таблицы из ваших инструкций INSERT.
Edit2: вы можете сократить код, используя array_keys, например Frosty Z, и пропустить первый файл foreach.
$inputArray = array('a' => array(1, 2, 3), 'b' => array("X'", 'Y', 'Z')); $finalArray = array(); // build array with appropriate data rows $finalIndex = 0; foreach($inputArray as $key => $row) { foreach($row as $value) $finalArray[$finalIndex][] = $value; $finalIndex++; } // format it as SQL insert queries $fields = array_keys($inputArray); foreach($finalArray as $row) { echo "INSERT INTO table (".implode(", ", $fields).") " . " VALUES (".implode(", ", array_map("format_data", $row)).");\n"; } function format_data($value) { // assuming you're using MySQL. Replace the escape function by // the appropriate one if (is_string($value)) return "'".mysql_real_escape_string($value)."'"; else return $value; }
Для этого вы можете использовать один из этих странных итераторов. 🙂
$iter = new MultipleIterator(MultipleIterator::MIT_KEYS_ASSOC); foreach ($uberArray as $colName => $colValues) { $iter->attachIterator(new ArrayIterator($colValues), $colName); } foreach ($iter as $vals) { print_r($vals); //or $pdoStmt->execute($vals); }
Но на самом деле простой цикл – это инструмент для использования здесь.
Я не вижу причины объединять массив, если вы не хотите потерять память. Вы уже, вероятно, сделали копию данных. Это просто вставляет данные по строкам.
$data = array('foo' => array(...), ... ); $fields = array('foo', 'bar', 'schoo'); $c = count($data[$fields[0])); $base_sql = 'INSERT INTO tbl ('.implode(',', $fields).') VALUES '; for ($i = 0; $i < $c; ++$i) { $row_data = array(); foreach ($fields as $field) $row_data[] = "'".escape_func($data[$field][$i])."'"; $sql = $base_sql . '(' . implode(',', $row_data). ')'; db_query($sql); }
Я бы действительно использовал подготовленные заявления.
И вы действительно должны попытаться выяснить, как итерации через исходный набор данных за один проход.