将一个常数(非变量)插入到“heredoc”中进行插值

57

考虑:

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

如果我把一个变量放在大括号里,它就会被打印出来。但是常量不行。我该怎么做呢?


可能是define和heredoc的重复问题。 - dsnunez
8个回答

62

你也可以通过将常量的值赋给一个变量来解决这个问题。

个人而言,我喜欢这种方式,因为如果你在字符串中有很多常量,那么你的sprintf()函数调用可能会很混乱。此外,扫描字符串并查看每个常量具体代表什么也更加困难。通过单独分配变量,你可以看到哪些值被赋给了哪些变量。

例如:

$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;

3
如果我要将值保存在变量中,那么为什么要首先定义常量呢? - Rain
3
@FatalError,这是一个旧的帖子,但我遇到了相同的问题,这个答案比被接受的答案更好,因为你可能在脚本的许多其他地方都使用了常量,但在一个特定的地方,你需要在heredoc中使用它,因此最好在使用heredoc之前将常量转换为变量。 - Abhay Maurya
这比已接受的答案略好一些。 - ddruganov

45

使用sprintf()

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

$string = sprintf($string, my_const);

我曾经遇到过同样的问题,这是我的唯一解决办法。对于方法来说也是同样的问题。 - haltabush
1
@haltabush,您可以以相同的方式使用函数。 - Starx
2
此时,我们最好将常量分配给一个变量,如下所建议。 - Mirko Pagliai
请注意,如果您使用带编号的参数,例如%1$d,则这些参数将无法与heredoc语法一起使用,因为$d会被视为变量。请在<<<后面的标签周围加上单引号,以更改为nowdoc语法。 - ThisLeeNoble
如果有更多的常量需要使用,这将变得太复杂,因此我更喜欢这个答案:https://dev59.com/6Wkw5IYBdhLWcg3wPIB7#65015391 - gnysek

22

以下是一种小技巧,允许在双引号字符串和heredoc中使用花括号语法包含任意表达式(包括常量和其他函数调用)。它利用了函数名可以被赋值给变量,然后在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;

4
这是一个很棒的技巧。同样适用于插入静态类属性。 - hackel
1
在传递计算值到包含JavaScript脚本的heredoc中非常有效。起初遇到了一些麻烦,因为我忘记在传递的字符串周围加上引号——呃。 - Stephen R
运行良好,可能比被接受的答案更快。 - Guesser

13
您可以使用"constant"函数。 例如:
    <?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;
    ?> 

12

你也可以使用 get_defined_constants 函数。它将所有当前定义的常量放回到一个数组中,您可以在HEREDOC字符串中使用:

// 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;

14
通常这并不是一个好主意,因为列表会非常庞大,其中包括语言核心和扩展中的所有常量,而你真正需要的可能只有一小部分。手动将它们赋值给本地变量会更加清晰易懂。 - FGM

1
将您定义的变量放入简单变量中,并像以下示例中那样在heredoc中使用它:
<?php
define('my_const', 100);
$variable = my_const;
   echo <<<MYECHO
      <p>The value of my_const is {$variable}.</p>
MYECHO;
?>

5
这与@Lukey的答案相同,没有增加任何内容。 - chiliNUT
6
这比@Lukey的回答更为简明。我觉得这样做增添了简洁性的好处。 - Sean Colombo

0
我已经喜欢上使用看起来像常量的变量名了。所以,举个更贴近现实的例子:
define('CONST_AUTHOR_FILTER_FIELD',      'authorValue') ;
define('CONST_CB_AUTO_SUBMIT',           'cbAutoSubmit') ;
define('CONST_CB_EXACT_AUTHOR',          'cbAuthorExact') ;
define('CONST_CB_FILTER_AUTHOR',         'cbFilterAuthor') ;

注意:此示例摘自一个脚本,该脚本已为HTML表单上的输入名称定义了常量。
然后,在一个循环中:
foreach (get_defined_constants(true)['user') AS $constName => $value)
    if (substr($constName, 0, 6) == 'CONST_')
        $$constName = $value ;

由于上述(记录的特性)双美元符号($$)的出现,此代码将设置$CONST_AUTHOR_FILTER_FIELD、$CONST_CB_AUTO_SUBMIT、$CONST_CB_EXACT_AUTHOR和$CONST_CB_FILTER_AUTHOR的值,使其与其常量对应项相匹配。如果您有一个定义的常量,比如('DEFAULT_STATE','VA'),那么此代码将忽略它(不以CONST_开头的常量)。
这样做有很大的优势,主要体现在一致性方面。至少对我来说,代码如下所示: $myVar = SOME_CONSTANT
(其中变量名和常量名不相似)只会导致编程错误。虽然这当然不能消除编程错误,但它在减少错误的发生频率方面起到了很大的作用,也许更容易发现和纠正。
值得一提的是:我在JavaScript中也采用类似的方式,为我的输入项命名常量。从同一段代码中提取的内容:
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>
. . . 

然后,在Java代码中,我可以引用与我在PHP代码中使用的相同的常量名称,并且可以确信它们指的是同一件事。

-1

并不是每个人都喜欢使用简写的回显标签,但这仍然是一种选择:

<?php
   define('my_const', 100);
?>
      <p>The value of my_const is <?= my_const ?>.</p>

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接