简体   繁体   English

PHP HEREDOC解析?

[英]PHP HEREDOC parsing?

I EDITED THE Q, AS THERE WAS NO ANSWERS. 由于没有答案,我编辑了Q。

I am a beginner in PHP, and I am writing a CMS templating "engine". 我是PHP的初学者,正在编写CMS模板“引擎”。 The idea is quite simple - I would preload snippets of HTML in HEREDOC strings, and than call them as and if the flow control asks for them. 这个想法很简单-我会在HEREDOC字符串中预加载HTML片段,然后在流控件要求它们时调用它们。

The issue is that heredoc strings behave strange. 问题是heredoc字符串的行为很奇怪。 Here is the example: 这是示例:

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

Below I have a condition that sets ERROR_MESSAGE and calls the function: 下面,我有一个条件设置ERROR_MESSAGE并调用该函数:

if (isset($_GET["MSGTYPE"]))
    {
    if ($_GET["MSGTYPE"] == "ERR")
        {
        $ERROR_MESSAGE = $_GET["MSG"];

        }
    }

   function splice_message_output()

And the output is: 输出为:

<div id="error-message">This is the errormessage text</div>
<div id="error-message">default</div>

How is this possible? 这怎么可能? I have clearly defined strign that was called BELOW in code, and the HEREDOC snippet returns the string that was set just above, and the other function the string that was set below. 我已经清楚地定义了在代码中称为BELOW的strign,并且HEREDOC代码段返回刚在上面设置的字符串,而另一个函数则在下面设置了字符串。

You only ever define $tst once with the message 'default' in it. 您只定义一次$tst ,并在其中输入消息'default' Your code below the function sets $ERROR_MESSAGE = $_GET["MSG"]; 该函数下方的代码设置了$ERROR_MESSAGE = $_GET["MSG"]; only if $_GET["MSGTYPE"] is set and equals 'ERR' . 仅当$_GET["MSGTYPE"]设置且等于'ERR' So it sets the variable, prints the embedded HEREDOC string and then prints $tst which hasn't changed. 因此,它设置变量,打印嵌入的HEREDOC字符串,然后打印未更改的$tst There is nothing strange about HEREDOCs here! 这里的HEREDOC没有什么奇怪的!

I think where you're getting confused is that you think the HEREDOC string will always contain a reference to $ERROR_MESSAGE . 我认为让您感到困惑的是,您认为HEREDOC字符串将始终包含对$ERROR_MESSAGE的引用。 This is not so. 事实并非如此。 A variable such as $ERROR_MESSAGE is replaced by its contents whenever it is used in a string, exactly the same as if you used $tst = "The message is: $ERROR_MESSAGE"; 只要在字符串中使用$ERROR_MESSAGE类的变量,其内容就会替换为内容,与使用$tst = "The message is: $ERROR_MESSAGE";完全相同$tst = "The message is: $ERROR_MESSAGE"; . Afterwards the value of $tst will be 'The message is: default' . 之后, $tst的值将为'The message is: default'

As mentioned, you have already declared the value of $tst before changing the value of $ERROR_MESSAGE. 如前所述,在更改$ ERROR_MESSAGE的值之前,您已经声明了$ tst的值。 Your understanding of heredoc is the problem here. 您对heredoc的理解就是这里的问题。 When you're inserting a variable into a heredoc (or even any type of string for that matter), it doesn't literally mean that you're inserting that variable itself (or a reference to the variable). 当您将变量插入heredoc(或什至是任何类型的字符串)时,这并不意味着您要插入该变量本身(或对该变量的引用)。 Rather, you are inserting the value of that variable into the heredoc. 而是将变量的值插入heredoc。 So for example, if you have the following variables; 因此,例如,如果您具有以下变量;

$var1 = "inserted var";
$var2 =
<<<VAR2
My $var1 goes here.
VAR2;

... changing the value of $var1 would not automatically change the value of var2. ...更改$ var1的值不会自动更改var2的值。

$var1 = "inserted var";
$var2 =
<<<VAR2
My $var1 goes here.
VAR2;

$var1 = "var changed";

echo
<<<MYECHO
var1: $var1
<br>
var2: $var2
MYECHO;

OUTPUT: 输出:

var1: var changed
var2: My inserted var goes here.

Heredoc functions like every other string. Heredoc的功能与其他所有字符串一样。 The difference is that in heredoc, you avoid the need to escape " and interchange between ' and " or any further escape hell. 区别在于,在heredoc中,您避免了对“进行转义以及在'和”之间进行互换或任何其他转义地狱的需要。 Overall, heredoc is just for making your code much easier to read and maintain. 总体而言,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;
?>

Another useful one is the nowdoc, but only if you're not planning to insert any php variable in your string. 另一个有用的功能是nowdoc,但前提是您不打算在字符串中插入任何php变量。

$this = "example";
echo
<<<'NOWDOCSAMPLE'
$this variable would not be treated as a $variable.
NOWDOCSAMPLE;

OUTPUT: 输出:

$this variable would not be treated as a $variable.

Now in your code sample: 现在在您的代码示例中:

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

Now if I were to propose a revision of that code, this'll be it: 现在,如果我打算对该代码进行修订,就是这样:

$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

The value of $tst is being evaluated before you can change the vale of $ERROR_MEGGAGE . 您必须先评估$tst的值,然后才能更改$ERROR_MEGGAGE So, you simply need to check your condition and make any changes to the value of $ERROR_MESSAGE before you use it in the HEREDOC statement for $tst . 因此,您只需要检查条件并对$ERROR_MESSAGE的值进行任何更改,然后再在$tst的HEREDOC语句中使用它即可。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM