Link to home
Start Free TrialLog in
Avatar of Sheldon Livingston
Sheldon LivingstonFlag for United States of America

asked on

Incrementing foreach loop

Here is my php code:
foreach($_POST as $key => $value){
	if (substr($key,-5) == "O~U~T"){
		if (is_numeric($value)){
			if ($value > 0){
				$query = "INSERT INTO myTable " . 
				   "Values " .
				   "(" . $value . ", " .
				   "" . $value* . ", " .
				   "" . $value** . ")";

				$result = mysqli_query($objConnection, $query);
			}
		}
	}
}

Open in new window

I'd like $value* to be the next value and $value** to be the value after that.
In other words I'd like to be able to increment the foreach mid stream.

Any thoughts?
Avatar of Julian Hansen
Julian Hansen
Flag of South Africa image

You do it by using
current()
next()
key()
<?php
// DUMMY DATA
$_POST = array(
   'a' => 'b',
   'O~U~T' => 2,
   'next' => 3,
   'nextnext' => 4
);
// LOOP WHILE ARRAY HAS ELEMENTS
while($value = current($_POST)) {
  // ... FROM YOUR CODE
  if (substr(key($_POST),-5) == "O~U~T"){
    if (is_numeric($value)){
      if ($value > 0){
        // GET THE NEXT VALUE
        $next = next($_POST);
        // ... AND THE NEXT 
        // NB YOU PROBABLY WANT TO DO SOME SANITY CHECKS HERE
        // TO MAKE SURE THAT THERE ARE NEXT VALUES
        $nextnext = next($_POST);
        $query = "INSERT INTO myTable " . 
           "Values " .
           "(" . $value . ", " .
           "" . $next . ", " .
           "" . $nextnext . ")";

        //$result = mysqli_query($objConnection, $query);
        // DEBUG DUMP RESULT
        echo $query;
      }
    }
  }
  next($_POST);
}

Open in new window

You may want to see the SPL for some ideas about this.
http://php.net/manual/en/book.spl.php
Avatar of Sheldon Livingston

ASKER

No joy Julian.  Let me explain further...

I have a form and submit it.  On the action page this code reveals this listing (partial listing):
foreach($_POST as $key => $value){
	echo $_POST . " - " . $key . " - " . $value . "<br>";
}

Open in new window

Partial listing:
Array - BoxesSold3 - 0
Array - outTotal -
Array - 44O~U~T - 8
Array - 44In - 6
Array - 44MPSold - 2
Array - 44Cost - 17.00
Array - 44Total - 34.00
Array - 112O~U~T -
Array - 112In - 0

What I am actually looking for is the value of "O~U~T" quantity and then the next value (quantity brought back in) and the next next value (Cost/each).

Thus I am looking for 8 (item 44 leaving the warehouse), 6 (how many item 44 was returned) and 17.00 (cost each of items not returned).

This code:
foreach($_POST as $key => $value){
	if($key == "44O~U~T"){
	echo $_POST . " - " . $key . " - " . $value . "<br>";
	echo next($_POST) . " - " . $key . " - " . $value . "<br>";
	echo next($_POST) . " - " . $key . " - " . $value . "<br>";
}

Open in new window


Returns:
Array - 44O~U~T - 1
0128T - 44O~U~T - 1
11-20-2015 - 44O~U~T - 1

I was hoping it would return:
Array - 44O~U~T - 8
Array - 44In - 6
Array - 44Cost - 17.00

I thought that next($_POST) would iterate to the next $_POST in the array.
Edit to my last post... I was hoping that this code:
foreach($_POST as $key => $value){
	if($key == "44O~U~T"){
	echo $_POST . " - " . $key . " - " . $value . "<br>";
	echo next($_POST) . " - " . $key . " - " . $value . "<br>";
	next($_POST);
	echo next($_POST) . " - " . $key . " - " . $value . "<br>";
}

Open in new window


would return:
Array - 44O~U~T - 8
Array - 44In - 6
Array - 44Cost - 17.00
It can't do that because $key and $value do not change inside your foreach() loop.
Dave, if $key and $value don't change then what is the purpose of "next"... such as next($_POST)?
'next($_POST)' may go to the next $_POST item but $key and $value are set by the foreach() code, not the 'next' code.  And in your code, echo next($_POST) is actually showing the next value which is 'array'.  If you assign it to an array variable, you could use the index to show the values you are looking for like...
$nxtarray = next($_POST);
echo $nxtarray[0].' '.$nxtarray[1];

Open in new window


http://php.net/manual/en/function.next.php
if $key and $value don't change then what is the purpose of "next"... such as next($_POST)?
You can't use next() in a foreach - it does not affect the pointer in the foreach iterator.

You need to use the code I posted with current() in a while loop.

Please can you post the output of the following

echo "<pre>" . print_r($_POST, true) . "</pre>";

Open in new window

So we can see what is actually in your $_POST
Array
(
    [theOfficeLedgerID] => 13
    [truckNum] => 0128T
    [jsOffice] => pen
    [truckDate] => 11-20-2015
    [managerName] => 4465~FKevin Moseley
    [contractor1] => 5189~FTammy Sheffield
    [BoxesSold1] => 1
    [contractor2] => 
    [BoxesSold2] => 0
    [contractor3] => 
    [BoxesSold3] => 0
    [outTotal] => 
    [44O~U~T] => 1
    [44In] => 0
    [44MPSold] => 1
    [44Cost] => 17.00
    [44Total] => 17.00
    [112O~U~T] => 
    [112In] => 0
    [112Sold] => 0
    [112Cost] => 20.00
    [112Total] => 0.00
    [111O~U~T] => 
    [111In] => 0
    [111Sold] => 0
    [111Cost] => 20.00
    [111Total] => 0.00
    [110O~U~T] => 
    [110In] => 0
    [110Sold] => 0
    [110Cost] => 20.00
    [110Total] => 0.00
    [1135O~U~T] => 
    [1135In] => 0
    [1135Sold] => 0
    [1135Cost] => 22.00
    [1135Total] => 0.00
    [1134O~U~T] => 
    [1134In] => 0
    [1134Sold] => 0
    [1134Cost] => 0.00
    [1134Total] => 0.00
    [135O~U~T] => 
    [135In] => 0
    [135Sold] => 0
    [135Cost] => 20.00
    [135Total] => 0.00
    [122O~U~T] => 
    [122In] => 0
    [122Sold] => 0
    [122Cost] => 18.00
    [122Total] => 0.00
    [69O~U~T] => 
    [69In] => 0
    [69Sold] => 0
    [69Cost] => 12.00
    [69Total] => 0.00
    [127O~U~T] => 
    [127In] => 0
    [127Sold] => 0
    [127Cost] => 20.00
    [127Total] => 0.00
    [128O~U~T] => 
    [128In] => 0
    [128Sold] => 0
    [128Cost] => 30.00
    [128Total] => 0.00
    [130O~U~T] => 
    [130In] => 0
    [130Sold] => 0
    [130Cost] => 30.00
    [130Total] => 0.00
    [131O~U~T] => 
    [131In] => 0
    [131Sold] => 0
    [131Cost] => 5.00
    [131Total] => 0.00
    [133O~U~T] => 
    [133In] => 0
    [133Sold] => 0
    [133Cost] => 30.00
    [133Total] => 0.00
    [134O~U~T] => 
    [134In] => 0
    [134Sold] => 0
    [134Cost] => 16.00
    [134Total] => 0.00
    [37O~U~T] => 
    [37In] => 0
    [37Sold] => 0
    [37Cost] => 12.00
    [37Total] => 0.00
    [129O~U~T] => 
    [129In] => 0
    [129Sold] => 0
    [129Cost] => 2.00
    [129Total] => 0.00
    [119O~U~T] => 
    [119In] => 0
    [119Sold] => 0
    [119Cost] => 9.00
    [119Total] => 0.00
    [14O~U~T] => 
    [14In] => 0
    [14Sold] => 0
    [14Cost] => 10.00
    [14Total] => 0.00
    [11O~U~T] => 
    [11In] => 0
    [11Sold] => 0
    [11Cost] => 0.00
    [11Total] => 0.00
    [25O~U~T] => 
    [25In] => 0
    [25Sold] => 0
    [25Cost] => 0.00
    [25Total] => 0.00
    [80O~U~T] => 
    [80In] => 0
    [80Sold] => 0
    [80Cost] => 20.00
    [80Total] => 0.00
    [117O~U~T] => 
    [117In] => 0
    [117Sold] => 0
    [117Cost] => 235.00
    [117Total] => 0.00
    [116O~U~T] => 
    [116In] => 0
    [116Sold] => 0
    [116Cost] => 180.00
    [116Total] => 0.00
    [114O~U~T] => 
    [114In] => 0
    [114Sold] => 0
    [114Cost] => 355.00
    [114Total] => 0.00
    [100O~U~T] => 
    [100In] => 0
    [100Sold] => 0
    [100Cost] => 300.00
    [100Total] => 0.00
    [truckCharge] => 40.00
    [totalChecks] => 
    [checkCharge] => 0.00
    [totalCC] => 
    [ccCharge] => 0.00
    [totalFS] => 
    [looseCharge] => 0.00
    [totalCode4] => 57.00
    [iceCharge] => 
    [taxes] => 0.00
    [totalDue] => 57.00
    [taxTotalDue] => 17
    [totalEnc] => 57.00
    [contractor1o] => Tammy Sheffield
    [overage1] => 0.00
    [contractor2o] => 
    [overage2] => 0.00
    [contractor3o] => 
    [overage3] => 0.00
    [managerO] => Kevin Moseley
    [overage4] => 
    [contractor1s] => Tammy Sheffield
    [shortage1] => 
    [contractor2s] => 
    [shortage2] => 0.00
    [contractor3s] => 
    [shortage3] => 0.00
    [managerS] => Kevin Moseley
    [shortage4] => 
    [shortage5] => 
)

Open in new window

In classic asp what I want to do was accomplished through:

for intLoop = 1 to Request.Form.Count
	if right (Request.Form.Key(intLoop),5) = "O~U~T" then
		if isnumeric(Request.Form.Item(intLoop)) then
			if Request.Form.Item(intLoop) > 0 then
				SQLStatement = "INSERT INTO envData " & _ 
				   "Values " & _
				   "('" & Request.Form("truckNum") & "', " & _
				   "'" & Request.Form("truckDate") & "', " & _
				   "'" & Request.Cookies("Office") & "', " & _
				   "'" & left(Request.Form.key(intLoop),len(Request.Form.key(intLoop))-5) & "', " & _
				   "" & Request.Form.Item(intLoop) & ", " & _
				   "" & Request.Form.Item(intLoop+1) & ", " & _
				   "" & Request.Form.Item(intLoop+3) & ", " & _
				   "'" & Request.Cookies("User") & "', " & _
				   "'" & Date & "')"

				objConn.Execute SQLStatement,,129

			end if
		end if
		intLoop=intLoop+2
	end if
next

Open in new window

You can do the same with PHP using the current() next() code I showed above - in the ASP case you are jumping from
intLoop+1
to
intLoop+3
just do a double next()
Julian... I assumed so.  I copied your code exactly.

The while loop executes 7 times and the if (substr(key($_POST),-5) == "O~U~T"){ portion is never ran.

Printing key($_POST) from the while loop displays:

theOfficeLedgerID
truckNum
jsOffice
truckDate
managerName
contractor1
BoxesSold1
@classnet: If you use var_export() you can produce PHP-compatible representations of data.  This is helpful because it enables us to copy the data and paste it into PHP scripts.  Then we can show you the code that operates on that data to give you the answers you need.
http://php.net/manual/en/function.var-export.php
var_export($_POST):

array ( 'theOfficeLedgerID' => '13', 'truckNum' => '0128T', 'jsOffice' => 'pen', 'truckDate' => '11-20-2015', 'managerName' => '4465~FKevin Moseley', 'contractor1' => '5189~FTammy Sheffield', 'BoxesSold1' => '1', 'contractor2' => '', 'BoxesSold2' => '0', 'contractor3' => '', 'BoxesSold3' => '0', 'outTotal' => '', '44O~U~T' => '1', '44In' => '0', '44MPSold' => '1', '44Cost' => '17.00', '44Total' => '17.00', '112O~U~T' => '', '112In' => '0', '112Sold' => '0', '112Cost' => '20.00', '112Total' => '0.00', '111O~U~T' => '', '111In' => '0', '111Sold' => '0', '111Cost' => '20.00', '111Total' => '0.00', '110O~U~T' => '', '110In' => '0', '110Sold' => '0', '110Cost' => '20.00', '110Total' => '0.00', '1135O~U~T' => '', '1135In' => '0', '1135Sold' => '0', '1135Cost' => '22.00', '1135Total' => '0.00', '1134O~U~T' => '', '1134In' => '0', '1134Sold' => '0', '1134Cost' => '0.00', '1134Total' => '0.00', '135O~U~T' => '', '135In' => '0', '135Sold' => '0', '135Cost' => '20.00', '135Total' => '0.00', '122O~U~T' => '', '122In' => '0', '122Sold' => '0', '122Cost' => '18.00', '122Total' => '0.00', '69O~U~T' => '', '69In' => '0', '69Sold' => '0', '69Cost' => '12.00', '69Total' => '0.00', '127O~U~T' => '', '127In' => '0', '127Sold' => '0', '127Cost' => '20.00', '127Total' => '0.00', '128O~U~T' => '', '128In' => '0', '128Sold' => '0', '128Cost' => '30.00', '128Total' => '0.00', '130O~U~T' => '', '130In' => '0', '130Sold' => '0', '130Cost' => '30.00', '130Total' => '0.00', '131O~U~T' => '', '131In' => '0', '131Sold' => '0', '131Cost' => '5.00', '131Total' => '0.00', '133O~U~T' => '', '133In' => '0', '133Sold' => '0', '133Cost' => '30.00', '133Total' => '0.00', '134O~U~T' => '', '134In' => '0', '134Sold' => '0', '134Cost' => '16.00', '134Total' => '0.00', '37O~U~T' => '', '37In' => '0', '37Sold' => '0', '37Cost' => '12.00', '37Total' => '0.00', '129O~U~T' => '', '129In' => '0', '129Sold' => '0', '129Cost' => '2.00', '129Total' => '0.00', '119O~U~T' => '', '119In' => '0', '119Sold' => '0', '119Cost' => '9.00', '119Total' => '0.00', '14O~U~T' => '', '14In' => '0', '14Sold' => '0', '14Cost' => '10.00', '14Total' => '0.00', '11O~U~T' => '', '11In' => '0', '11Sold' => '0', '11Cost' => '0.00', '11Total' => '0.00', '25O~U~T' => '', '25In' => '0', '25Sold' => '0', '25Cost' => '0.00', '25Total' => '0.00', '80O~U~T' => '', '80In' => '0', '80Sold' => '0', '80Cost' => '20.00', '80Total' => '0.00', '117O~U~T' => '', '117In' => '0', '117Sold' => '0', '117Cost' => '235.00', '117Total' => '0.00', '116O~U~T' => '', '116In' => '0', '116Sold' => '0', '116Cost' => '180.00', '116Total' => '0.00', '114O~U~T' => '', '114In' => '0', '114Sold' => '0', '114Cost' => '355.00', '114Total' => '0.00', '100O~U~T' => '', '100In' => '0', '100Sold' => '0', '100Cost' => '300.00', '100Total' => '0.00', 'truckCharge' => '40.00', 'totalChecks' => '', 'checkCharge' => '0.00', 'totalCC' => '', 'ccCharge' => '0.00', 'totalFS' => '', 'looseCharge' => '0.00', 'totalCode4' => '57.00', 'iceCharge' => '', 'taxes' => '0.00', 'totalDue' => '57.00', 'taxTotalDue' => '17', 'totalEnc' => '57.00', 'contractor1o' => 'Tammy Sheffield', 'overage1' => '0.00', 'contractor2o' => '', 'overage2' => '0.00', 'contractor3o' => '', 'overage3' => '0.00', 'managerO' => 'Kevin Moseley', 'overage4' => '', 'contractor1s' => 'Tammy Sheffield', 'shortage1' => '', 'contractor2s' => '', 'shortage2' => '0.00', 'contractor3s' => '', 'shortage3' => '0.00', 'managerS' => 'Kevin Moseley', 'shortage4' => '', 'shortage5' => '', )

Open in new window

Now that I look at this a little more, it appears that the application is misdesigned.  If we have two values that need to be associated (such as the value of "O~U~T" quantity and then the next value) it is appropriate to group these somehow, perhaps in an array.  Or you might use a JSON or XML construct of some kind to transport the data.  I recommend that you consider redesigning the app so the data structure makes more sense.

If you are forced to work with what you have here. you may be able to reorganize the data something like this.  The resulting array of arrays may be easier to put into a query string.
http://iconoun.com/demo/temp_classnet.php
<?php // demo/temp_classnet.php
/**
 * http://www.experts-exchange.com/questions/28861239/Incrementing-foreach-loop.html#a41287325
 */
error_reporting(E_ALL);
echo '<pre>';


$_POST = Array
(
    'theOfficeLedgerID' => '13',
    'truckNum' => '0128T',
    'jsOffice' => 'pen',
    'truckDate' => '11-20-2015',
    'managerName' => '4465~FKevin Moseley',
    'contractor1' => '5189~FTammy Sheffield',
    'BoxesSold1' => '1',
    'contractor2' => '',
    'BoxesSold2' => '0',
    'contractor3' => '',
    'BoxesSold3' => '0',
    'outTotal' => '',
    '44O~U~T' => '1',
    '44In' => '0',
    '44MPSold' => '1',
    '44Cost' => '17.00',
    '44Total' => '17.00',
    '112O~U~T' => '',
    '112In' => '0',
    '112Sold' => '0',
    '112Cost' => '20.00',
    '112Total' => '0.00',
    '111O~U~T' => '',
    '111In' => '0',
    '111Sold' => '0',
    '111Cost' => '20.00',
    '111Total' => '0.00',
    '110O~U~T' => '',
    '110In' => '0',
    '110Sold' => '0',
    '110Cost' => '20.00',
    '110Total' => '0.00',
    '1135O~U~T' => '',
    '1135In' => '0',
    '1135Sold' => '0',
    '1135Cost' => '22.00',
    '1135Total' => '0.00',
    '1134O~U~T' => '',
    '1134In' => '0',
    '1134Sold' => '0',
    '1134Cost' => '0.00',
    '1134Total' => '0.00',
    '135O~U~T' => '',
    '135In' => '0',
    '135Sold' => '0',
    '135Cost' => '20.00',
    '135Total' => '0.00',
    '122O~U~T' => '',
    '122In' => '0',
    '122Sold' => '0',
    '122Cost' => '18.00',
    '122Total' => '0.00',
    '69O~U~T' => '',
    '69In' => '0',
    '69Sold' => '0',
    '69Cost' => '12.00',
    '69Total' => '0.00',
    '127O~U~T' => '',
    '127In' => '0',
    '127Sold' => '0',
    '127Cost' => '20.00',
    '127Total' => '0.00',
    '128O~U~T' => '',
    '128In' => '0',
    '128Sold' => '0',
    '128Cost' => '30.00',
    '128Total' => '0.00',
    '130O~U~T' => '',
    '130In' => '0',
    '130Sold' => '0',
    '130Cost' => '30.00',
    '130Total' => '0.00',
    '131O~U~T' => '',
    '131In' => '0',
    '131Sold' => '0',
    '131Cost' => '5.00',
    '131Total' => '0.00',
    '133O~U~T' => '',
    '133In' => '0',
    '133Sold' => '0',
    '133Cost' => '30.00',
    '133Total' => '0.00',
    '134O~U~T' => '',
    '134In' => '0',
    '134Sold' => '0',
    '134Cost' => '16.00',
    '134Total' => '0.00',
    '37O~U~T' => '',
    '37In' => '0',
    '37Sold' => '0',
    '37Cost' => '12.00',
    '37Total' => '0.00',
    '129O~U~T' => '',
    '129In' => '0',
    '129Sold' => '0',
    '129Cost' => '2.00',
    '129Total' => '0.00',
    '119O~U~T' => '',
    '119In' => '0',
    '119Sold' => '0',
    '119Cost' => '9.00',
    '119Total' => '0.00',
    '14O~U~T' => '',
    '14In' => '0',
    '14Sold' => '0',
    '14Cost' => '10.00',
    '14Total' => '0.00',
    '11O~U~T' => '',
    '11In' => '0',
    '11Sold' => '0',
    '11Cost' => '0.00',
    '11Total' => '0.00',
    '25O~U~T' => '',
    '25In' => '0',
    '25Sold' => '0',
    '25Cost' => '0.00',
    '25Total' => '0.00',
    '80O~U~T' => '',
    '80In' => '0',
    '80Sold' => '0',
    '80Cost' => '20.00',
    '80Total' => '0.00',
    '117O~U~T' => '',
    '117In' => '0',
    '117Sold' => '0',
    '117Cost' => '235.00',
    '117Total' => '0.00',
    '116O~U~T' => '',
    '116In' => '0',
    '116Sold' => '0',
    '116Cost' => '180.00',
    '116Total' => '0.00',
    '114O~U~T' => '',
    '114In' => '0',
    '114Sold' => '0',
    '114Cost' => '355.00',
    '114Total' => '0.00',
    '100O~U~T' => '',
    '100In' => '0',
    '100Sold' => '0',
    '100Cost' => '300.00',
    '100Total' => '0.00',
    'truckCharge' => '40.00',
    'totalChecks' => '',
    'checkCharge' => '0.00',
    'totalCC' => '',
    'ccCharge' => '0.00',
    'totalFS' => '',
    'looseCharge' => '0.00',
    'totalCode4' => '57.00',
    'iceCharge' => '',
    'taxes' => '0.00',
    'totalDue' => '57.00',
    'taxTotalDue' => '17',
    'totalEnc' => '57.00',
    'contractor1o' => 'Tammy Sheffield',
    'overage1' => '0.00',
    'contractor2o' => '',
    'overage2' => '0.00',
    'contractor3o' => '',
    'overage3' => '0.00',
    'managerO' => 'Kevin Moseley',
    'overage4' => '',
    'contractor1s' => 'Tammy Sheffield',
    'shortage1' => '',
    'contractor2s' => '',
    'shortage2' => '0.00',
    'contractor3s' => '',
    'shortage3' => '0.00',
    'managerS' => 'Kevin Moseley',
    'shortage4' => '',
    'shortage5' => '',
)
;
// ACTIVATE THIS TO SEE THE REQUEST DATA
// var_dump($_POST);

// COLLECT THE REORGANIZED DATA IN THIS ARRAY
$out = [];

$index = -1;
foreach ($_POST as $key => $value)
{
    // ARRAY_SLICE() ITERATOR STARTS WITH INDEX == ZERO
    $index++;

    // DOES THE KEY CONTAIN A SIGNAL OF SOMETHING WE WANT?
    if (strpos($key, 'O~U~T'))
    {
        $signal = str_replace('O~U~T', NULL, $key);
        $subset = array_slice($_POST, $index, 4, TRUE);
        $out[$signal] = $subset;
    }
}

// SHOW THE WORK PRODUCT
print_r($out);

Open in new window

ASKER CERTIFIED SOLUTION
Avatar of Julian Hansen
Julian Hansen
Flag of South Africa image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Thank you for sticking with this Julian.  Works great!

Ray, comment duly noted... due to time constraints the plan is to convert then redesign.
You are welcome.
When you get ready to refactor, learn about cyclomatic complexity first.  It should deeply affect the way you write code, and for the better.  It also explains why the example I posted uses only one iterator and one if() statement.
http://www.ibm.com/developerworks/java/library/j-cq03316/
Avatar of acemary mary
acemary mary

<?php
$n = 0;
foreach ($_productCollection as $_product):
$n++;
?>
<div style="float: left; font-size: 120px;height:50px;padding-top:50px; color:#ccc"><?php echo $n; ?>
</div>
<div class="listing-item<?php if( ++$_iterator == sizeof($_productCollection) ): ?> last<?php endif; ?>">