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

时间:2017-09-01 17:22:07

标签: php json chunks

我有一个客户记录导出,需要分成几个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请求,然后我可以找到包含记录号的Chunk作为数组键,然后返回该记录:

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

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

1 个答案:

答案 0 :(得分:1)

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

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

在表格上加上UNIQUE(chunk_no, position_in_chunk)索引。

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

如果您不想使用数据库,您也可以将此数据存储为JSON文件,但检索性能将不得不每次都打开并解析一个大型JSON文件。