Hey guys, I have this forloop reading an array:

                $data = $_POST['data'];

                foreach ($data as $array) {
                        foreach ($array as $key=>$prices) {
                                $message .= ''.$prices.' '; 
                        }
                        $message .= '<br>';
                }

It currently displays like this:
item1 item2 item3 item4
item1 item2 item3 item4
etc

Is there any way to split those variables up so I can display them like this:

    $data = $_POST['data'];

    foreach ($data as $array) {
                        foreach ($array as $key=>$prices) {
                                $message .= ''.$item1.''.$item2.''.$item3.''.$item4.''; 
                        }
                        $message .= '<br>';
                }

Recommended Answers

All 15 Replies

I am a little confused as to what you are trying to do...
You have the solution to your question in your original code, it seems.

Can you show an example of your expected output, please?

Sorry, yeah, let me explain a little better.

My code outputs like this:

item1 item2 item3 item4

However, I'm wanting to add text around these variables, ideally I'm wanting something like:

item1 ( item2 x item3) item4

And I can't do that with the array being in one variable. So i figured the best way to do that would be having the code something like this:

$message .= ''.$item1.'('.$item2.'X'.$item3.')'.$item4.'';

Hopefully that makes more sense (:

Member Avatar for diafol

That concatenation is a bit awkward. Not sure why you need those single quotes ar the start and the end.

$message .= $item1.' ('.$item2.' x '.$item3.') '.$item4;

or

$message .= "$item1 ($item2 x $item3) $item4";

It was just a quick example really, but thanks for point it out! I'll try that when I figure out how to split it up.

Apparentlty extract is the way you go about doing this.

extract($data, EXTR_PREFIX_SAME, "wddx");

found that example Click Here but can't seem to figure it out. If it helps my form is set up like this:

<input name="data[0][0]" placeholder="Item Description">

And my echoed array looks like this:

Array ( [0] => Array ( [0] => 1 [1] => 1 [2] => 1 [3] => £1.00 ) )

In my opinion...

extract() can be dangerous if you have an array key that matches a variable you already have in use in the namespace. In reality, all that extract is doing under the hood is looping through they array with a foreach loop, and using the $key part to declare a variable for you (to many developers, this kind of automation and magical creation of variables is bad since you did not declare it explicitly and therefore risk overwriting something of your own on accident, making a near impossible to find bug in your code).

If your array is always going to be the same, I would encourage you to make a sub function that processes by index, something like:

function StringifyCartArray($aArr)
{
  return $aArr[0] . " ( " . $aArr[1] . " x " . $aArr[2] . " ) " . $aArr[3];
}

Or, if this in a function already, simply access the variables by array index.

Of course, in the example above, if you have a two dimensional array, ($data), you would pass in $data[0], eg:
$message = StringifyCartArray($data[0]);

Reasoning:
As I understand it, arrays in PHP are not "really" arrays - they are more like iterable hash maps (like in javascript). These hashmaps are stupid fast already, so why bother iterating if the data is never going to change? And even if it does, if you abstract it out to a function, all you have to do is change the function to consume the new indexes that exist in the array passed in.

Hope that helps!

Ryan

That's brilliant, thanks! Great info aswell (:

The only issue, it's obviously just going to display just the first four items in the array, is there a way to get it to display all the data like it did in the forloop? This will obviously output:

item1 item2 item3 item4
(then it would ignore anything else after these)

So it would still have to loop though?

it all depends on your data structure... I cant possibly answer your question without knowing more about how the data looks.

From your example, your most basic data had only 4 parts, so it would be silly to iterate through only 4.

If you have, say, 50 fields, then yes - iteration is likely the best method, but then you kinda lose the customization of your string based on index...

youre asking theory questions at this point - instead, why not show an example of what you are actually working on and you will get far superior answers that are more relevant to your exact problem. I can show you all the tools in the world by pointing you to php.net, but without knowing the job it's impossible to tell you the right one. (think, jack hammer to hang a picture? I think not..).

Riiight okay, here's all the extra info I can give you:

The form that's posting the information (it has four columns, but you can add and delete the rows as needed):

    <table id="TextBoxesGroup">
      <tbody> 
        <tr>
          <td><input type="button" class="deleteDep" value="Delete" /></td>
          <td><input name="data[0][0]" placeholder="Item Description"></td>
          <td><input data-field="quantity" name="data[0][1]" placeholder="Item Quantity" ></td>
          <td><input data-field="price" name="data[0][2]" placeholder="Item Amount"></td>
          <td><input data-field="total" name="data[0][3]" placeholder="Item Total" readonly="readonly"></td>
           <td><input type="button" class="addButton" value=" Add Row "></td>
        </tr>
      </tbody>
    </table>

Example of the kind of form I have here : Click Here

I'm then passing it to the PHP using this:

$data = $_POST['data'];

What I'm wanting is to do is email this information in the format:

item1 ( item2 x item3 ) item4

So if I fill in just one row, and submit the form, it will output this:

item1 ( item2 x item3 ) item4

If I fill in two rows, it will output this:

item1 ( item2 x item3 ) item4
item1 ( item2 x item3 ) item4

and so on.

The fourloop I had did exactly what I wanted, I just couldn't figure out how to get those brackets and times into the output. The code you gave me works great, but it only shows the first row of whats filled in on the form.

Hopefully this makes it clearer?

You would need to iterate over your $data array.. soo...

for ($Lup = 0; $Lup < sizeof($data); $Lup++)
  echo StringifyCartArray($data[$Lup]);

Or some variance of that, depending on your need.

That's it! Thanks a lot for that. I really do like to try and figure this stuff out, but it's so hard to know what to do when sometimes. But thanks once again ryantroop and diafol, greatly appreciated :)

The full code for anyone else stuggling with this:

//Information from form stored in $data variable
$data = $_POST['data'];

//Split your $data variable into indavidual variables
function StringifyCartArray($aArr){
    return $aArr[0] . " ( " . $aArr[1] . " x " . $aArr[2] . " ) " . $aArr[3] . "<br>";
}

//Iterate $data array
for ($Lup = 0; $Lup < sizeof($data); $Lup++)

//Print the message in your email
$message .= StringifyCartArray($data[$Lup]);

Hey! I think there maybe a tiny issue with the way this works upon further testing. Examples of what's happening:

EXAMPLE 1

Input:
1 1 1 1.00
2 2 2 2.00
3 3 3 3.00

Output:
1 ( 1 x £1 ) £1.00
2 ( 2 x £2 ) £4.00
3 ( 3 x £3 ) £9.00

(Works fine, just as expected)

EXAMPLE 2

Input:
1 1 1 1.00
3 3 3 3.00 << inserted row into into table
2 2 2 2.00

Output:
1 ( 1 x £1 ) £1.00
2 ( 2 x £2 ) £4.00
3 ( 3 x £3 ) £9.00 << wrong position, should read like the input

EXAMPLE 3

Input:
1 1 1 1.00
2 2 2 2.00 << I then delete this row
3 3 3 3.00

So the data when the forms sent is this:
1 1 1 1.00
3 3 3 3.00

Output:
1 ( 1 x £1 ) £1.00
( x £ ) £

I've checked printing the array and it's always correct, it's just the small snippet you gave me that's causing the issue. Wondered if you (or anyone) knew why?

Check the post before this for the full PHP I'm using.

Member Avatar for diafol

Depends how you're deleting it and how you then access it.

If you access via specific index (usually in a for loop), then yes it will be empty as $array[1] no longer exists as you've deleted it. However, if you use a foreach loop, this does not pull in the item specified by the index.

Well here's how I'm add and deleting rows,

$(window).load(function() {

    $(document).ready(function() {

        var table = $("#TextBoxesGroup");
        var row = table.find("tr");
        var count = 0;
        var cols = "";

        //Adding function

        $(document).on('click', '.addButton', function(e) {
            var newRow = row.clone();
            var regex = new RegExp("data\[[0-9]+\]", "g");
            newRow.html(newRow.html().replace(regex, "data[" + (++count) + "]"));
            newRow.append(cols);
            newRow.insertAfter($(this).closest("tr"));
        });

        //Deleting function

        $('body').on('click', 'input.deleteDep', function(e) {
            if (table.find("tr").length == 1) {
                return;
            }
            $(this).parents('tr').remove();
        });

        //Calculation

        $(document).on('keyup', "*[data-field='quantity'],*[data-field='price']", function(e) {
            var thisRow = $(this).parents("tr:first");
            var rowTotalField = thisRow.find("*[data-field='total']");
            var price = parseFloat(thisRow.find("*[data-field='price']").val());
            var quantity = parseInt(thisRow.find("*[data-field='quantity']").val());
            rowTotalField.val((!isNaN(price) && !isNaN(quantity) ?
                price * quantity : 0).toFixed(2));
            var total = 0;
            table.find("*[data-field='total']").each(function() {
                var t = parseFloat($(this).val().replace("£", ""));
                total += !isNaN(t) ? t : 0;
            });
            $('#total').val(total.toFixed(2));
        });
    });
});

And I'm accessing it with the code earlier in this thread. But your saying maybe I need to put the code above into somesort of foreach loop like it was before?

foreach ($data as $Lup) {
foreach ($Lup as $key=>$data) {
$message .= StringifyCartArray($data[$Lup]); 
}
}

Something along those lines? I've tested a few things and not got much luck. I know the code above wont work but it this the kinda thing your talking about?

Member Avatar for diafol
foreach($data as $datum) $message .= StringifyCartArray($datum);

Brilliant, thankyou.

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.