Рубрики
Uncategorized

PHP использует fputcsv для реализации операции экспорта больших данных

Автор оригинала: David Wong.

В этой статье приведен пример, показывающий, как экспортировать большие данные с помощью fputcsv в PHP. Подробности заключаются в следующем:

Чтобы поэкспериментировать с экспортом больших данных, мы сами создаем большую таблицу. Структура таблицы выглядит следующим образом:

CREATE TABLE `tb_users` (
 `id` int(11) unsigned NOT NULL AUTO_ Create comment 'user ID',
 `Name ` varchar (32) default '' comment 'user name',
 `Age ` tinyint (3) default '0' comment 'user age',
 `Desc ` varchar (255) default '' comment 'user description',
 `Phone ` varchar (11) default '' comment 'user's mobile phone',
 `QQ ` varchar (16) default '' comment 'user QQ',
 `Email ` varchar (64) default '' comment 'user mailbox',
 `Addr ` varchar (255) default '' comment 'user address',
 PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

Затем напишите PHP-скрипт для вставки данных в таблицу. Код выглядит следующим образом:

php
set_time_limit(0);
ini_set('memory_limit', '128M');

//If you use the string class of tp3.2, an error will be reported under php7. Please change the class name
require './String.class.php';
use Org\Util\NewString;

$begin = microtime(true);

$db = new mysqli('127.0.0.1', 'root', '', 'test');

if($db->connect_error) {
  die('connect error');
}
//Data insertion statement
$insSql = '';

//One million data, divided into 200 steps, each step inserts 5000 pieces
$step = 200;
$nums = 5000;

for($s = 0; $s < $step; ++$s) {
  $insSql = 'INSERT INTO tb_users VALUES';
  for($n = 0; $n < $nums; ++$n) {
    $name = NewString::randString(3, 4);
    $age = mt_rand(1, 120);
    $desc = NewString::randString(64, 4);
    $phone = NewString::randString(11, 1);
    $qq = NewString::randString(13, 1);
    $email = $qq . '@qq.com';
    $addr = NewString::randString(128, 4);
    $insSql .= "(NULL, '{$name}', $age, '{$desc}', '{$phone}', '{$qq}', '{$email}', '{$addr}'),";
  }
  $insSql = rtrim($insSql, ',');
  $db->query($insSql);
}
$end = microtime(true);
Echo 'time:', $end - $begin;

$db->close();

Класс строк tp3.2, используемый в нем, можно загрузить с официального сайта TP. Это занимает более 2 часов, а окончательный размер данных составляет 662 млн.

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

connect_error) {
  die('connect error');
}

//We tried to export 1 million data from the database with fputcsv
//We take 10000 pieces of data at a time and execute them in 100 steps
//If the online environment cannot support reading 10000 pieces of data at one time, you can reduce $nums and increase $step accordingly.
$step = 100;
$nums = 10000;

//Set title
$title = array ('id ',' user name ',' user age ',' user description ',' user mobile ',' user QQ ',' user email ',' user address');
foreach($title as $key => $item) {
  $title[$key] = iconv('UTF-8', 'GBK', $item);
}
//Write the title to the standard output
fputcsv($fp, $title);

for($s = 1; $s <= $step; ++$s) {
  $start = ($s - 1) * $nums;
  $result = $db->query("SELECT * FROM tb_users ORDER BY id LIMIT {$start},{$nums}");
  
  if($result) {
    while($row = $result->fetch_assoc()) {
      foreach($row as $key => $item) {
        //We have to transcode here, otherwise it will be messy
        $row[$key] = iconv('UTF-8', 'GBK', $item);
      }
      fputcsv($fp, $row);
    }
    $result->free();
    
    //Refresh buffer for every 10000 data
    ob_flush();
    flush();
  }
}

$end = microtime(true);
Echo 'time:', $end - $begin;

Весь процесс занимает 5 минут, а конечный размер сгенерированного CSV-файла составляет 420м.

Для того, как экспортировать большие данные с помощью phpexcel, лучшего решения не существует. Некоторые методы кэширования, предоставляемые phpexcel, сжатие данных, хотя использование памяти невелико, используемое время больше и время для пространства, очевидно, не являются лучшим решением. Более надежный метод состоит в том, чтобы сгенерировать несколько адресов ссылок для загрузки, перенести данные, которые вы хотите загрузить, на текущий номер страницы в форме get, разбить данные на страницы в фоновом режиме, а затем экспортировать их.

Например, у вас есть форма данных запроса с идентификатором searchfrm, а затем вы хотите разделить экспортированные данные на 10000 частей (phpexcel может экспортировать 10000 частей одновременно, и эффективность в порядке).

Name < input type = text "name = uname" > < input type = button "value = export summary result" >

Для получения дополнительной информации о PHP читатели, интересующиеся им, могут ознакомиться со следующими темами: Вводный курс по работе с базами данных PHP + MySQL, краткое изложение навыков программирования баз данных PHP + redis, вводный курс объектно-ориентированного программирования PHP и краткое изложение общих навыков работы с базами данных PHP

Я надеюсь, что эта статья будет полезна для программирования на PHP.