Skip to content
Advertisement

How to access and return specific value of a foreach in PHP

So I have a request-response that looks like this

$json='[ {"item_cat":"Stationary","items":[{"item_name":"A4 Paper","qty":"2"},{"item_name":"Test Paper","qty":"6"}],"total":"2"},
{"item_cat":"Computer Accessory ","items":[{"item_name":"Power pack","qty":"2"}],"total":"1"},
{"item_cat":"Material","items":[{"item_name":"T-Shirt","qty":"3"},
{"item_name":"Cap","qty":"5"}],"total":"2"}]';

I’m trying to get each item_name and qty so I can use them to manipulate my db. Here is what I’ve done

$data = json_decode($json, true);
$len = count($data);

    for($i =0; $i< $len; $i++){
            $item_length = count($data[$i]['items']);

        for($c=0; $c < $item_length; $c++){
            foreach ($data[$i]['items'][$c] as $key => $value ) {

                $qty = '';
                if($key == "qty"){
                    $qty = $data[$i]['items'][$c];
                    }

                if($key == 'item_name'){
                    $item_name = "$value";
                    }

                    $sql= $db->query("SELECT `stock` from `inventory` WHERE `item_name` = '$item_name'");
                    while ($sql1 = $sql->fetch_assoc()) {
                            $stock = $sql1['stock'];
                  }

                    if($stock > $qty ){

                        $stock_balance = $stock - $qty;

                    $quantity = (int)$qty;

                         $db->query("UPDATE `inventory` SET `stock` =  (`stock` - '$quantity')   WHERE `item_name` = '$item_name'");
                    }else{
                        echo "<h3> This Operation Not Allowed: Stock Balance Is Less Than The Request <h3>";
                    }

                }
            }
        }

A non-numeric value encountered, which is as a result of $qty because I’m not able to return just qty value. I’ve tried several other means. I’m really exhausted. Would appreciate any help please. Cheers!

Advertisement

Answer

Let’s decompose your code.

This is json:

[
   {
      "item_cat":"Stationary",
      "items":[
         {
            "item_name":"A4 Paper",
            "qty":"2"
         },
         {
            "item_name":"Test Paper",
            "qty":"6"
         }
      ],
      "total":"2"
   },
   {
      "item_cat":"Computer Accessory ",
      "items":[
         {
            "item_name":"Power pack",
            "qty":"2"
         }
      ],
      "total":"1"
   },
   {
      "item_cat":"Material",
      "items":[
         {
            "item_name":"T-Shirt",
            "qty":"3"
         },
         {
            "item_name":"Cap",
            "qty":"5"
         }
      ],
      "total":"2"
   }
]

Now the array loop without the SQL (to ensure that it works as expected):

$data = json_decode($json, true);
$len = count($data);

    for($i =0; $i< $len; $i++){
            $item_length = count($data[$i]['items']);

        for($c=0; $c < $item_length; $c++){
            foreach ($data[$i]['items'][$c] as $key => $value ) {

                $qty = '';
                if($key == "qty"){
                    $qty = $data[$i]['items'][$c];
                    }

                if($key == 'item_name'){
                    $item_name = "$value";
                    }

The problems here are: un-human variable names and not correct working with JSON object.

First of all, let us rename variables to something readable.

Example:

  • $data[$i] will be $catalog_entry (object)
  • $data[$i]['items'] will be $catalog_entry_items (array)
  • $data[$i]['items'][$c] will be $catalog_entry_item (one item, object)

Let’s change the code with new variables:

$data = json_decode($json, true);
$len = count($data);

for($i =0; $i< $len; $i++) {
    $catalog_entry = $data[$i];
    $catalog_entry_items = $data[$i]['items'];
    
    for($c=0; $c < sizeof($catalog_entry_items); $c++) {
        $catalog_entry_item = $data[$i]['items'][$c];
        $qty = $catalog_entry_item['qty'];
        $item_name = $catalog_entry_item['item_name'];
        echo $item_name . ' : ' . $qty . "n"; // <-- this is for testing
    }
}

Run this code and see the expected result:

A4 Paper : 2
Test Paper : 6
Power pack : 2
T-Shirt : 3
Cap : 5

Good, now we have qty and item_name.

Let’s make queries. First look at your code:

$sql= $db->query("SELECT `stock` from `inventory` WHERE `item_name` = '$item_name'");
                    while ($sql1 = $sql->fetch_assoc()) {
                            $stock = $sql1['stock'];
                  }

Two strange things: 1) possible SQL injection, 2) replace $stock variable many times with new value (if we have more than 1 row for item in inventory).

Anyway, if this code is working (I can’t check), then we come to next part:

if ($stock > $qty ) {
    $stock_balance = $stock - $qty;
    $quantity = (int)$qty;
    $db->query("UPDATE `inventory` SET `stock` =  (`stock` - '$quantity')   WHERE `item_name` = '$item_name'");
} else {
    echo "<h3> This Operation Not Allowed: Stock Balance Is Less Than The Request <h3>";
}

First, unnecessary cast to integer, so remove line $quantity = (int)$qty; and put $stock_balance into query. We will have:

if ($stock >= $qty ) {
    $stock_balance = $stock - $qty;
    $db->query("UPDATE `inventory` SET `stock` =  $stock_balance WHERE `item_name` = '$item_name'");
} else {
    echo "<h3> This Operation Not Allowed: Stock Balance Is Less Than The Request <h3>";
}

…well… not only you are exhausted, so I will end now. Ask if something is not correct or not understandable.

User contributions licensed under: CC BY-SA
5 People found this is helpful
Advertisement