【问题标题】:Creating a correct JSON output that follows JSON:API convention创建遵循 JSON:API 约定的正确 JSON 输出
【发布时间】:2019-11-19 20:16:59
【问题描述】:

我正在尝试解析存储在我的数据库中的一些 JSON,对其进行转换,然后将其发送到第 3 方 API(通过 webhook)。我目前停留在 JSON 输出格式。我正在尝试遵循 JSON:API 的标准。

这是我的数据库列fields.content的输入:

[{"0": "Page 1, col 1.", "1": "", "2": ""}, {"0": "", "1": "Page 1, col 2.", "2": ""}, {"0": "", "1": "", "2": "Page 1, col 3"}]

如您所见,这是一个由对象组成的 JSON 数组。每个对象代表一行,每个键代表一列。这可以被视为:

___________________________________________________
| COL 1         | COL 2          | COL 3          |
___________________________________________________
| Page 1, col 1.|                |                |
|---------------|----------------|----------------|
|               |Page 1, col 2.  |                |
|---------------|----------------|----------------|
|               |                | Page 1, col 3. |
---------------------------------------------------

在我的模型 Field.php 中,我使用 Laravel 铸造:

protected $casts = [
     'content' => 'array'
];

自动将json字符串转为数组:

dd($content) //$content is the json string from the database

返回:

array:3 [▼
  0 => array:3 [▼
    0 => "Page 1, col 1."
    1 => ""
    2 => ""
  ]
  1 => array:3 [▼
    0 => ""
    1 => "Page 1, col 2."
    2 => ""
  ]
  2 => array:3 [▼
    0 => ""
    1 => ""
    2 => "Page 1, col 3"
  ]
]

所以考虑一下我对这个数组做了什么,比如将单词 Page 替换为 Section

$out = [];
foreach ($content as $col => $rows) {
    $out[$col] = str_replace('Page', 'Section', $rows);
}
dd($out);

这会返回:

array:3 [▼
  0 => array:3 [▼
    0 => "Section 1, col 1."
    1 => ""
    2 => ""
  ]
  1 => array:3 [▼
    0 => ""
    1 => "Section 1, col 2."
    2 => ""
  ]
  2 => array:3 [▼
    0 => ""
    1 => ""
    2 => "Section 1, col 3"
  ]
]

我现在想更新我的数据库fields.content,以反映这一变化。但是,当将其重新保存到数据库时,例如:


$field = Field::find(1);
$field->content = $out;
$field->save();

现在保存为数组数组:

[["Section 1, col 1.", "", ""], ["", "Section 1, col 2.", ""], ["", "", "Section 1, col 3"]]

这意味着当我通过我的 webhook 发送它时,它不再遵循与开始时相同的 JSON 模式。

我曾尝试对数组进行 json_encode,例如:

$field->content = [json_encode($out, JSON_FORCE_OBJECT)]

但这不会产生所需的输出/有效的 JSON。

谁能帮助我如何使用 Laravel/PHP 转换我的 JSON 对象,并将其重新保存到我的数据库并保持初始有效的 JSON:API 格式?

【问题讨论】:

  • 你不应该改造它。该数组将自动编码为 json。演员表告诉 Laravel 模型应该期待一个数组。只需将对象更新为$field->content = $out;
  • 我正在使用str_replace 对其进行转换,并希望将其再次保存到数据库中。我已经绑定了$field->content = $out,正如我在问题中所说,它将它保存为数组数组:[[...]]
  • 嗯,没错。您的初始数据是一个未编号的数组数组。这是典型的json。如果没有,您将有 3 个单独的 json 结果,因此数据库中有 3 个条目。

标签: php arrays json laravel laravel-5


【解决方案1】:

结果绝对正确。这是一个有效的数组表示。你所拥有的 0, 1... 是一个数组索引,根据 PHP,它在序列化为字符串时不会反映。

怎么办?

直接转换为对象(JSON 是对象而不是数组)。

protected $casts = [
     'content' => 'object'
];

要将$content 转换为循环,您可以使用以下内容代替dd

$content = json_decode(json_encode($content), true);

要进行解析,请尝试以下操作:

$out = [];

$i = 0;
foreach($content as $con){
    $result = [];
    foreach ($con as $col => $rows) {
        $result[$col] = str_replace('Page', 'Section', $rows);
    }
    $out = array_merge($out, [$i => $result]);
}
$out = json_encode($out);

// Loose the dd($out) part.

免责声明:我没来得及尝试。

【讨论】:

  • 如果我要转换为object,那么我无法在我的循环中对其进行转换(不将其转换为数组),从而回到第一方......
  • 我刚刚看到您的编辑。 $content = json_decode($content, true) 不起作用,因为 json_decode() 需要一个字符串。
  • @oliverbj 那么如果不是字符串,那么您的数据以什么形式提供?它在您显示的代码中字面意思是dd($content) //$content is the json string from the database
  • @misorude 是的,但我还指定在我的模型上使用$casts'content' => 'array'
  • @oliverbj 好吧,如果它没有达到你想要的效果,也许就停止这样做吧?如果您只是对从数据库获得的字符串值使用 json_decode,那么您的问题将不存在 - 您将获得一个数组 of 对象,以便您可以循环遍历它,and 使用 $foo->bar 语法来访问循环内的对象属性。之后再次将其编码为 JSON,将自动为您提供所需的结构(因为您并没有首先通过将其转换为其他东西来破坏该结构。)
【解决方案2】:

转换后:

$out = [];
foreach ($content as $col => $rows) {
    $out[$col] = str_replace('Page', 'Section', $rows);
}

现在您可以使用以下代码重新格式化:

 $result"[";
 foreach ($out as $value) {
     $string = json_encode($value);
     $string = str_replace('[', '{', $string);
     $string = str_replace(']', '}', $string);
     $result .= $string .",";
 }
 $result= rtrim($result, ',');
 $result.= "]";

 echo $result;
 // [{"Section 1, col 1.","",""},{"","Section 1, col 2.",""},{"","","Section 1, col 3"}]

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多