为什么数组中充满对象而不是附加对象?

时间:2019-03-23 14:13:27

标签: php

我正在构建一个应用程序,该应用程序从服务器接收一个产品列表(例如)并显示它们。我正在使用PHP和Apache从SQL Server数据库(几乎是REST API)中检索列表。在构建数组并对其进行编码时,我注意到我的数组有10个元素(或更多,目前我设置了测试限制),每个元素都是最后一个。

我尝试使用$arr[] = $prodarray_push($arr, $prod),或创建一个临时数组并合并它们,但结果仍然相同。我还尝试过从macOS Apache切换到Windows安装或Linux安装(我想可能是Apache / PHP版本)。

$prod = new StdClass(); $arr = array();

$search = $_GET['search'];
$search = "%$search%";

$sql = "SELECT TOP 10
            product, qty
        FROM
            table
        WHERE
            product LIKE ?";
$stmt = sqlsrv_prepare( $conn, $sql, array($search));
sqlsrv_execute( $stmt );
$i = 0;
if ( $stmt === false ) {
    die( print_r( sqlsrv_errors(), true) );
}
else {
    while ( $row=sqlsrv_fetch_array($stmt, SQLSRV_FETCH_ASSOC) ) {
        $prod->mainInfo =  $row['product'];
        $prod->secondInfo = $row['qty'];
        $arr[] = $prod;
    }
}
http_response_code(200);
echo json_encode($arr);

结果是这些行中的东西(有更多行,但由于不相关,所以我只包含三行):

[
  {
    "mainInfo": "product3",
    "secondInfo": "qty3"
  },
  {
    "mainInfo": "product3",
    "secondInfo": "qty3"
  },
  {
    "mainInfo": "product3",
    "secondInfo": "qty3"
  }
]

如果我要加载三个产品。第三个乘积显示在数组的所有元素中。应该是这样的:

[
  {
    "mainInfo": "product1",
    "secondInfo": "qty1"
  },
  {
    "mainInfo": "product2",
    "secondInfo": "qty2"
  },
  {
    "mainInfo": "product3",
    "secondInfo": "qty3"
  }
]

3 个答案:

答案 0 :(得分:0)

您要一遍又一遍地修改 same 对象。即使已将其添加到数组中,它也会影响该 single 对象。而且您的数组仅获得对同一个对象的多个引用。

要解决此问题,请确保$prod是每次迭代的新对象。

所以移动这一行:

$prod = new StdClass(); 

...在循环内:

while ( $row=sqlsrv_fetch_array($stmt, SQLSRV_FETCH_ASSOC) ) {
    $prod = new StdClass(); // <----
    $prod->mainInfo =  $row['product'];
    $prod->secondInfo = $row['qty'];
    $arr[] = $prod;
}

或者,您可以使用(object)强制转换并一次性分配新对象,而无需使用$prod变量:

while ( $row=sqlsrv_fetch_array($stmt, SQLSRV_FETCH_ASSOC) ) {
    $arr[] = (object) [
        "mainInfo" => $row['product'],
        "secondInfo" => $row['qty']
    ];
}

答案 1 :(得分:0)

php中的对象始终被引用处理。因此,每次在一个地方修改$prod时,其他地方都会对其进行修改。为避免这种情况,clone对象并使用克隆的副本:

while ( $row=sqlsrv_fetch_array($stmt, SQLSRV_FETCH_ASSOC) ) {
    $newProd = clone $prod;
    $newProd->mainInfo =  $row['product'];
    $newProd->secondInfo = $row['qty'];
    $arr[] = $newProd;
}

答案 2 :(得分:0)

对象通过引用更新。

这意味着,即使您过去将对象放入数组,值也会随着您修改对象而动态变化。基本上,您一遍又一遍地修改同一对象。

您可以使用newclone

创建对象的新实例。
while ( $row=sqlsrv_fetch_array($stmt, SQLSRV_FETCH_ASSOC) ) {
    $_prod = clone $prod; //copy the object
    $_prod ->mainInfo =  $row['product'];
    $_prod ->secondInfo = $row['qty'];
    $arr[] = $_prod;
}