Interpolate a constant (not variable) into 'heredoc'
Asked Answered
B

8

59

Consider:

<?php
   define('my_const', 100);
   echo <<<MYECHO
      <p>The value of my_const is {my_const}.</p>
MYECHO;
?>

If I put a variable inside the braces, it prints out. But not the constant. How can I do it?

Brittneybrittni answered 6/4, 2012 at 8:50 Comment(1)
possible duplicate of define and heredocCorner
D
47

Use sprintf()

define('my_const', 100);
$string = <<< heredoc
      <p>The value of my_const is %s.</p>
heredoc;

$string = sprintf($string, my_const);
Devinna answered 6/4, 2012 at 8:54 Comment(6)
I had the same problem, and it was my only way. It's the same problem for methodsAcutance
@haltabush, You can use function also the same way.Devinna
at this point, we might as well assign the constant to a variable, as recommended belowChemoprophylaxis
Just to note that if you use numbered arguments e.g. %1$d, then these won't work with heredoc syntax because the $d is taken to mean a variable. Change it to nowdoc by putting single quotes around the label after the <<<Nodal
This would become too complicated if there's more constants to be used, so I like this answer much more: https://mcmap.net/q/327285/-interpolate-a-constant-not-variable-into-39-heredoc-39Wist
You can use numbered arguments like ThisLeeNoble suggestsed, but the answer you have quoted is good suggestion as well.Devinna
I
63

You can also approach the problem by assigning the value of the constant to a variable.

Personally I do it that way because if you have lots of constants in your string then your sprintf() call can be quite messy. It's also then harder to scan through the string and see what is doing what. Plus, by assigning the variables individually, you can see what is taking on what value.

An example would be:

$const = CONST;
$variable = VARIABLE;
$foo = (new Foo)->setFooProperty(12)->getFooProperty();
$bar = (123 - 456) * 10;
$ten = 1 + 2 + 1 + (5 - 4);
<<<EOD
Lorem ipsum dolor sit amet, **$variable** adipiscing elit.
Duis gravida aliquet dolor quis gravida.
Nullam viverra urna a velit laoreet, et ultrices purus condimentum.
Ut risus tortor, facilisis sed porta eget, semper a augue.
Sed adipiscing erat non sapien commodo volutpat.
Vestibulum nec lectus sed elit dictum accumsan vel adipiscing libero.
**$const** vehicula molestie sapien.
Ut fermentum quis risus ut pellentesque.
Proin in dignissim erat, eget molestie lorem. Mauris pretium aliquam eleifend.
**$foo** vitae sagittis dolor, quis sollicitudin leo.
Etiam congue odio sit amet sodales aliquet.
Etiam elementum auctor tellus, quis pharetra leo congue at. Maecenas sit amet ultricies neque.
Nulla luctus enim libero, eget elementum tellus suscipit eu.
Suspendisse tincidunt arcu at arcu molestie, a consequat velit elementum.
Ut et libero purus. Sed et magna vel elit luctus rhoncus.
Praesent dapibus consectetur tortor, vel **$bar** mauris ultrices id.
Mauris pulvinar nulla vitae ligula iaculis ornare.
Praesent posuere scelerisque ligula, id tincidunt metus sodales congue.
Curabitur lectus urna, porta sed molestie ut, mollis vitae libero.
Vivamus vulputate congue **$ten**.
EOD;
Inherit answered 2/1, 2013 at 14:6 Comment(3)
If I'm going to keep values in variables then why bothered defining constants in the first place?Curlew
@FatalError, its an old thread but I ran into same issue and this answer is better than the accepted one because, its possible that you have used the constant at many other places in your script but at one particular place you need to use it inside heredoc hence its better to just convert the constant in variable before you use heredoc.Dumond
this is marginally better than the accepted answerHarmon
D
47

Use sprintf()

define('my_const', 100);
$string = <<< heredoc
      <p>The value of my_const is %s.</p>
heredoc;

$string = sprintf($string, my_const);
Devinna answered 6/4, 2012 at 8:54 Comment(6)
I had the same problem, and it was my only way. It's the same problem for methodsAcutance
@haltabush, You can use function also the same way.Devinna
at this point, we might as well assign the constant to a variable, as recommended belowChemoprophylaxis
Just to note that if you use numbered arguments e.g. %1$d, then these won't work with heredoc syntax because the $d is taken to mean a variable. Change it to nowdoc by putting single quotes around the label after the <<<Nodal
This would become too complicated if there's more constants to be used, so I like this answer much more: https://mcmap.net/q/327285/-interpolate-a-constant-not-variable-into-39-heredoc-39Wist
You can use numbered arguments like ThisLeeNoble suggestsed, but the answer you have quoted is good suggestion as well.Devinna
N
23

Here is an little trick to allow double-quoted strings and heredocs to contain arbitrary expressions in curly braces syntax, including constants and other function calls. It uses the fact that a function name can be assigned to a variable and then called within heredoc:

<?php
    // Declare a simple function
    function _placeholder($val) { return $val; }
    // And assign it to something short and sweet
    $_ = '_placeholder';

    // Or optionally for php version >= 5.3
    // Use a closure (anomynous function) like so:
    $_ = function ($val){return $val;};

    // Our test values
    define('abc', 'def');
    define('ghi', 3);

    $a = 1;
    $b = 2;

    function add($a, $b) { return $a+$b; }

    // Usage
    echo "b4 {$_(1+2)} after\n"; // Outputs 'b4 3 after'
    echo "b4 {$_(abc)} after\n"; // Outputs 'b4 def after'
    echo "b4 {$_(add($a, $b)+ghi*2)} after\n"; // Outputs 'b4 9 after'
    $text = <<<MYEND

    Now the same in heredoc:
    b4 {$_(1+2)} after
    b4 {$_(abc)} after
    b4 {$_(add($a, $b)+ghi*2)} after

    MYEND;
    echo $text;
Nicholasnichole answered 22/9, 2016 at 21:56 Comment(3)
This is a great trick. Also works well for inserting static class properties.Kruger
Worked great for passing calculated values into a heredoc containing a JavaScript script. Had a bit of trouble at first because I forgot to put quotes around the string I was passing -- DuhVertical
Works well and probably faster than the accepted answerDowitcher
L
13

You may use the "constant" function.

for example:

    <?php
    define('CONST1', 100);
    define('CONST2', 200);
    $C= 'constant';
    echo <<<MYECHO
          <p>The value of CONST1 is: {$C('CONST1')}, 
              and CONST2 is:{$C('CONST2')}.</p>
    MYECHO;
    ?> 
Lupe answered 26/11, 2020 at 2:37 Comment(0)
N
12

You can also use the get_defined_constants function. It puts back all currently defined constants in an array, which you can use in your HEREDOC string:

// Let's say there is FOO and BAR defined
$const = get_defined_constants();

$meta = <<< EOF
     my awesome string with "{$const['FOO']}" and "{$const['BAR']}" constants
EOF;
Necropolis answered 11/6, 2015 at 10:13 Comment(1)
This is usually not such a good idea, as the list will be quite large, because it includes all the constants from the language core and extensions in addition to the ones you really want. Manually assigning them to local variables seems cleaner.Girhiny
P
1

Put your defined variable into simple variable and use include it in heredoc just as in following example:

<?php
define('my_const', 100);
$variable = my_const;
   echo <<<MYECHO
      <p>The value of my_const is {$variable}.</p>
MYECHO;
?>
Philips answered 15/11, 2014 at 11:48 Comment(2)
This is the same as @Lukey's answer and does not add anythingJuice
This is a lot more succinct than @Lukey's answer. I think it adds the benefit of brevity.Irresolvable
C
0

I've become fond of using variable names that look like the constants they represent. So, for a more real-world example:

define('CONST_AUTHOR_FILTER_FIELD',      'authorValue') ;
define('CONST_CB_AUTO_SUBMIT',           'cbAutoSubmit') ;
define('CONST_CB_EXACT_AUTHOR',          'cbAuthorExact') ;
define('CONST_CB_FILTER_AUTHOR',         'cbFilterAuthor') ;

Note: The example is extracted from a script that has used defined constants for the INPUT names on an HTML form.

Then, in a loop:

foreach (get_defined_constants(true)['user') AS $constName => $value)
    if (substr($constName, 0, 6) == 'CONST_')
        $$constName = $value ;

Due to the advent of (documented feature) double-dollarsign ($$) above, this code will set the values of $CONST_AUTHOR_FILTER_FIELD, $CONST_CB_AUTO_SUBMIT, $CONST_CB_EXACT_AUTHOR, and $CONST_CB_FILTER_AUTHOR to match their constant counterparts. if you have a defined constant like ('DEFAULT_STATE', 'VA') then it will be ignored by this code (not named CONST_ something).

There are huge advantages to this, primarily in the area of consistency. For me, at least - others may disagree - code like

$myVar = SOME_CONSTANT

(where the variable names and the constant names are dissimilar) will just lead to programming errors. While this will certainly not eliminate programming errors, it goes far in making them less common, and perhaps easier to spot and correct.

For the record: I go a step further with this, making constants for my JavaScript and naming my INPUT items similarly. Extracted from the same code:

echo <<<EOS
    <!DOCTYPE html>
    <html lang="en">
        <head>
          . . . .
          <style> 
             . . . .
        </style>
        <script>
            const url = '$url' ;

    EOS ;
foreach (get_defined_constants(true)['user'] AS $constant => $value)
    if (substr($constant, 0, 6) == 'CONST_') {
        echo 'const ' . $constant . " = '" . $value . "' ;" . PHP_EOL ;
    }
echo <<<EOS
        </script>
        <script src='$jsFile?modTime=$jsModTime'></script>
    </head>
. . . .
<td><input onclick='authorFilterClicked(this)' type='checkbox' name='$CONST_CB_FILTER_AUTHOR' id='$CONST_CB_FILTER_AUTHOR' $filterAuthorChecked />
   <label for='$CONST_CB_FILTER_AUTHOR'>Filter author</label></td>
<td><input onclick='authorRegExClicked(this)' type='checkbox' name='$CONST_CB_USE_REGEX_AUTHOR' id='$CONST_CB_USE_REGEX_AUTHOR' $authorUseRegExChecked />
   <label for= '$CONST_CB_USE_REGEX_AUTHOR'>Use REGEX</label></td>
<td>Author filter</td>
. . . 

Then, in the JavaCode, I can refer to the same constant names I used in the PHP code, and know with confidence that they refer to the same thing.

Chavaree answered 29/11, 2023 at 19:15 Comment(0)
S
-2

Not everybody will like the use of shorthand echo tags, but this is still an option:

<?php
   define('my_const', 100);
?>
      <p>The value of my_const is <?= my_const ?>.</p>
Scorpion answered 28/1, 2023 at 22:49 Comment(0)

© 2022 - 2025 — McMap. All rights reserved.