在PHP中有更好的方法来编写HTML字符串吗?

23

我发现自己在PHP中编写了很多返回HTML代码的函数。它们可能看起来像这样:

function html_site_head()
{
    return
        "
            <div id=\"site_header\">
                <div id=\"site_header_inner\">
                    <div id=\"site_header_logo\"></div>

                    <div id=\"site_header_countdown\">BARE XX DAGER IGJEN</div>
                </div>
            </div>
        ";
}

我可以发誓我曾经看过更好的 PHP 长字符串写法。我喜欢 Python 的做法:

return """
    <div id="site_header">
        <div id="site_header_inner">
            <div id="site_header_logo"></div>

            <div id="site_header_countdown">BARE XX DAGER IGJEN</div>
        </div>
    </div>
"""

由于您不必转义引号。另一种选择是使用单引号,但这意味着不能直接在字符串中使用PHP变量。我发誓我曾经在PHP中看到过这样的东西:

return <<<
    <div id="site_header">
        <div id="site_header_inner">
            <div id="site_header_logo"></div>

            <div id="site_header_countdown">BARE XX DAGER IGJEN</div>
        </div>
    </div>

或类似的东西。有人可以帮我恢复一下记忆吗?

谢谢


5
如果你的 PHP 脚本输出像这样的“长 HTML 字符串”,我认为你做错了什么。你应该将逻辑(PHP 代码)和 HTML 分离。在这种情况下,把 HTML 放在一个单独的文件中,需要时再进行包含。 - RoToRa
php.net/heredoc会指引你正确的方向。简而言之,使用<<<likethis开始,然后换行,输入HTML代码,再换行,最后使用likethis结束heredoc。 - DampeS8N
1
放弃手写HTML代码并使用DOMDocument是一种选择。 - Hello World
8个回答

21

18

如果您需要一种可以用来将HTML存储到字符串中的方法,这就是实现的方式。

我不会使用其他提出的方法,哈哈,我会使用输出缓冲区。这些其他方法似乎都很混乱(因为在规模上会有很多特殊字符飞来飞去)...所以冒犯某些人的风险我只想说我喜欢我的方法的原因。

如果您像我一样使用输出缓冲区...

当使用IDE时,您仍然可以获得与HTML和PHP分开的极好的智能提示,并且仍然可以快速编写通用DOM对象。

查看代码时,它看起来更加人性化易读。

可以传递HTML代码的DOM准备好状态,而不是作为字符串,最终需要解析并创建成DOM准备好状态。

当使用HTML作为字符串方法时,尝试在运行时使用各种字符串函数搜索和替换方法可能会变得非常困难。例如,在包含大量其他HTML元素的字符串中查找<img>标记可能会很困难,尤其是在尝试查找标记之间的内容时。

我会这样使用输出缓冲流...

ob_start();
?>
    <div id="site_header">
        <div id="site_header_inner">
            <div id="site_header_logo"><?php echo $PhpVar; ?></div>
            <div id="site_header_countdown">BARE XX DAGER IGJEN</div>
        </div>
    </div>
<?php
$output = ob_get_clean();
ob_flush();

return $output; OR return echo $output

这比使用字符串或HEREDOC更易读的HTML。这种方法有什么缺点吗? - ow3n
这是我构建HTML的首选方法。易读且相当容易理解。 - John Bell
@JohnBell,是的,我发现使用清晰、干净的代码更容易将新人引入我的代码库,大多数智能感知应用程序都可以识别。更不用说移除100个<?php ?>标签的混乱了。此外,这也使得我的Sublime Text的Emmet插件仍然可以正常工作 ;) - GoreDefex
ob_flush()是不必要的,因为ob_get_clean()停止了缓冲,实际上当启用zlib.output_compression时,它会破坏整体输出。 - vanowm
使用VS Code,如果您将分界符命名为语言名称(例如<<<HTML),HEREDOC字符串将正确突出显示其中的代码。 - mbomb007

2

You can use a HEREDOC:

<?php

function blah() {
  $bar = <<<EOS
  <div id="site_header">
        <div id="site_header_inner">
            <div id="site_header_logo"></div>

            <div id="site_header_countdown">BARE XX DAGER IGJEN</div>
        </div>
  </div>
EOS;

return $bar;
}

?>

1
实际上那样做行不通,因为结束定界符前后不能有空格。 - Hubro
糟糕!我把问题归咎于代码块空格。 :P 我已经编辑过来修复了。 - bhamby
1
EOS 后面需要加上分号 ;。 - Robin Manoli
在HTML中使用变量怎么样? - vanowm

2
更好的方式——不要写意大利面条式的代码,使用模板或者...
// php code
?>
<div id="site_header">
    <div id="site_header_inner">
        <div id="site_header_logo"><?=$echoPhpVar?></div>
        <div id="site_header_countdown">BARE XX DAGER IGJEN</div>
    </div>
</div>
<?php
//php code

2
如果需要从一个函数返回HTML,这可能会很困难。 - Felix Kling
4
@Felix:函数不应该返回HTML。 - RoToRa
@RoToRa:这取决于你是否编写模板生成器或其他工具。通常情况下不需要,我同意,但也有一些使用情况。 - Felix Kling
+1 for "函数不应该返回HTML。" 将你的表现层与业务层分离。有一些框架可以使这个过程更容易。看看Zend MVC。 - RepDetec

1
有时由于某些原因,PHP、Javascript或其他程序会插入大量反斜杠。普通函数无法察觉到这一点。因此,需要使用“inflate”函数来处理:
<?php
function removeslashes($string)
{
    $string=implode("",explode("\\",$string));
    return stripslashes(trim($string));
}

/* Example */

$text="My dog don\\\\\\\\\\\\\\\\'t like the postman!";
echo removeslashes($text);
?>

RESULT: My dog don't like the postman!

这个小工具对我非常有帮助,因为我以前遇到过这个问题。
来源:这里

1

0
正如Haim所说 - heredoc是正确的方法。
如果你发现自己在写单行代码,请记住(或意识到)你可以使用单引号来表示HTML属性(不要相信任何人告诉你它们无效)。
例如:
$html = "<div id='blah'>$contents</div>";

0

我想建议这个 PHP 库,它可以使用 php 生成几乎任何 HTML 标签,并使用闭包嵌套来帮助可读性。

https://github.com/raftalks/Form

例如 - 一个在 div 标签内的表格。
Html::make('div', function($html))
{
    $html->table(function($table)
    {
        $table->thead(function($table)
        {
            $table->tr(function($tr)
            {
                $tr->th('item');
                $tr->th('category');
            });
        });


        $table->tr(function($tr)
        {   
            $tr->td()->ng_bind('item.name','ng-bind');
            $tr->td()->ng_bind('item.category','ng-bind');

            $tr->setNgRepeat('item in list','ng-repeat'); //using second parameter to force the attribute name.
        });

        $table->setClass('table');
    });

   $html->setClass('tableContainer');
});

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接