从PHP函数返回HTML的最佳方法是什么?

5

我之前问了一个类似的问题,但现在更加困惑了,所以我会用不同的方式来问...

我尝试将我的 PHP 抽象化,并将作为错误消息的 HTML 位于验证器中使用的部分,放入返回 HTML 的函数中,以便它们能够在页面上需要的地方使用。

我目前拥有的是:

<section>
<?php 
if($errMsg)
{
    errMsg();
}
?>
</section>

<?php
function errMsg()
{
       ?>
       <section>
           <p>O crap!  There was an error</p>
       </section>
       <?php
}
?>

但是在我之前提到的问题中,我被告知这样做是一种“肮脏的hack”,最好在这种情况下使用return。但是要使用return,我需要将所有返回的html分配给一个变量,而为此我需要将html放入字符串中。我宁愿避免在字符串中放置超过两行的html,因为需要引用的引号数量会让人头疼。

所以我在考虑是否使用heredoc语法或ob_start/ob_get_clean函数。我想知道:

1. 我是否需要费心抽象化我的代码?
2. 如果需要,哪种方式是最佳实践?和/或
3. 我应该放弃网站开发,回到披萨外送吗?:-\

7个回答

5

1: 如果做得当,你可以这样做,但不是必须的。

2: 要实现此功能,建议您在PHP错误函数中使用EOF,它看起来像这样:

function errMsg()
{
       $error = <<<EOF 
<section>
<p>O crap!  There was an error</p>
</section>
EOF;
}

4
  1. 是的,你现在做的方式没有灵活性。
  2. 最好将所有HTML与PHP分开,至少将函数分开——唯一可以接受的地方是在使用PHP来显示函数输出的视图中。
  3. 披萨!开玩笑的,但永远不会有足够的披萨!?

请查看Zend框架 http://framework.zend.com/manual/en/zend.application.quick-start.html ,他们将未被捕获的错误消息转发到一个错误处理程序,然后使用自己的视图呈现错误。

或者无需框架:

try{
     //do work here and throw exception on error
}
catch (Exception $e)
{
     //do error logging/display error
     //or preferably load another class which handles your error and produces output
}

请原谅我的新手,但是当您说将所有HTML与PHP分开时,您是否意味着将不同的语言保存在不同的文件中?就像不显眼的JavaScript一样?因为现在,几乎所有我的.php文件都是在doctype上方编写PHP的网页。 - Matt Whitehead
文件的顶部是可以的,但我不会直接混合HTML和PHP,即使用<<<EOF或关闭php标签来添加HTML在重新设计时会带来麻烦。在编码时,请考虑自己 - 当重新设计网站时,这会让我的生活变得困难吗?根据您的示例,很可能的答案是肯定的;-) - williamvicary
谢谢您的回答。现在,如果将PHP与HTML混合使用闭合标签是一个不好的主意,那么您如何将PHP输出到HTML中呢?例如,如果从服务器返回一个带有错误的表单,您如何在不使用value="<?php $_POST['username'] ?>"这样的东西的情况下保留用户输入字段中的内容? - Matt Whitehead
我建议使用Zend_Form类来处理此问题(或类似的类),或者构建自己的类来处理规范并为您构建输出。这样,您可以对诸如过滤、验证等诸多事项拥有很大的控制权。在PHP代码中将普通变量输出到HTML中并不一定是坏事,但是,如果您开始使用逻辑(例如if语句、for循环等),那么在重新设计时维护起来将会是一场噩梦,并且会导致重复的代码(这总是不好的!) - williamvicary
你的逻辑让我恍然大悟。所以,不要在表单中使用if语句来输出某个变量为真时的内容或从那里调用函数。我可以在一个单独的脚本中创建一个类,基于该类创建一个对象,并从对象调用适当的方法,在if语句所在的位置执行需要执行的操作吗?如果这听起来没有意义,那我很抱歉,但我仍在努力掌握如何在PHP中进行面向对象编程。在我的看法中,Actionscript 3中的OOP要容易得多... - Matt Whitehead
我会真诚地考虑Zend Framework,它在某种程度上迫使您编写更好的代码,它有一种称为“视图助手”的模式,涵盖了视图中的逻辑。但是,基本上,您可以拥有一个对象,该对象与许多不同的视图共享,以抽象化视图逻辑(例如,如果您通常显示“X分钟前”,则将该逻辑放入类中并将输入传递给它,以便将来可以在一个地方自定义它)。如果您希望不使用框架,则应查看MVC模式(搜索“MVC PHP” - 有很多示例!),它应该提供很多见解。 - williamvicary

4
我不会返回任何HTML。只需从函数返回错误消息,然后在更合适的位置构建HTML。例如,在模板内部构建。

2
你可以这样做:
<?php if($errMgs){ ?>
<section>
    <p><?php echo errMsg(); ?></p>
</section>
<?php } ?>

通常情况下,我尽力避免通过 PHP 输出 HTML。为什么?因为如果设计师需要处理我的代码,我不想让他/她担心函数输出了什么HTML。


2
将html代码移动到一个单独的文件error.php中,然后你只需要捕获输出即可:
function errMsg()
{
    ob_start();
    include '/path/to/error.php';
    return ob_get_clean();
}

// ...

echo errMsg();

2

首先,我同意上面的帖子。不要格式化,只需让函数返回裸错误信息,如果需要在显示时适当地进行格式化。

其次,我总是发现能够快速开启和关闭错误和测试消息非常有用。由于我的大部分代码都是面向对象的,我可能只想在一个对象中弹出消息,所以我通常在我的类中添加以下内容:

class userObject
{
    public $history;// = historyObject;
    public $userName;
    public $userRelation;
    public $userCode;
    private $mySQLAccessData;
    private $isDebug=false;

    public function makeHistoryObject($KPI, $KPIType)
    {
        if($this->isDebug){echo "Having a go at creating ".$this->userName.".<br>";}
        $this->history = new historyObject($this->userCode, $KPI, $KPIType);
    }
}

我会在代码中插入一个名为“private”的元素,默认值为false。如果需要进行调试或更改,则将其设置为true,所有错误/日志消息都会整齐地显示在屏幕上。我知道这并没有直接回答你的问题,但是我发现它非常方便,当你开始时可能值得一试。它肯定比注释掉然后取消注释数十条消息要好。您可以在对象中保留这些输出而不用担心,并且让它们显示您需要的所有详细信息。

0
如果你可能在某个时候遇到多个错误,请按照以下步骤进行操作。
<?php
$errors = array();

if (!$item = getItem($id)) {
    addError("No item $id");
}

if (!updateUser($user, $id)) {
    addError("Can not update user");
}

if (!updateItemPicture($id, $picture)) {
    addError("Can not add picture to $id");
}

function addError($error) {
    global $errors; $errors []= $error;
}

function hasErrors() {
   global $errors; return count($errors);
}

function printErrors() {
   if (!hasErrors()) return;

   print "<ul class='errors'><li>" . join("</li><li>", $errors) . "</li></ul";
}


printErrors();
?>

如果您不使用面向对象的方式,可以这样做。并假设所有错误都不是致命的,并在try {} catch () {}块中捕获。


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