2011-12-21 3 views
4

Я пытаюсь создать инструкцию 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");

Все оцененная помощь.

ОБНОВЛЕНИЕ: Привет всем, большое спасибо за ваши ответы. Мне, наконец, удалось заставить его работать с помощью итераторов строк и ячеек в соответствии с предложением Марка и он работает. Теперь у меня есть отдельная проблема, но я думаю, что это то, что я могу решить. Еще раз спасибо.

+0

не знаком с php, но разве это не двухмерная структура [] []? – Kent

+0

@Kent в php-массивах - это списки списков карт и около каждой другой структуры данных, все в одном ... – corsiKa

+0

Получение массива, который вы хотите, с помощью итераторов строк и ячеек PHPExcel, или даже метода rangeToArray(), должно быть довольно просто ... какие у вас проблемы с этим? –

ответ

1
<?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, что очень быстро.

1

Не уверен, если это то, что вы были после, но ...

<?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); 

Edit: Хотя я думаю, что вы упускаете имя таблицы из ваших заявлений INSERT.

Edit2: Вы можете сократить код с помощью array_keys, таких как Frosty Z, и пропустить первый файл foreach.

1
$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; 
} 
0

Я не вижу причины объединять массив, если вы не чувствуете, что теряете память. Вы уже, вероятно, сделали копию данных. Это просто вставляет данные по строкам.

$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); 
} 

Я бы действительно использовал подготовленные заявления.

И вы действительно должны попытаться выяснить, как итерации через исходный набор данных за один проход.

+0

Я предполагаю, что это в основном то же самое, что и ответ @ powerbuoy, за исключением того, что он немного оптимизирован, вытаскивая несколько элементов из основного цикла. – Matthew

1

Вы можете использовать один из тех странных Spl итераторы для этого :)

$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); 
} 

Но на самом деле, простой цикл является инструментом для использования здесь.

+0

ничего себе. симпатичный элегантный. проверит в следующий раз .. спасибо. – Mina

Смежные вопросы