【问题标题】:Constants inside quotes are not printed?引号内的常量不打印?
【发布时间】:2010-05-30 01:25:22
【问题描述】:

这会打印苹果:

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

但这不是:

echo "This is a constant: CONSTANT";

为什么?

【问题讨论】:

  • 我不明白。第二种情况的预期输出是什么? This is a apple: A?
  • 想想如果解析器必须检查是否有任何子字符串与定义的常量匹配,那么解析双引号字符串会做多少工作......并且当您定义更多常量时它会变慢。并且,在定义该常量之后,您必须在所有字符串中转义大写字母 A!
  • 不打印的原因是因为它被视为字符串文字。 PHP 不知道在第二个示例中替换 apple,您必须像 Artefacto 演示的那样手动定义它。
  • 因为 PHP 设计不佳。许多其他语言都可以很好地处理这个问题。
  • @BlaineLafreniere 抱歉,我并不是要暗示 一般 仅在 PHP 中使用原始问题中的语法会很困难。在您的 Ruby 示例(以及许多其他字符串模板系统)中,开发人员有一种方法可以指示将字符串的 哪一部分 视为代码。这是这里的关键区别

标签: php


【解决方案1】:

因为“不打印引号内的常量”。正确的形式是:

echo "This is a constant: " . CONSTANT;

点是连接运算符。

【讨论】:

  • 只要有"{$var}",我希望"{CONSTANT}" 也能匹配字符串插值语法。
  • @AlainTiemblo 我也预料到了这一点。 Ruby 做了这样的事情:“这是一个#{CONSTANT}”。我觉得有趣的是这里有 cmets 说对常量进行相同类型的解析非常困难或缓慢或不可能或其他什么......是的,对。
  • @BlaineLafreniere - 我没有看到这样的 cmets。我看到的 cmets 实际上说,给定当前的语法,这是不可能的、困难的或缓慢的。请注意,OP 甚至没有将 {} 放在字符 CONSTANT 周围 - 显然完全缺乏特殊语法将是解析的噩梦,并且无法知道程序员是否打算进行替换。
【解决方案2】:
define('QUICK', 'slow');
define('FOX', 'fox');

$K = 'strval';

echo "The {$K(QUICK)} brown {$K(FOX)} jumps over the lazy dog's {$K(BACK)}.";

【讨论】:

  • 如果不明显,间接函数调用技术的大问题是 $K 不在全局命名空间中,因此必须在每个需要使用的函数中使用 global $K; 声明它。
【解决方案3】:

如果你想在字符串中包含对变量的引用,你需要使用特殊的语法。此功能称为字符串插值,并包含在大多数脚本语言中。

This page 描述了 PHP 中的特性。在 PHP 中的字符串插值期间似乎不会替换常量,因此获得所需行为的唯一方法是使用 Artefacto 建议的连接。

其实我刚刚发现another post说了这么多:

AFAIK,使用静态变量,一个有 与常量相同的“问题”: 无法进行插值,只需使用 临时变量或连接。

【讨论】:

  • 不能将特殊语法{} 与常量一起使用的原因很简单:只有在{ 后面紧跟$ 时,方括号才会被识别为“特殊语法”。但是常量没有那个...
  • $ 通常被称为印记。我还没有看到任何硬性和快速的文档说字符串插值仅适用于带有$ 的变量和表达式,但我能找到的 PHP 中字符串插值的每个示例都使用它。 Grossvogel 的假设可能是非常合理的原因。
  • OP 也可以使用sprintf 作为产生相同结果的简单方法。 sprintf('This is a constant: %s', CONSTANT);
  • 有什么理由不能将 {...} 视为特殊语法?为什么必须是 {$...}?
【解决方案4】:

这个问题已经回答了,但我想提供一个更通用的见解。

在双引号中,PHP 将任何以$ 开头的内容识别为要插值的变量。此外,它考虑了数组和对象访问([]->),但只考虑了一个级别。例如。 "$foo->bar" 插入 $foo->bar$foo->bar->baz 做同样的事情,并将 ->baz 视为字面上的字符串。此外,对于字符串键,[] 中的引号必须省略。例如。 "$foo[bar]" 插入 $foo['bar']"$foo['bar']" 是语法错误。 AFAIK,就是这样。要获得更多功能,您需要"{$...}" 语法。

这里的$ 实际上是语法的一部分,没有它就无法工作。例如。 "{FOO}" 不会插入常量 FOO,它只是一个语法错误。然而,除了一些奇怪的语法限制之外,这个构造实际上非常强大,并且可以包含任何有效的 PHP 表达式,只要它以 $ 开头并且是数组访问、对象访问或函数调用。 (也许其他一些情况是允许的。如果有人对此有更好的理解,请告诉我。)解决问题的最通用方法是在您的某处定义类似以下函数的内容代码库:

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

这只是一个身份函数——它返回你给它的任何东西。它必须定义为匿名函数,因此您可以将其称为$id$

现在您可以使用此函数插入​​任何 PHP 表达式:

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

不能使用匿名函数的 PHP 版本

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)}"

【讨论】:

    【解决方案5】:

    这里建议将连接作为唯一的解决方案,但是在使用以下语法时不起作用:

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

    当然,上面只是将文本'MY_CONSTANT'放在$html中。

    其他选项包括:

    • 定义一个临时变量来保存常量:

          $myConst = MY_CONSTANT;
          $html = <<< EOS
          <p>Some html, {$myConst} </p>
      EOS;
      
    • 如果有很多常量,你可以得到一个数组并使用它:

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

    当然,在如此简单的例子中,没有理由使用

    【讨论】:

    • 这个答案很棒,经过深思熟虑,提供了新的选择,并且拒绝做太常见的非答案答案。帽子的尖端
    猜你喜欢
    • 2015-03-01
    • 1970-01-01
    • 1970-01-01
    • 2022-06-28
    • 2015-03-31
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多