63

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.

1

4 Answers 4

61

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.

9
  • @nikic, I can't find this exact case (w/o curly braces) in the docs, where is it? Thanks, rbo Commented Jan 19, 2011 at 18:11
  • @mario: Personally I think it's not good, but many probably others are okay with it -> Dropped that part.
    – NikiC
    Commented Jan 19, 2011 at 18:12
  • @rubber boots: look out for this line: echo "He drank some $juices[koolaid1] juice.".PHP_EOL;.
    – NikiC
    Commented Jan 19, 2011 at 18:13
  • 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. :-( Commented Jan 19, 2011 at 18:20
  • 1
    @nikic somehow serve, right. But not on a single line. compare Perl: $x = qq{<a href="$link">$text</a>}; Commented Jan 19, 2011 at 18:40
21

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.

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.

1
  • 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
    Commented Jan 19, 2011 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
0

Not the answer you're looking for? Browse other questions tagged or ask your own question.