tags:

views:

178

answers:

3
+3  Q: 

Array and foreach

$posts = array(
"message" => 'this is a test message'
);

foreach ($posts as $post) {
     echo $post['message'];
}

Why does the above code only output the first letter in message? "t".

Thanks!

+10  A: 

foreach takes each element of the array and assigns it to the variable. To get the results I assume you are expecting you just need to do:

foreach ($posts as $post) {
   echo $post;
}

The specifics as to why your code didn't work: $post would be the contents of the array element - in this case a string. Because PHP isn't strongly typed / supports type juggling, you can infact work with a string as if it were an array, and get to each character in the sequence:

foreach ($posts as $post) {
    echo $post[0]; //'t'
    echo $post[1]; //'h'
}

Obviously $post['message'] therefore is not a valid element, and there is no explicit conversion from (string)'message' to int, so this evals to $post[0].

iAn
((int) 'message') is pretty well defined: http://de.php.net/manual/en/language.types.string.php#language.types.string.conversion
soulmerge
Very true: bad choice of vocabulary on my part to express what I meant
iAn
+6  A: 
# $posts is an array with one index ('message')
$posts = array(
    "message" => 'this is a test message'
);

# You iterate over the $posts array, so $post contains
# the string 'this is a test message'
foreach ($posts as $post) {
    # You try to access an index in the string.
    # Background info #1:
    #   You can access each character in a string using brackets, just
    #   like with arrays, so $post[0] === 't', $post[1] === 'e', etc.
    # Background info #2:
    #   You need a numeric index when accessing the characters of a string.
    # Background info #3:
    #   If PHP expects an integer, but finds a string, it tries to convert
    #   it. Unfortunately, string conversion in PHP is very strange.
    #   A string that does not start with a number is converted to 0, i.e.
    #   ((int) '23 monkeys') === 23, ((int) 'asd') === 0,
    #   ((int) 'strike force 1') === 0
    # This means, you are accessing the character at position ((int) 'message'),
    # which is the first character in the string
    echo $post['message'];
}

What you possibly want is either this:

$posts = array(
    array(
        "message" => 'this is a test message'
    )
);
foreach ($posts as $post) {
    echo $post['message'];
}

Or this:

$posts = array(
    "message" => 'this is a test message'
);
foreach ($posts as $key => $post) {
    # $key === 'message'
    echo $post;
}
soulmerge
+1 for really nice background info (:
peirix
That's not really solving the problem, which is an obvious mis-conception about how foreach works with arrays.
iAn
'Solving the problem'? Of course I can't solve the problem without knowing what he wants to achieve with his script, I can only answer his question and give working examples. But I do think the info here is enough to make his script work.
soulmerge
+3  A: 

I'd add to iAn's answer something: if you want somehow to access to the key of the value, use this:

foreach ($posts as $key => $post) {
    echo $key . '=' . $post;
}

Result:

message=this is a test message
FWH