我正在写一个CMS模板“引擎”。这个想法很简单--我会在HEREDOC字符串中预加载HTML片段,而不是在流控制要求时调用它们。
问题是,本文档字符串的行为很奇怪。下面是一个例子:
$ERROR_MESSAGE = "default";
$tst = <<<EOF
<div id="error-message">$ERROR_MESSAGE</div>
EOF;
function splice_message_output()
{
global $ERROR_MESSAGE;
global $tst;
if (isset($ERROR_MESSAGE))
{
echo <<<EOF
<div id="error-message">$ERROR_MESSAGE</div>
EOF;
echo $tst;
}
}下面有一个设置ERROR_MESSAGE并调用函数的条件:
if (isset($_GET["MSGTYPE"]))
{
if ($_GET["MSGTYPE"] == "ERR")
{
$ERROR_MESSAGE = $_GET["MSG"];
}
}
function splice_message_output()产出如下:
<div id="error-message">This is the errormessage text</div>
<div id="error-message">default</div>这怎麽可能?我在代码中明确定义了下面调用的字符串,HEREDOC片段返回刚才设置的字符串,另一个函数返回下面设置的字符串。
发布于 2015-10-04 09:14:02
如前所述,在更改$tst值之前,您已经声明了$ERROR_MESSAGE的值。你对这里的理解才是问题所在。当您将变量插入到heredoc (甚至任何类型的字符串)中时,这并不意味着要插入变量本身(或对变量的引用)。相反,您正在将该变量的值插入到heredoc中。例如,如果您有以下变量;
$var1 = "inserted var";
$var2 =
<<<VAR2
My $var1 goes here.
VAR2;..。更改$var1的值不会自动更改var2的值。
$var1 = "inserted var";
$var2 =
<<<VAR2
My $var1 goes here.
VAR2;
$var1 = "var changed";
echo
<<<MYECHO
var1: $var1
<br>
var2: $var2
MYECHO;产出:
var1: var changed
var2: My inserted var goes here.Heredoc的功能和其他字符串一样。区别在于,在本文档中,您避免了“和”之间的“和交换”或任何进一步的逃避地狱的需要。总的来说,本文档只是为了使代码更易于阅读和维护。
<?Php
echo "<button onclick='alert(\"double-quote\")'>double-quote</button>";
echo '<button onclick="alert('."'single-quote'".')">single-quote</button>';
echo
<<<HEREDOCSAMPLE
<button onclick='alert("heredoc")'>heredoc</button>
HEREDOCSAMPLE;
?>另一个有用的方法是现在文档,但前提是您不打算在字符串中插入任何php变量。
$this = "example";
echo
<<<'NOWDOCSAMPLE'
$this variable would not be treated as a $variable.
NOWDOCSAMPLE;产出:
$this variable would not be treated as a $variable.现在在您的代码示例中:
$ERROR_MESSAGE = "default";
$tst =
<<<EOF
<div id="error-message">$ERROR_MESSAGE</div>
EOF;
//THIS WOULD MAKE THE CURRENT VALUE OF $tst as:
//<div id="error-message">default</div>
function splice_message_output()
{ global $ERROR_MESSAGE;
global $tst;
if (isset($ERROR_MESSAGE))
// I DON'T THINK THIS VALIDATION MAKES SENSE SINCE $ERROR_MESSAGE
// WOULD ALWAYS BE DECLARED
{ echo <<<EOF
<div id="error-message">$ERROR_MESSAGE</div>
EOF;
echo $tst;
}
}
if (isset($_GET["MSGTYPE"]))
{ if ($_GET["MSGTYPE"] == "ERR")
{ $ERROR_MESSAGE = $_GET["MSG"];
// THE ONLY VARIABLE THAT CHANGED HERE IS $ERROR MESSAGE
// $tst DID NOT CHANGE AT ALL
}
}
function splice_message_output()
// RE-DECLARED FUNCTION? OR PERHAPS:
splice_message_output();
// AT THIS POINT ONLY $ERROR_MESSAGE HAS CHANGED ITS VALUE.现在,如果我提议对该代码进行修订,将是这样的:
$ERROR_MESSAGE = "default";
function splice_message_output()
{ global $ERROR_MESSAGE;
global $tst;
if (isset($_GET["MSG"]))
{ echo <<<EOF
<div id="error-message">$ERROR_MESSAGE</div>
EOF;
$tst = <<<EOF
<div id="error-message">$ERROR_MESSAGE</div>
EOF;
// NOW HERE'S A TRICKY ONE. SINCE YOU DECLARED $tst AS A
// GLOBAL VARIABLE WITHIN THIS FUNCTION, DOING AN if(isset($tst))
// OUTSIDE THIS FUNCTION AFTER CALLING THIS FUNCTION WOULD
// BE EQUAL TO 'TRUE'
echo $tst;
}
}
if (isset($_GET["MSGTYPE"]))
{ if ($_GET["MSGTYPE"] == "ERR")
{ $ERROR_MESSAGE = $_GET["MSG"];
// THE ONLY VARIABLE THAT CHANGED HERE IS $ERROR MESSAGE
// $tst DID NOT CHANGE AT ALL
}
}
// THE VARIABLE $tst DOESN'T EXIST AT THIS POINT BUT
splice_message_output(); // ONCE THIS FUNCTION IS CALLED
// $tst WOULD HAVE ALREADY EXISTED发布于 2015-03-05 09:20:08
您只定义过一次包含消息$tst的'default'。只有在设置了$ERROR_MESSAGE = $_GET["MSG"];并等于'ERR'时,函数下面的代码才会设置$_GET["MSGTYPE"]。因此,它设置变量,打印嵌入的HEREDOC字符串,然后打印没有更改的$tst。这里的HEREDOCs没有什么奇怪的!
我认为您感到困惑的地方是,您认为HEREDOC字符串将始终包含对$ERROR_MESSAGE的引用。情况并非如此。当变量在字符串中使用时,像$ERROR_MESSAGE这样的变量就会被它的内容替换,就像使用$tst = "The message is: $ERROR_MESSAGE";一样。之后,$tst的值将是'The message is: default'。
发布于 2015-10-04 09:53:05
在更改$tst的vale之前,将对$ERROR_MEGGAGE的值进行评估。因此,在HEREDOC语句中使用$ERROR_MESSAGE之前,只需检查条件并对其值进行任何更改。
https://stackoverflow.com/questions/25309292
复制相似问题