PHP EOF(heredoc)

EOF(End Of File)是PHP中用于表示多行字符串的一种特殊语法,也被称为heredoc和nowdoc语法。这种语法让处理包含引号、换行和变量的多行文本变得更加方便。

PHP heredoc语法

heredoc语法用于创建多行字符串,同时会解析字符串中的变量和转义序列。

heredoc的基本语法

<<<标识符
多行字符串内容
标识符;

heredoc的特点

  • 开始标记是<<<后面跟着一个标识符(通常是大写字母,如EOT、EOF、HTML等)
  • 结束标记必须是单独一行,且不能有缩进
  • 结束标记后面必须紧跟分号
  • 字符串内容中的变量会被解析
  • 字符串内容中的转义序列会被解析(如\n、\t等)

heredoc的基本示例

<?php
$str = <<<EOT
这是一个
多行字符串
示例
EOT;

echo $str;
// 输出:
// 这是一个
// 多行字符串
// 示例
?>

在heredoc中使用变量

<?php
$name = "John";
$age = 30;

$message = <<<EOT
亲爱的 $name:

你好!你今年 $age 岁。
这是一条使用heredoc语法创建的多行消息。

祝好,
系统管理员
EOT;

echo $message;
// 输出:
// 亲爱的 John:
// 
// 你好!你今年 30 岁。
// 这是一条使用heredoc语法创建的多行消息。
// 
// 祝好,
// 系统管理员
?>

在heredoc中使用复杂表达式

PHP 5.3及以上版本支持在heredoc中使用更复杂的表达式:

<?php
$user = array("name" => "John", "age" => 30);

$message = <<<EOT
用户信息:
姓名: {$user['name']}
年龄: {$user['age']}
一年后的年龄: {$user['age'] + 1}

欢迎 {$user['name']} 加入我们的系统!
EOT;

echo $message;
?>

PHP nowdoc语法

nowdoc语法类似于heredoc,但它不会解析字符串中的变量和转义序列,将内容原样输出。它类似于单引号字符串,但支持多行。

nowdoc的基本语法

<<<'标识符'
多行字符串内容
标识符;

nowdoc和heredoc的唯一区别是nowdoc的标识符用单引号包围。

nowdoc的示例

<?php
$name = "John";

$message = <<<'EOT'
亲爱的 $name:

你好!变量 $name 不会被解析。
这是一条使用nowdoc语法创建的多行消息。

转义序列也不会被解析: \n \t
EOT;

echo $message;
// 输出:
// 亲爱的 $name:
// 
// 你好!变量 $name 不会被解析。
// 这是一条使用nowdoc语法创建的多行消息。
// 
// 转义序列也不会被解析: \n \t
?>

heredoc和nowdoc的区别

特性 heredoc nowdoc
语法 <<<标识符 <<<'标识符'
变量解析 会解析变量 不解析变量
转义序列 解析转义序列 不解析转义序列
类似于 双引号字符串 单引号字符串

heredoc和nowdoc的实际应用场景

1. 创建HTML模板

<?php
$title = "欢迎来到我的网站";
$content = "这是网站的主要内容。";
$footer = "版权所有 © 2023";

$html = <<<HTML
<!DOCTYPE html>
<html>
<head>
    <title>$title</title>
</head>
<body>
    <header>
        <h1>$title</h1>
    </header>
    <main>
        <p>$content</p>
    </main>
    <footer>
        <p>$footer</p>
    </footer>
</body>
</html>
HTML;

echo $html;
?>

2. 定义SQL查询

<?php
$table = "users";
$fields = "id, name, email, created_at";
$conditions = "status = 'active'";

$sql = <<<SQL
SELECT $fields
FROM $table
WHERE $conditions
ORDER BY created_at DESC
LIMIT 10;
SQL;

// 然后使用这个SQL查询
// $result = mysqli_query($connection, $sql);
?>

3. 创建配置文件或配置块

<?php
// 使用nowdoc来创建不解析的配置数据
$config = <<<'CONFIG'
[database]
host = localhost
port = 3306
username = root
password = secret

[application]
debug = true
log_level = info
CONFIG;

file_put_contents('config.ini', $config);
?>

4. 生成电子邮件内容

<?php
$to = "user@example.com";
$subject = "账户激活";
$username = "John";
$activation_link = "https://example.com/activate?token=abc123";

$message = <<<EMAIL
亲爱的 $username,

感谢您注册我们的服务!
请点击下面的链接激活您的账户:
$activation_link

如果您没有注册我们的服务,请忽略此邮件。

此致,
客户支持团队
EMAIL;

// 然后发送电子邮件
// mail($to, $subject, $message);
?>

heredoc和nowdoc的高级用法

1. 在函数和方法中使用

<?php
function getWelcomeMessage($name) {
    return <<<EOT
欢迎,$name!
这是您的个人欢迎消息。
EOT;
}

class User {
    public function getProfileHtml() {
        $name = $this->name;
        $email = $this->email;
        
        return <<<HTML
<div class="user-profile">
    <h3>$name</h3>
    <p>Email: $email</p>
</div>
HTML;
    }
}
?>

2. 使用双引号或不用引号的标识符(PHP 7.3+)

PHP 7.3及以上版本支持在heredoc中使用双引号或不用引号的标识符:

<?php
// PHP 7.3+ 支持的语法
$str1 = <<<"EOT"
这是使用双引号标识符的heredoc
EOT;

$str2 = <<<EOT
这是不用引号标识符的heredoc(PHP 7.3+)
EOT;
?>

3. 结束标记后不加分号(PHP 7.3+)

PHP 7.3及以上版本中,如果heredoc是语句的最后一部分,可以省略结束标记后的分号:

<?php
// PHP 7.3+ 支持的语法
echo <<<EOT
这是一个示例
EOT
// 注意:这里没有分号
?>

4. 在字符串中嵌入heredoc(PHP 5.6+)

PHP 5.6及以上版本允许在字符串中嵌入heredoc:

<?php
$greeting = "你好,".<<<EOT
世界!
这是一个嵌入在字符串中的heredoc
EOT;

echo $greeting;
?>

heredoc和nowdoc综合示例

<?php
// 定义一些变量
$name = "PHP学习者";
$version = phpversion();
$features = array("面向对象", "类型声明", "命名空间", "异常处理");

// 1. 使用heredoc创建包含变量的欢迎消息
$welcome = <<<WELCOME
欢迎来到PHP教程!

您正在使用的PHP版本是: $version

以下是PHP的一些主要特性:
WELCOME;

echo $welcome;

// 2. 在heredoc中循环数组
echo <<<FEATURES
<ul>
FEATURES;

foreach ($features as $feature) {
    echo "    <li>$feature</li>\n";
}

echo <<<FEATURES
</ul>
FEATURES;

// 3. 使用nowdoc创建不解析的代码示例
$code_example = <<<'CODE'
// 这是一个PHP代码示例
// 变量不会被解析: $name
function hello() {
    echo "Hello world!\n";
}
CODE;

echo <<<HTML
<h3>PHP代码示例</h3>
<pre><code>$code_example</code></pre>
HTML;

// 4. 使用heredoc创建HTML表单
$form = <<<FORM
<h3>用户注册表单</h3>
<form method="post" action="submit.php">
    <div class="form-group">
        <label for="username">用户名:</label>
        <input type="text" id="username" name="username" placeholder="输入用户名">
    </div>
    <div class="form-group">
        <label for="email">邮箱:</label>
        <input type="email" id="email" name="email" placeholder="输入邮箱">
    </div>
    <div class="form-group">
        <label for="password">密码:</label>
        <input type="password" id="password" name="password" placeholder="输入密码">
    </div>
    <button type="submit" class="btn-submit">注册</button>
</form>
FORM;

echo $form;

// 5. 使用heredoc定义JSON数据
$user_data = <<<JSON
{
    "name": "$name",
    "language": "PHP",
    "version": "$version",
    "active": true,
    "features": [
        "{$features[0]}",
        "{$features[1]}",
        "{$features[2]}",
        "{$features[3]}"
    ]
}
JSON;

echo <<<HTML
<h3>JSON数据示例</h3>
<pre><code>$user_data</code></pre>
HTML;

// 6. PHP 7.3+ 特性 - 不用引号的标识符
echo <<<EXAMPLE
这是PHP 7.3+的新特性演示
不需要引号的heredoc标识符
EXAMPLE;
?>