hyvor/php-json-exporter

将大量数据集导出到JSON文件而不会耗尽内存

0.0.3 2023-04-11 15:12 UTC

This package is auto-updated.

Last update: 2024-09-13 17:55:52 UTC


README

为什么创建这个库

Hyvor Talk,我们有客户在其网站上拥有数百万条评论,他们希望定期导出数据以备份和分析。我们的第一个导出器是为了从数据库中获取所有记录并从中创建JSON文件,这会将所有数据都加载到内存中。它适用于小型网站,但大型网站无法使用此方法,因为服务器会因为内存耗尽而崩溃。因此,我们创建了这个库,将数据导出到磁盘上的JSON文件,而不将其加载到内存中。

你可以做什么

这个库的主要目的是将大量的小型对象数组(例如,表行)导出到磁盘上的JSON文件。你可以创建包含多个集合和直接值的JSON文件。

{
    "collection-1": [
        // an array of objects (rows)
        {},
        {},
        {}
    ],
    "collection-2": [
        {},
        {},
        {}
    ],
    "direct-value": "value"
}

集合中的每个对象都可以代表数据库表中一行。预期数组很长(包含很多对象/行)。

安装

composer require hyvor/php-json-exporter

使用

use Hyvor\JsonExporter\File;

$file = new File('export-file.json'); // you can use a relative or absolute path

// add a collection named users
$usersCollection = $file->collection('users');
$usersCollection->addItems(getUsers());
$usersCollection->addItems(getUsers(100));

// add a collection named 
$postsCollection = $file->collection('posts');
$postsCollection->addItems(getPosts());
$postsCollection->addItems(getPosts(100));
$postsCollection->addItems(getPosts(200));

// add a direct value
// the value will be JSON encoded
// you can use arrays, objects, strings, numbers, booleans, null
$file->value('direct-value', 'value');
$file->value('direct-value-2', $myObject);
$file->value('json-value', '{"name": "John"}', encode: false); // the value will not be JSON encoded

// call this function finally
$file->end();

在上面的示例中,getUsers()getPosts()是假设的函数,返回数组形式的有限记录(100条),并支持偏移量参数以跳过已添加的记录。通常,你会在循环或回调中调用addItems()方法(下面有Laravel示例)。上述示例的JSON输出将如下所示

{
    "users": [
        // array of JSON-encoded user objects
    ],
    "posts": [
        // array of JSON-encoded post objects
    ],
    
    "direct-value": "value",
    "direct-value-2": {
        // JSON-encoded object
    },
    "json-value": {"name": "John"}
    
}

Laravel集合示例

你可以使用Laravel分块来生成大型集合。

use Hyvor\JsonExporter\File;

$file = new File('export-file.json');

$usersCollection = $file->collection('users');
User::chunk(200, fn ($users) => $usersCollection->addItems($users->toArray()));

$file->end();