2

Trying to learn arrays in PHP. Snippets posted for brevity.

HTML form here:

<p>What are your favorite type of cookies?</p> 
<input type="checkbox" name="cookies[]" value="Oreos" />Oreos<br />
<input type="checkbox" name="cookies[]" value="Chocolate chip" />Chocolate chip<br />
<input type="checkbox" name="cookies[]" value="Sugar" />Sugar<br />
<input type="checkbox" name="cookies[]" value="Vanilla Mocha" />Vanilla Mocha<br /> 

<p>What are your favorite type of drinks?</p>
<input type="checkbox" name="drinks[]" value="Soda" />Soda<br />
<input type="checkbox" name="drinks[]" value="Wine" />Wine<br />
<input type="checkbox" name="drinks[]" value="Milk" />Milk<br />
<input type="checkbox" name="drinks[]" value="Water" />Water<br /> 

PHP page here:

foreach ($drinks as $d) {
    echo "Your favorite drink(s) are: " . $d . "<br />"; 
}

foreach ($cookies as $cookie) {
    echo "Your favorite cookies are: " . $cookie . "<br />"; 
} 

$experimentalArray = array($cookie => $d); 

foreach ($experimentalArray as $key => $value) { 
    echo "Cookie - " . $key . " Drink - " . $value . "<br /><br />"; 
} 

Both cookies and drinks are multi-choice questions, so you can select more than one answer.

However, the experimentalArray only shows the last answer chosen in both drink and cookie question.

For example, I choose Oreos and Chocolate Chip in cookies, and Soda and Wine in drinks.

The answer comes out as: "Cookie - Chocolate chip Drink - Wine"

Why is it not displaying all values?

Edited for a multi-dimensional script

<?php 

$drinks = $_POST['drinks']; 
$cookies = $_POST['cookies']; 

    $combinedArray = array( 'Cookies' => $cookies, 'Drinks' => $drinks); 

    foreach($combinedArray as $snackType => $snack) {
    print "<h2>$snackType</h2>";
    foreach ($snack as $number => $snackChosen) {
        print " $number is $snackChosen<br />";
    }

} ?>

Ok, so tried to do a multi-dimensional array script instead since the previous script wasn't going to obtain all the values as per the HTML form.

This script works (was ripped off from a book and modified for this code here), however, $number value starts at 0. How do I modify that so that it starts at 1 instead?

Also, is this proper form for doing multi-dimensional array? Could it have been rewritten in a better way?

And again, thank you for all responses. Even if I don't quite understand them! :) So, thank you for your patience as well.

2
  • Protip: print_r($_POST);. Also, please, please tell me that you have register_globals off and you're just aliasing the $_POST array. Commented Jan 24, 2011 at 0:24
  • yes, register globals are off. and yes, aliasing $_POST array, if you mean that am I "renaming" it in the php page. As posted in my comment beneath to ThiefMaster: $drinks = $_POST['drinks']; $cookies = $_POST['cookies']; Commented Jan 24, 2011 at 0:35

4 Answers 4

6

No idea which php tutorial you are using, but stop using it, it's probably horribly outdated!

You'll have to use the $_POST / $_GET / $_REQUEST (contains POST, GET and - depending on the config - Cookie values) arrays. register_globals is deprecated and a potential security hole if enabled.

For example, use $drinks = isset($_POST['drinks']) ? $_POST['drinks'] : array(); to get your $drinks array. Same for the $cookies one.


About your array issue. It looks like you want the keys from the drinks array and the values from hte cookies array. If yes, have a look at array_combine(). Note that it requires both arrays to have the same amount of elements though so feeding it with user-generated arrays where the length can vary is not a very good idea.

Fyi, $experimentalArray = array($cookie => $d); maps the last element from $cookies to the last element of $drinks because PHP has no block scope and thus $cookie and $d still point to the last array elements you got in your foreach loops.

Sign up to request clarification or add additional context in comments.

5 Comments

Um, I am using $_POST to get the values. Sorry, posted only the parts that I thought was relevant to the question. Didn't mean to make it unclear. Here are my $_POST stuff:$drinks = $_POST['drinks']; $cookies = $_POST['cookies'];
Yes, it's obvious that if he's getting anything at all, he must be converting $_POST['drinks'] and $_POST['cookies'] to another variable or using them directly.
Oy vey. Sorry, wasn't trying to make it unclear. Thought it would be obvious that if I was asking why it was showing only the last values chosen that I was using $_POST somewhere. I'm really new to all this. Anyway, any answers on why it shows only the last values? Is my question clear? And wow, do people ever answer blazing fast here!
Now you know not to omit important code parts without at least mentioning that you omitted them. ;) Regarding the "last values" issue: see the last paragraph of my answer. Oh, and maybe change your SO nick from "user567665" to something real. Default nicks make people look dumb IMO.
How could the script output any values at all if the $drinks and $cookies array didn't contain something? +1 for the thought though, this was my first idea
1

There are a few problems here.

  1. When you iterate with foreach and you would like to perform actions for each element, the code need to be between the foreach's brakets.
  2. There is always a chance that the user will select a different number of cookies than drinks, which would cause problems because one food item wouldn't have a pair.

The solution that I propose is the array_combine() function to pair cookies with drinks after padding each of the arrays to the same length:

<?php
//$cookies = array_pad( $cookies , count( $drinks ), '(none)' ); Doesn't work, thanks for pointing this out @Phoenix
$drinks = array_pad( $drinks, count( $cookies ), '(none)' ); //If more cookies than drinks, add (none) drinks to account for extra cookies
$combined = array_combine( $cookies, $drinks ); //Combine arrays and cookies
?>

Of course this may seem a little complicated so let me explain. Let's say the user choses Sugar and Chocolate Chip Cookies with Milk and Water. These obviously aren't the tastiest choices, but they are the most optimal in this case. Since there are an equal number of cookies as there are drinks, PHP will simply pair up the choices with the array_combine() function. This function accepts an array of keys (cookies) and values ($drinks) and combines them into one. Ex.

array_combine( array( 'one', 'two' ), array( 1, 2 ) ) == array( 'one' => 1, 'two' => 2 );

We run into problems when the user chooses an unequal number of favorite snacks. This is when the first two lines come into play. The first line will add (none) to the cookie array for each extra drink. Ex.

array_pad( array( 'one' ), 2, '(none)' ) == array( 'one', '(none)' );

The next line does the same, but instead equals the drinks with the cookies (in the case there are more cookies selected than drinks).

Let me know if you need more examples.

6 Comments

Here's another way to potentially pad $cookies appropriately: if(count($drinks)>count($cookies)){ for($i=1;$i<=count($drinks);$i++){ if(!isset($cookies[$i])){ $cookies[$i] == 'None ' . $i;}}}
@Phoenix Nice example (though I do prefer foreach). I was looking for a way so that the output won't be polluted with a bunch on nones. I guess the easiest thing to do would be to regex for (None[0-9]*) and replace it with (No Choice) or something more user friendly. Now that I think about it, the best way to do this would be to establish pairs of cookies and drinks and only display pairs where both the cookie and drink have been selected.
Hm, interesting. When I tried to echo your $combined, it gave me "Array." And if I'm not seemingly getting it, please do excuse me. This is really new to me.
@user567665 Echoing an array should output "Array". To see the contents of an array, use print_r(). Ex. print_r( array( 1, 2, 3 ) );
hey, it kind of works if you choose the same number of answers on both questions. Goes a little wonky if not equal. Hm. All the answers here a little, ok ok, way over my head. need a little time to think all this through. Thanks all though. Really appreciate the time taken to answer my question.
|
0

What about the previous two? Do they work appropriately? I believe that the problem is here:

$experimentalArray = array($cookie => $d);

Which should be

$experimentalArray = array($cookies => $drinks);

I don't think I've ever made an array in that fashion though, not sure if the values of $cookies will automatically be the keys of $drinks.

If not, a method of generating such an array would be something like:

if(count($drinks) >= count($cookies))
{
     $count = count($drinks);
}
else
{
     $count = count($cookies);
}

for($i=1;$i<=$count;$i++)
{
     if(isset($drinks[$i]) && isset($cookies[$i]))
     {
          $experimentalArray[$cookies[$i]] = $drinks[$i];
     }
     else if(isset($drinks[$i]) && !isset($cookies[$i]))
     {
          $experimentalArray['None' . $i] = $drinks[$i];
     }
     else
     {
          $experimentalArray[$cookies[$i]] = 'None' . $i;
     }
}   

Or something like that, which accounts for if there are fewer of one type chosen than the other.

9 Comments

Tried this right now. It doesn't work. Nothing comes up. And yes, the previous two works. Here's the code for it. foreach ($drinks as $d) { echo "Your favorite drink(s) are: " . $d . "<br />"; } foreach ($cookies as $cookie) { echo "Your favorite cookies are: " . $cookie . "<br />"; }
Just modified post. But I believe there is a built in function to combine two arrays as value=>value, but I've never really had much use for it, and I'm not sure how it reacts if one has fewer values than the other.
@Phoenix You're thinking of array_combine(). "Returns ... FALSE if the number of elements for each array isn't equal"
Ah, yes, up there by PhpMyCoder, array_combine. Of course, what you'd wind up with that is a multidimensional array if one exceeded the other by two or more, because you'd wind up with two or more $experimentalArray['(none)'] using what he posted, well, if and only if drinks exceeded cookies by two or more.
That's why you have to array_pad each before you array_combine them. (See my answer)
|
0
This script works (was ripped off from a book and modified for this code here), however, $number value starts at 0. How do I modify that so that it starts at 1 instead?

PHP always starts the Count at 0. You can read more about that at: http://php.net/manual/de/language.types.array.php

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.