Constants inside quotes are not printed?
Asked Answered
S

6

29

This prints apple:

define("CONSTANT","apple");
echo CONSTANT;

But this doesn't:

echo "This is a constant: CONSTANT";

Why?

Stipel answered 30/5, 2010 at 1:25 Comment(6)
I don't understand. What is your expected output for the second case? This is a apple: A?Kuroshio
Think about how much work parsing double-quoted strings would be if the parser had to check whether any substring matched a defined constant... And it would slow down as you define more constants. AND, you'd have to escape the capital letter A inside ALL of your strings after defining that constant!Retainer
Reason why its not printed is because it is treated as a string literal. PHP would not know to subsitute apple in the second example, you would have to define that manually as Artefacto has demonstrated.Paternalism
because PHP is poorly designed. Plenty of other languages handle this just fine.Whore
@Retainer Ruby does it easily, like this: "This is a constant: #{CONSTANT}" - so no, it isn't impossible or extremely difficult.Costermansville
@BlaineLafreniere sorry I wasn't trying to imply that it would be difficult in general just in PHP using the syntax in the original question. In your Ruby example (and in many other string template systems) there's a way for the developer to indicate which part of the string to treat as code. That's the key difference hereRetainer
E
30

Because "constants inside quotes are not printed". The correct form is:

echo "This is a constant: " . CONSTANT;

The dot is the concatenation operator.

Eastbourne answered 30/5, 2010 at 1:27 Comment(3)
As soon as there is "{$var}", I expected "{CONSTANT}" to match the string interpolation syntax too.Smallclothes
@AlainTiemblo I expected that as well. Ruby does something like this: "This is a #{CONSTANT}". I find it funny how there are comments here saying that doing the same kind of parsing for constants is super difficult or slow or impossible or whatever... yeah right.Costermansville
@BlaineLafreniere - I see no such comments. The comments I see say, in effect, that given the current syntax, it is not possible, difficult, or slow. Note that OP didn't even put {} around the characters CONSTANT - obviously a complete lack of special syntax would be a nightmare to parse, and impossible to know whether the programmer intended the substitution or not.Hesperides
B
27
define('QUICK', 'slow');
define('FOX', 'fox');

$K = 'strval';

echo "The {$K(QUICK)} brown {$K(FOX)} jumps over the lazy dog's {$K(BACK)}.";
Bialystok answered 7/10, 2010 at 20:3 Comment(1)
In case it's not apparent, the big problem with the indirect function call technique is that $K is not in the global namespace, so it must be declared with global $K; in every function that needs to use it.Bialystok
S
8

The question was already answered, but I'd like to provide a more generic insight on this.

In double quotes, PHP recognizes anything starting with a $ as a variable to be interpolated. Further more, it considers array and object access ([] and ->) but only up to a single level. E.g. "$foo->bar" interpolates $foo->bar and $foo->bar->baz does the same thing and treats ->baz as a string literally. Also, the quotes in [] must be ommited for string keys. E.g. "$foo[bar]" interpolates $foo['bar'] while "$foo['bar']" is a syntax error. AFAIK, that's it. To get more functionality, you need the "{$...}" syntax.

The $ here is actually a part of the syntax and it doesn't work without it. E.g. "{FOO}" will not interpolate a constant FOO, it's simply a syntax error. However, other than some strange syntactical restrictions, this construct is actually quite strong and may contain any valid PHP expression, as long as it starts with a $ and is an array access, object access, or a function call. (Maybe some other cases are permitted to. Please let me know, if anyone has a better understanding of this.) The most general solution to your problem would be to define something like the following function somewhere in your code base:

$id = function ($x) {
    return $x;
}

It's simply the identity function - it returns whatever you give it. It must be defined as an anonymous function, so you can refer to it as $id with the $.

Now you can use this function to interpolate any PHP expression:

echo "{$id(CONSTANTS)}"
echo "{$id($some + $operators - $as . $well)}"
// etc...

Alternative for PHP versions < 5.3 where you can't use anonymous functoins:

class Util {
    function id ($x) { return $x; }
}
$u = new Util;
echo "{$u->id(ANY + $expression . $here)}"
// or...
function id ($x) { return $x; };
$id = 'id';
echo "{$id(ANY + $expression . $here)}"
Stier answered 15/1, 2021 at 8:45 Comment(0)
V
7

If you want to include references to variables inside of strings you need to use special syntax. This feature is called string interpolation and is included in most scripting languages.

This page describes the feature in PHP. It appears that constants are not replaced during string interpolation in PHP, so the only way to get the behavior you want is to use the concatenation that Artefacto suggested.

In fact, I just found another post saying as much:

AFAIK, with static variables, one has the same 'problem' as with constants: no interpolation possible, just use temporary variables or concatenation.

Vapor answered 30/5, 2010 at 1:47 Comment(4)
The reason why you cannot use the special syntax {} with constants is simple: The brackets are only recognized as "special syntax" if { is immediately followed by a $. But constants don't have that...Tallu
The $ is usually called a sigil. I haven't seen any hard and fast documentation that says string interpolations only works on variables and expressions with a $, but every example of string interpolation in PHP I can find uses it. grossvogel's postulation is probably the very reasonable reason that this is so.Vapor
OP could also use sprintf as a simple way to yield the same result. sprintf('This is a constant: %s', CONSTANT);Believe
Is there any reason why they can't treat {...} as special syntax? Why is it have to be {$...}?Waterlogged
I
7

Concatenation has been suggested as the only solution here, but that doesn't work when using syntax like:

    define("MY_CONSTANT", "some information");
    $html = <<< EOS
    <p>Some html, **put MY_CONSTANT here**</p>
EOS;

Of course, the above just puts the text 'MY_CONSTANT' in $html.

Other options include:

  • define a temporary variable to hold the constant:

        $myConst = MY_CONSTANT;
        $html = <<< EOS
        <p>Some html, {$myConst} </p>
    EOS;
    
  • if there are many constants, you can get an array of them all and use that:

        $constants = get_defined_constants();
        $html = <<< EOS
        <p>Some html, {$constants["MY_CONSTANT"]} </p>
    EOS;
    

Of course, in such a trivially short example, there's no reason to use the <<< operator, but with a longer block of output the above two may be much clearer and easier to maintain than a bunch of string concatenation!

Interwork answered 12/2, 2016 at 7:5 Comment(2)
this answer is amazing, well-thought out, provides new options, and refuses to do the too-common non-answer answer. tip of the hatWhore
I chose to assign that constant to a variable before using. It adds an extra line for each constant, but it's much more convenient. And it retains it's GLOBAL privilege.Waterlogged
P
2

The native interpolation does not support constants. Still not up to PHP 8.2 (and maybe later on). An alternative to echo is to use printf() or sprintf() for getting the interpolation result as string.

const MY_CONSTANT = "foo";
printf("Hello %s bar!", MY_CONSTANT);
Pancreatin answered 10/11, 2022 at 15:26 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.