【问题标题】:Saving Array as JSON to a file using PHP使用 PHP 将数组作为 JSON 保存到文件中
【发布时间】:2021-06-25 00:15:30
【问题描述】:
{"Files": [
    {"file_name": "Text_file.txt","path": "to_folder","file_id": "abc12345"},
    {"file_name": "Img.jpg","path": "to_folder","file_id": "abc12346"}
]}

我想使用 php 将文件上传的信息保存到 JSON 文件。

//Code: PHP class : Save() 
<?php
class Save
{
private $file = './files/data.json', $jsonstring = null, $jsonarray = array(), $temp = array(), $data = array();

public function __construct()
{
    $this->init();
}

private function init()
{
    if (!file_exists($this->file)) {
        touch($this->file);
        $this->read();
    } else {
        $this->read();
    }
}

private function read()
{
    $this->jsonstring = file_get_contents($this->file);
    $this->jsonarray = empty($this->jsonstring) ? array() : json_decode($this->jsonstring, true);
    $this->temp = (object) $this->jsonarray;
}

private function write($data, $collection = false)
{
    if ($collection) {
        if (empty($this->jsonarray) || $this->jsonarray == null && $this->jsonarray[$collection] == null) {
            unset($this->jsonarray);
            $this->jsonarray = array();
            $this->jsonarray[$collection] = array();
            array_push($this->jsonarray[$collection], $data);
            $this->jsonarray = json_encode($this->jsonarray);
            file_put_contents($this->file, $this->jsonarray);
            return 1;
        } elseif (property_exists($this->temp, $collection)) {
            // $this->jsonarray[$collection] = array_values($this->jsonarray[$collection]);
            array_push($this->jsonarray[$collection], $data);
            $this->jsonarray = json_encode($this->jsonarray);
            file_put_contents($this->file, $this->jsonarray);
            return 2;
        } elseif (!property_exists($this->temp, $collection)) {
            $this->jsonarray[$collection] = array();
            array_push($this->jsonarray[$collection], $data);
            $this->jsonarray = json_encode($this->jsonarray);
            file_put_contents($this->file, $this->jsonarray);
            return 3;
        }
    } else {
        if (empty($this->jsonarray) || $this->jsonarray == null) {
            unset($this->jsonarray);
            $this->jsonarray = array();
            array_push($this->jsonarray, $data);
            $this->jsonarray = json_encode($this->jsonarray);
            file_put_contents($this->file, $this->jsonarray);
            return 4;
        } else {
            $this->jsonarray = array_values($this->jsonarray);
            array_push($this->jsonarray, $data);
            $this->jsonarray = json_encode($this->jsonarray);
            file_put_contents($this->file, $this->jsonarray);
            return 5;
        }
    }
    return false;
}

public function push($data, $collection = false)
{
    if (is_array($data)) {
        $a =$this->write($data, $collection);
        if ($a) {
            return $a;
        }
        return false;
    }
    return false;
}

public function get($collection = false)
{
    if ($collection) {
        return json_encode($this->jsonarray[$collection]);
    }
    return json_encode($this->jsonarray);
}
}

现在的问题是,当我上传单个文件时,它可以正常工作 3-6 次,然后由于 JSON 格式为 null 或错误,它再次重置 JSON 文件。 & 当我一起上传 30 个文件时,会自动发送每个文件。 JS 代码 [...files].forEach(upload(file)) 它的行为很奇怪。这是写函数的回调 更新 JS:

function handelSelect(e) {
    let files;
    if (e.type == 'drop') {
         files = e.originalEvent.dataTransfer.files;
     } else {
          files = e.target.files;
     }
     if (files.length > 0) handleFiles(files);
 }
//handelFiles(files) send files using ajax(single request).

我哪里做错了?

【问题讨论】:

  • 这里少了点什么。你展示了一些有 Undefined Variable 问题的 PHP 代码,然后问一个关于一小段 JavaScript 的问题。
  • 如果一个请求读取了文件的一个版本,然后另一个请求写入它,那么之前的写入将被覆盖,或者更糟。为 file_put_contents 尝试 LOCK_EX,或者更好,不要使用 db 存储在 json 中
  • 让我更新代码

标签: php arrays json multidimensional-array


【解决方案1】:

在检查了执行时间后,我得出结论: Ajax 发送请求的方式比 PHP 可以写入文件更快; https://www.php.net/manual/en/function.file-put-contents.php 基准如下:

file_put_contents() 用于 1,000,000 次写入 - 3 个基准测试的平均值:

  • 真正的 0m3.932s
  • 用户0m2.487s
  • 系统 0m1.437s

fopen() fwrite() 用于 1,000,000 次写入,fclose() - 3 个基准测试的平均值:

  • 真实0m2.265s
  • 用户0m1.819s
  • sys 0m0.445s

所以我在 javascript 中延迟了请求。

Object.keys(files).forEach((file) => {
    setTimeout(() => {
        uploadFile(files[file], file);
    }, file*2500);
});

如果有人有更好的解决方案,请分享。

【讨论】:

    猜你喜欢
    • 2015-10-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-03-19
    • 2018-08-13
    • 1970-01-01
    • 2017-05-10
    • 1970-01-01
    相关资源
    最近更新 更多