MySQL to MySQLi Query проблема при объединении массивов - PullRequest
0 голосов
/ 16 июля 2011

Я пытаюсь преобразовать некоторые запросы MYSQL в MYSQLI, но у меня возникла проблема, ниже приведена часть скрипта, с которым у меня возникают проблемы, скрипт превращает запрос в csv:

$columns = (($___mysqli_tmp = mysqli_num_fields($result)) ? $___mysqli_tmp : false); 

// Build a header row using the mysql field names 

$rowe = mysqli_fetch_assoc($result);
$acolumns = array_keys($rowe);
$csvstring = '"=""' . implode('""","=""', $acolumns) . '"""';
$header_row = $csvstring; 

// Below was used for MySQL, Above was added for MySQLi
//$header_row = '';
//for ($i = 0; $i < $columns; $i++) {
//  $column_title = $file["csv_contain"] . stripslashes(mysql_field_name($result, $i)) . $file["csv_contain"];
//  $column_title .= ($i < $columns-1) ? $file["csv_separate"] : '';
//  $header_row .= $column_title;
//  } 
$csv_file .= $header_row . $file["csv_end_row"]; // add header row to CSV file 

// Build the data rows by walking through the results array one row at a time 
$data_rows = ''; 
while ($row = mysqli_fetch_array($result)) { 
  for ($i = 0; $i < $columns; $i++) { 
    // clean up the data; strip slashes; replace double quotes with two single quotes 
    $data_rows .= $file["csv_contain"] .$file["csv_equ"] .$file["csv_contain"] .$file["csv_contain"] . preg_replace('/'.$file["csv_contain"].'/', $file["csv_contain"].$file["csv_contain"], stripslashes($row[$i])) . $file["csv_contain"] .$file["csv_contain"] .$file["csv_contain"];
    $data_rows .= ($i < $columns-1) ? $file["csv_separate"] : ''; 
  } 
  $data_rows .= $this->csv_end_row; // add data row to CSV file 
} 
$csv_file .= $data_rows; // add the data rows to CSV file 

if ($this->debugFlag) { 
  echo "Step 4 (repeats for each attachment): CSV file built. \n\n"; 
} 

// Return the completed file 
return $csv_file; 

Проблема, с которой я сталкиваюсь, заключается в том, что при построении строки заголовка для заголовков столбцов mysqli не использует field_names, поэтому я выбираю заголовки столбцов, используя mysqli_fetch_assoc(), а затем implode() массив, добавляя ,.и т.д. для CSV.

Это работает, но когда я создаю CSV, я удаляю первую строку данных, когда заголовок активен, когда я удаляю свою часть заголовка скрипта и оставляю заголовок как ноль, я получаю всестроки данных и пустой заголовок (как и ожидалось).

Так что я должен что-то упустить при соединении моего заголовка с массивом в $csv_file.

Может кто-нибудь указать мне правильное направление?

Большое спасибо

Бен

Ответы [ 2 ]

0 голосов
/ 17 июля 2011

Третьим вариантом является рефакторинг тела цикла как функции, а затем вызов этой функции в первой строке перед входом в цикл.Вы можете использовать fputcsv в качестве этой функции.

$csv_stream = fopen('php://temp', 'r+');

if ($row = $result->fetch_assoc()) {
    fputcsv($csv_stream, array_keys($row));

    fputcsv($csv_stream, $row);
    while ($row = $result->fetch_row()) {
        fputcsv($csv_stream, $row);
    }

    fseek($csv_stream, 0);
}
$csv_data = stream_get_contents($csv_stream);
if ($this->debugFlag) { 
  echo "Step 4 (repeats for each attachment): CSV file built. \n\n"; 
} 

// Return the completed file
return $csv_data;

Поскольку это в основном то же самое, что и цикл do ... while, который имеет больше смысла в использовании.Я привел эту альтернативу, чтобы представить технику рефакторинга тела цикла, которую можно использовать, когда цикл другого типа не имеет смысла.

Лучше всего было бы использовать mysqli_result::fetch_fields и fputcsv

$csv_stream = fopen('php://temp', 'r+');

$fields = $result->fetch_fields();
foreach ($fields as &$field) {
    $field = $field->name;
}
fputcsv($csv_stream, $fields);

while ($row = $result->fetch_row()) {
    fputcsv($csv_stream, $row);
}

fseek($csv_stream, 0);
$csv_data = stream_get_contents($csv_stream);
if ($this->debugFlag) { 
  echo "Step 4 (repeats for each attachment): CSV file built. \n\n"; 
} 

// Return the completed file
return $csv_data;

Если вы можете потребовать, чтобы PHP был как минимум версии 5.3, вы можете заменить foreach, генерирующий строку заголовка, вызовом array_map.По общему признанию, нет большого преимущества в этом, я просто нахожу функциональный подход более интересным.

fputcsv($csv_stream, 
        array_map(function($field) {return $field->name}, 
                  $result->fetch_fields()));
0 голосов
/ 16 июля 2011

Как вы заметили, вы используете первую строку для получения имен полей, но затем не используете данные из строки.Очевидно, вам нужно изменить свой код, чтобы получить обе эти вещи.

Существует несколько способов сделать это.Наиболее подходящим является использование mysqli_fetch_fields() вместо того, чтобы получить метаданные поля из результирующего объекта.

http://www.php.net/manual/en/mysqli-result.fetch-fields.php

В качестве альтернативы, вы можете сделать цикл ниже в коде a do... while вместо while.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...