2019-07-23更新
使用heredoc语法报错:
有些时候在使用heredoc语法时,尽管遵守了规则,但可能因为习惯性的在纯PHP文本不写结束标签?>而导致报错,报错原因暂未研究。

原文:

报错:
Parse error: syntax error, unexpected end of file, expecting variable (T_VARIABLE) or heredoc end (T_END_HEREDOC) or ${ (T_DOLLAR_OPEN_CURLY_BRACES) or {$ (T_CURLY_OPEN) in...

源码:

<?php

class Demo 
{
	// 类常量就是它的值在类中始终不变的量
	// 类常量是用const关键字创建,不要加$,必须初始化
	const siteName = 'php中文网';
	// 类常量从php5.3开始支持nowdoc语法
	const domain = <<< 'EOT'
	<a href="">www.php</a>
	EOT;
	public function getSiteName()
	{
		//在类的方法中访问类常量:self::内场了名
		return self::siteName;
	}
}

//方法1:类名::类常量名
echo '1.类名::类常量名:'.Demo::siteName.Demo::domain.'<hr/>';

//方法2:类变量::类常量名 php5.3+
$className = 'Demo';
echo '2.类变量::类常量名:'.$className::siteName.'<hr/>';

//方法3:用当前类的对象来访问类常量
echo '3.对象::类常量名:'.(new Demo)::siteName.'<hr/>';
错误原因

在使用nowdoc结构时要注意:

Warning!!!

要注意的是结束标识符这行除了可能有一个分号(;)外,绝对不能包含其它字符。这意味着标识符不能缩进,分号的前后也不能有任何空白或制表符。 更重要的是结束标识符的前面必须是个被本地操作系统认可的换行,比如在 UNIX 和 Mac OS X 系统中是 \n,而结束定界符(可能其后有个分号)之后也必须紧跟一个换行。

如果不遵守该规则导致结束标识不“干净”,PHP 将认为它不是结束标识符而继续寻找。如果在文件结束前也没有找到一个正确的结束标识符,PHP 将会在最后一行产生一个解析错误。

Heredocs 结构不能用来初始化类的属性。自 PHP 5.3 起,此限制仅对 heredoc 包含变量时有效。

改错后代码
<?php

class Demo 
{
	// 类常量就是它的值在类中始终不变的量
	// 类常量是用const关键字创建,不要加$,必须初始化
	const siteName = 'php中文网';
	// 类常量从php5.3开始支持nowdoc语法
	const domain = <<< 'EOT'
<a href="">www.php</a>
EOT;
	public function getSiteName()
	{
		//在类的方法中访问类常量:self::内场了名
		return self::siteName;
	}
}

//方法1:类名::类常量名
echo '1.类名::类常量名:'.Demo::siteName.Demo::domain.'<hr/>';

//方法2:类变量::类常量名 php5.3+
$className = 'Demo';
echo '2.类变量::类常量名:'.$className::siteName.'<hr/>';

//方法3:用当前类的对象来访问类常量
echo '3.对象::类常量名:'.(new Demo)::siteName.'<hr/>';
关于Heredocs 结构和Nowdoc结构
Heredoc 结构

表达字符串的方法, heredoc 句法结构:<<<。在该运算符之后要提供一个标识符,然后换行。接下来是字符串 string 本身,最后要用前面定义的标识符作为结束标志。

结束时所引用的标识符必须在该行的第一列,而且,标识符的命名也要像其它标签一样遵守 PHP 的规则:只能包含字母、数字和下划线,并且必须以字母和下划线作为开头。

Heredoc 结构就象是没有使用双引号的双引号字符串,这就是说在 heredoc 结构中单引号不用被转义,但是上文中列出的转义序列还可以使用。变量将被替换,但在 heredoc 结构中含有复杂的变量时要格外小心。

Heredoc 结构的字符串示例:

<?php
$str = <<<EOD
Example of string
spanning multiple lines
using heredoc syntax.
EOD;

/* 含有变量的更复杂示例 */
class foo
{
    var $foo;
    var $bar;

    function foo()
    {
        $this->foo = 'Foo';
        $this->bar = array('Bar1', 'Bar2', 'Bar3');
    }
}

$foo = new foo();
$name = 'MyName';

echo <<<EOT
My name is "$name". I am printing some $foo->foo.
Now, I am printing some {$foo->bar[1]}.
This should print a capital 'A': \x41
EOT;
?>

以上例程会输出:

My name is "MyName". I am printing some Foo.
Now, I am printing some Bar2.
This should print a capital 'A': A

其他用法:

  1. 也可以把 Heredoc 结构用在函数参数中来传递数据
  2. 在 PHP 5.3.0 以后,也可以用 Heredoc 结构来初始化静态变量和类的属性和常量
  3. 自 PHP 5.3.0 起还可以在 Heredoc 结构中用双引号来声明标识符
Nowdoc 结构

就象 heredoc 结构类似于双引号字符串,Nowdoc 结构是类似于单引号字符串的。Nowdoc 结构很象 heredoc 结构,但是 nowdoc 中不进行解析操作。这种结构很适合用于嵌入 PHP 代码或其它大段文本而无需对其中的特殊字符进行转义。与 SGML 的 <![CDATA[ ]]> 结构是用来声明大段的不用解析的文本类似,nowdoc 结构也有相同的特征。

一个 nowdoc 结构也用和 heredocs 结构一样的标记 <<<, 但是跟在后面的标识符要用单引号括起来,即 <<<‘EOT’。Heredoc 结构的所有规则也同样适用于 nowdoc 结构,尤其是结束标识符的规则。

结构字符串示例:

<?php
$str = <<<'EOD'
Example of string
spanning multiple lines
using nowdoc syntax.
EOD;

/* 含有变量的更复杂的示例 */
class foo
{
    public $foo;
    public $bar;

    function foo()
    {
        $this->foo = 'Foo';
        $this->bar = array('Bar1', 'Bar2', 'Bar3');
    }
}

$foo = new foo();
$name = 'MyName';

echo <<<'EOT'
My name is "$name". I am printing some $foo->foo.
Now, I am printing some {$foo->bar[1]}.
This should not print a capital 'A': \x41
EOT;
?>

以上例程会输出:

My name is "$name". I am printing some $foo->foo.
Now, I am printing some {$foo->bar[1]}.
This should not print a capital 'A': \x41
NOTE:
  1. 不象 heredoc 结构,nowdoc 结构可以用在任意的静态数据环境中,最典型的示例是用来初始化类的属性或常量
  2. Nowdoc 结构是在 PHP 5.3.0 中加入的。

详细相关请参考:PHP手册中 heredoc 和 nowdoc

更多推荐

Parse error: syntax error, unexpected end of file, expecting variable (T_VARIABL