开发者

MySQL to MySQLi Query issue when joining arrays

I'm trying to convert some MYSQL querys to MYSQLI, but I'm having an issue, below is part of the script I am having issues with, the script turn a query into 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 f开发者_高级运维ile built. \n\n"; 
} 

// Return the completed file 
return $csv_file; 

The problem I am having is when building a header row for the column titles mysqli doesn't use field_names so I am fetching the column titles by using mysqli_fetch_assoc() and then implode() the array, adding the ,'s etc for the csv.

This works but when I produce the csv I am deleting the first data row when the header is active, when I remove my header part of the script and leave the header as null I get all data rows and a blank header (As expected).

So I must be missing something when joining my header to array to the $csv_file.

Can anyone point me in the right direction?

Many Thanks

Ben


A third alternative is to refactor the loop body as a function, then also call this function on the first row before entering the loop. You can use fputcsv as this function.

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

As this basically does the same thing as a do ... while loop, which would make more sense to use. I bring up this alternative to present the loop body refactoring technique, which can be used when a different kind of loop doesn't make sense.

Best of all would be to use both mysqli_result::fetch_fields and 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;

If you can require that PHP be at least version 5.3, you can replace the foreach that generates the header line with a call to array_map. There admittedly isn't much advantage to this, I just find the functional approach more interesting.

fputcsv($csv_stream, 
        array_map(function($field) {return $field->name}, 
                  $result->fetch_fields()));


As you observe, you're using the first row to obtain the field names but then not using the data from the row. Evidently, you need to change your code so that you get both of those things.

There are a number of ways you might do this. The most appropriate one is to use mysqli_fetch_fields() instead to get the field metadata from the result object.

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

Alternatively, you could make the loop lower down in the code a do... while instead of a while.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜