如何跟踪 PHP 中多个 json 对象的记录号

How can I keep track of record number across multiple json objects in PHP

我有一个客户记录导出,需要拆分为 500 条记录的几块。我通过 REST 请求获取每个块,将其保存到我的服务器:

public function createImportFile($json)
{
    $filePath = storage_path().'/import/'.$this->getImportFileName($this->import->chunkNumber);
    $importFile = fopen($filePath, 'w');
    $array = json_decode($json);

    fwrite($importFile, $json);
    fclose($importFile);
    return $filePath;

}

然后在抓取所有块后,我导入所有记录。我想知道在所有块中找到第 N 条记录的最佳方法是什么?

目前,我将要查找的记录数除以块总数,以找出记录将位于哪个块中。然后,我得到前面块的总记录数并减去这个数字从记录号获取记录在块中的位置。

while ($this->recordNumber <= $this->totalRecords) {
            $item = $this->getRecord($this->recordNumber);
            if (empty($item)) {
                $this->recordNumber++;
                continue;
            }
            $results = $this->translateItem($item);
            $this->recordNumber++;
 }
public function getRecord($recordNumber)
{
    if ($this->import->isChunkedImport()) {
        $chunkNumber = (integer) $this->returnChunkFromRecordNumber($recordNumber);
        $countInPrevChunks = intval($this->returnRecordCountForPrevChunks($chunkNumber));
        $chunkPosition = intval($this->getChunkPosition($recordNumber, $countInPrevChunks));
        $jsonObj = $this->getJsonObjectForChunkNumer($chunkNumber);
        return $jsonObj[$chunkPosition];
    } 
    else {
        $chunkPosition = $this->getChunkPosition($recordNumber, 0);
        $filePath = storage_path().'/import/'.$this->getImportFileName();
        return (array) json_decode(file_get_contents($filePath))[$chunkPosition];
    }
}

private function &getJsonObjectForChunkNumer($chunkNumber)
{
    if ($this->currentFileArray == null || ($chunkNumber != $this->lastChunkNumber)) {
        $filePath = storage_path().'/import/'.$this->getImportFileName($chunkNumber);
        $this->currentFileArray = json_decode(file_get_contents($filePath), true);
        $this->lastChunkNumber = $chunkNumber;
    }
    return $this->currentFileArray;
}

public function getChunkCount()
{
    $filePath = storage_path().'/import/'.$this->getImportFileName();
    return count(json_decode(file_get_contents($filePath)));
}

public function returnChunkFromRecordNumber($recordNumber)
{

    if ($recordNumber >= $this->getChunkCount()) {
        if (is_int($recordNumber/$this->getChunkCount())) {
            if (($recordNumber/$this->getChunkCount()) == 1) {
                return intval(1);
            }
            return intval(($recordNumber/$this->getChunkCount())-1);
        }
        else {
            return intval($recordNumber/$this->getChunkCount());
        }
    }
    else {
        return intval(0);
    }
}

public function getChunkPosition($recordNumber, $countInPrevChunks)
{
    $positionInChunk = $recordNumber - $countInPrevChunks;
    if ($positionInChunk == 0) {
        return $positionInChunk;
    }
    return $positionInChunk - 1;
}

public function returnRecordCountForPrevChunks($chunkNumber)
{
    if ($chunkNumber == 0) {
        return 0;
    }
    else {
        return $this->getChunkCount() * $chunkNumber;

我尝试将块中的块和记录的第一个键都解释为 0,但我仍然缺少导入的最后一条记录。看起来我可能会使它变得比它需要的更复杂。我想知道是否有人有建议或更简单的方法来获取第 N 条记录。我考虑过可能只是在将记录与 REST 请求一起带入时对记录进行编号,然后我可以找到包含记录号作为数组键的块,然后 return 该记录:

public function createImportFile($json)
{
    $filePath = storage_path().'/import/'.$this->getImportFileName($this->import->chunkNumber);
    $importFile = fopen($filePath, 'w');
    if ($this->import->chunkNumber == 0 && $this->recordNumber == 0) $this->recordNumber = 1;
    $array = json_decode($json);
    $ordered_array = [];
    foreach ($array as $record) {
        $ordered_array[$this->recordNumber] = $record;
        $this->recordNumber++;
    }
    fwrite($importFile, json_encode($ordered_array));
    fclose($importFile);
    return $filePath;
}

但我不确定这是否是最好的方法。

如果有很多记录,您可以使用数据库 table。 MySQL 可以轻松处理数万条记录。您甚至不需要存储整个记录。也许只是:

record_no | chunk_no | position_in_chunk
  • record_no:主键。此记录的唯一标识符
  • chunk_no: 哪个块包含记录
  • position_in_chunk: 块中记录所在的位置

在 table 上放置一个 UNIQUE(chunk_no, position_in_chunk) 索引。

然后,当您提取记录时,为它们分配一个编号,构建数据库 table,并在将记录写入磁盘时保存 table。将来,要获取特定记录,您只需要它的编号即可。

如果您不想使用数据库,也可以将此数据存储为 JSON 文件,但检索性能会因必须打开和解析大 JSON 文件而受到影响每次。