始终如一地迭代 API 响应,该响应可以是一个对象或对象数组

Consistently iterate API response which may be an object or an array of objects

提问人:Matthijs 提问时间:10/6/2023 最后编辑:mickmackusaMatthijs 更新时间:10/7/2023 访问量:109

问:

我有以下JSON代码。

{
  "Artikelnr":"1000",
  "Vooraad_NL":2.0,
  "Voorraad_DE":1.0,
  "Voorraad_BE":0.0
}

当我使用 foreach 遍历 json 时,它会循环 4 次。我怎样才能让它只循环浏览文章的数量。就像 1 篇文章只循环一次。当 json 循环中有 3 篇文章时,循环 3 次。

我使用以下 php 代码:

$data = json_decode(file_get_contents('php://input'), true);

if ((isset($data) && $data != "") && (json_last_error() === JSON_ERROR_NONE)) {

foreach ($data as $key => $val) {
    $articlenumber = $data['Artikelnr'];
    $voorraad_nl = $data['Vooraad_NL'];
    $voorraad_de = $data['Vooraad_DE'];
    $voorraad_be = $data['Vooraad_BE'];
}

}
PHP 数组对象 类型 foreach

评论

0赞 user3783243 10/6/2023
你构建 JSON 吗?如果是这样,将其放入数组中将允许 1 个循环。否则,如果您只想在数据点上运行循环,则可以使用。if($key != 'Artikelnr') { continue; }"Artikelnr":"1000",
0赞 Matthijs 10/6/2023
JSON 由 Microsoft API 发送。当产品在我们的网站上销售时,Microsoft Business Central API 会发送库存更新。
0赞 user3783243 10/6/2023
它像那样发送或像?这样一来,所有点都将在一个层面上得到满足。就这样,它们都处于同一水平。我不明白他们如何使用这种结构同时发回 2 个结果[{ "Artikelnr":"1000", "Vooraad_NL":2.0, "Voorraad_DE":1.0, "Voorraad_BE":0.0 }]
1赞 Damian Chudobiński 10/6/2023
当我在 foreach 中使用简单的 echo 运行您的代码时,它只会循环,并且只回显每个项目一次
1赞 mickmackusa 10/6/2023
所以你基本上需要写一个条件:php is variable a array or object 如果你的脚本需要一个 objectArray,但你有一个对象,你需要将该对象推送到一个父数组中。您的问题对于应用程序正在接收的可变有效负载并不十分清楚。请创建一个完整的最小可重现示例

答:

4赞 The Alpha 10/6/2023 #1

您拥有以下条件json

{
  "Artikelnr":"1000",
  "Vooraad_NL":2.0,
  "Voorraad_DE":1.0,
  "Voorraad_BE":0.0
}

所以,当你循环它之后,你会得到这样的东西:json_decode

Array
(
    [Artikelnr] => 1000
    [Vooraad_NL] => 2
    [Voorraad_DE] => 1
    [Voorraad_BE] => 0
)

因此,当您循环$data时:

$data = json_decode(file_get_contents('php://input'), true);

foreach ($data as $key => $val) {
    $articlenumber = $data['Artikelnr'];
    $voorraad_nl = $data['Vooraad_NL'];
    $voorraad_de = $data['Vooraad_DE'];
    $voorraad_be = $data['Vooraad_BE'];
}

循环遍历包含 4 个项目的数组,您没有使用内部循环,而是使用循环本身,因此您会看到相同的项目 4 次。$data$key/$val$data

如果你只有一个,那么你就不需要循环,你可以简单地做同样的事情,没有循环,例如:json

echo $data['Artikelnr'];
echo $data['Vooraad_NL'];
echo $data['Voorraad_DE'];
echo $data['Voorraad_BE'];

如果您不确定结果是对象数组还是单个对象,您可以尝试如下操作:

// Decode without passing the true in the json_encode
$data = json_decode(file_get_contents('php://input'));

if (is_object($data)) {
    $data->Artikelnr;
    $data->Vooraad_NL;
    $data->Vooraad_DE;
    $data->Vooraad_BE;
} else {
    foreach ($data as $item) {
        $articlenumber = $item->Artikelnr;
        $voorraad_nl   = $item->Vooraad_NL;
        $voorraad_de   = $item->Vooraad_DE;
        $voorraad_be   = $item->Vooraad_BE;
    }
}

如果你想把每个项目都作为一个数组,那么你可以转换对象(stdClass),例如:(array)

foreach ($data as $item) {
    $item = (array) $item;
    // Now you can use the item as an array
    $articlenumber = $item['Artikelnr'];
    // ...
}

对于单个对象,也可以这样做,例如:

if (is_object($data)) {
    $data = (array) $data;
    $articlenumber = $data['Artikelnr'];
}
1赞 mickmackusa 10/6/2023 #2

我建议有条件地将任何遇到的对象转换为 objectArrays,并无条件地编写一个循环来迭代 objectArray。

所有应用程序都应努力稳定其输入/输出数据类型,以便更简化脚本(很遗憾,您正在访问的终结点没有考虑这一点)。

代码:(演示)

$data = json_decode($response);
if (is_object($data)) {
    $data = [$data];
}
foreach ($data as $obj) {
    var_dump($obj);
}