61

When interpolating PHP's string-indexed array elements (5.3.3, Win32) the following behavior may be expected or not:

$ha = array('key1' => 'Hello to me');

print $ha['key1'];   # correct (usual way)
print $ha[key1];     # Warning, works (use of undefined constant)

print "He said {$ha['key1']}"; # correct (usual way)
print "He said {$ha[key1]}";   # Warning, works (use of undefined constant)

print "He said $ha['key1']";   # Error, unexpected T_ENCAPSED_AND_WHITESPACE
print "He said $ha[ key1 ]";   # Error, unexpected T_ENCAPSED_AND_WHITESPACE
print "He said $ha[key1]";     # !! correct (How Comes?)

Inerestingly, the last line seems to be correct PHP code. Any explanations? Can this feature be trusted?


Edit: The point of the posting now set in bold face in order to reduce misunderstandings.
Rais Alam
  • 6,970
  • 12
  • 53
  • 84
rubber boots
  • 14,924
  • 5
  • 33
  • 44
  • **See also:** https://stackoverflow.com/questions/27742321/how-to-echo-element-of-associative-array-in-string – dreftymac Jul 27 '18 at 21:44

4 Answers4

59

Yes, you may trust it. All ways of interpolation a variable are covered in the documentation pretty well.

If you want to have a reason why this was done so, well, I can't help you there. But as always: PHP is old and has evolved a lot, thus introducing inconsistent syntax.

NikiC
  • 100,734
  • 37
  • 191
  • 225
  • @nikic, I can't find this exact case (w/o curly braces) in the docs, where is it? Thanks, rbo – rubber boots Jan 19 '11 at 18:11
  • @mario: Personally I think it's not good, but many probably others are okay with it -> Dropped that part. – NikiC Jan 19 '11 at 18:12
  • @rubber boots: look out for this line: `echo "He drank some $juices[koolaid1] juice.".PHP_EOL;`. – NikiC Jan 19 '11 at 18:13
  • Heaps of pros and cons. Personally I prefer the Perl/PHP string interpolation syntax over the printf-style methods in Python or Ruby. It keeps code more readable and maintainable. OTOH it has enabled sloppy coders to write exploitable SQL statements too easily. Yet better than single-quote micro optimizing. – mario Jan 19 '11 at 18:16
  • 2
    @mario, I come from Perl (still live there) and interpolation *in Perl* usually makes things more readable. The DMF in PHP here (dearly mising feature) is Perls q-operator (quote) series -> qq{}, q{}, qx{}, qw{}. Therefore (imho) string interpolation might be not as useful in PHP as it could be. :-( – rubber boots Jan 19 '11 at 18:20
  • @rubber boots: Well, PHP does have `HEREDOC` and `NOWDOC`. Though they probably aren't that nice-looking, but they generally serve the same purpose, don't they? – NikiC Jan 19 '11 at 18:22
  • 1
    @nikic somehow serve, right. But not on a single line. compare Perl: $x = qq{$text}; – rubber boots Jan 19 '11 at 18:40
  • @rubber boots: Yes, I admit that it is rather .. er .. bulky. Minimum of three lines, normally four if it's in function call, are required. – NikiC Jan 19 '11 at 18:58
  • When you think about it, it sort of makes sense in an abstract kind of way. When you have an associative array it expects a string, now the whole thing is already in a string, the variable name itself is being interpolated, but having more quotes in the square brackets would be redundant. It makes sense to have the variable name interpolated while the value inside the square brackets is *not* being interpolated unless it starts with a dollar sign. At least this is how I interpret this feature, it seems like reasonable logic to me. – Tory Nov 25 '15 at 19:20
20

Yes, this is well defined behavior, and will always look for the string key 'key', and not the value of the (potentially undefined) constant key.

For example, consider the following code:

$arr = array('key' => 'val');
define('key', 'defined constant');
echo "\$arr[key] within string is: $arr[key]";

This will output the following:

$arr[key] within string is: val

That said, it's probably not best practice to write code like this, and instead either use:

$string = "foo {$arr['key']}"

or

$string = 'foo ' . $arr['key']

syntax.

mfonda
  • 7,873
  • 1
  • 26
  • 30
9

The last one is a special case handled by the PHP tokenizer. It does not look up if any constant by that name was defined, it always assumes a string literal for compatibility with PHP3 and PHP4.

mario
  • 144,265
  • 20
  • 237
  • 291
  • 5
    Just for those interested (probably nobody...): PHP will generate a `T_STRING` for the array index (or a `T_NUM_STRING` if it is a non-overflowing decimal number) instead of the normal `T_CONSTANT_ENCAPSED_STRING`. – NikiC Jan 19 '11 at 18:18
0

To answer your question, yes, yes it can, and much like implode and explode, php is very very forgiving... so inconsistency abound

And I have to say I like PHP's interpolation for basical daisy punching variables into strings then and there,

However if your doing only string variable interpolation using a single array's objects, it may be easier to write a template which you can daisy print a specific object variables into (like in say javascript or python) and hence explicit control over the variable scope and object being applied to the string

I though this guy's isprintf really useful for this kind of thing

http://www.frenck.nl/2013/06/string-interpolation-in-php.html

<?php

$values = array(
    'who'   => 'me honey and me',
    'where' => 'Underneath the mango tree',
    'what'  => 'moon',
);

echo isprintf('%(where)s, %(who)s can watch for the %(what)s', $values);

// Outputs: Underneath the mango tree, me honey and me can watch for the moon
aqm
  • 2,942
  • 23
  • 30