PHP模板函数的参数

时间:2011-09-20 17:50:50

标签: php coding-style

这更像是一个风格问题。我有一个模板文件header.php,我在其中定义了PrintHeader()函数。

此函数的调用者可以通过全局变量指定页面的标题以及打印标题时要包含的任何Javascript脚本(因为肯定不是每个页面都具有相同的标题或想要包含相同的脚本)。我选择使用全局变量而不是函数参数,因为后者在添加新参数时需要更改接口。

这被认为是“好”的风格,是否有“更好”的方式来做我想做的事情?

header.php(简化)

<?php
function PrintHeader()
{
  global $pageTitle, $scripts; // Set by the caller of this function

  echo <<<HEADER
<html>
 <head>
  <title>$pageTitle</title>

HEADER;

  if( !empty($scripts) )
  {
    foreach($scripts as $script)
    {
      echo "  <script type=\"text/javascript\" src=\"$script.js\"></script>\n";
    }
  }

  echo " </head>\n";
}
?>

index.php(简体)

<?php
  $pageTitle = 'Welcome';
  $scripts = array('script1', 'script2');
  require('header.php');
  PrintHeader();

  // Print the rest of the page
?>

5 个答案:

答案 0 :(得分:2)

使用全局变量肯定是不可取的,我质疑使用heredoc的必要性 - 并不是说​​heredoc本质上存在任何错误,只是你似乎在这个样本模板中相当随意地使用了它。

使用函数的返回值作为每个模板的输出并不优雅 - 这会破坏模板的重用性之一。

看看smarty,如果不是直接使用它(毕竟,为什么要重新发明轮子),至少要了解渲染类是如何用来穿梭变量的模板需要而不需要使用凌乱的全局变量。

答案 1 :(得分:2)

以下是对模板化方法的快速概述:

您有一个模板类,您可以将数据分配给然后呈现模板。

的template.php:

class Template
{
    protected $data = array();
    public function assign($key, $value)
    {
        $this->data[$key] = $value;
    }

    public function render($file)
    {
        extract($this->data);
        require $file;
    }
}

然后你有你的模板header.php:

<html>
 <head>
   <title><?php echo $pageTitle; ?></title>
....

在index.php中,您可以使用模板类来分配数据并渲染模板。

$tpl = new Template;
$tpl->assign('pageTitle', 'My page title!');
$tpl->render('header.php');

这只是一个展示这个想法的简单例子,可以给你一个很好的起点。

答案 2 :(得分:2)

  

有没有“更好”的方式去做我想做的事情?

确定。
我认为在定义和调用函数方面没有任何意义。以及使用heredoc。

header.php(大大简化):

<html>
 <head>
  <title><?=$pageTitle?></title>

<? if( !empty($scripts) ): ?>
  <?  foreach($scripts as $script): ?>
<script type="text/javascript" src="<?=$script?>.js"></script>
  <? endforeach ?>
<? endif ?>
  </head>

的index.php:

<?php
  $pageTitle = 'Welcome';
  $scripts = array('script1', 'script2');
  require('header.php');
?>

但它仍然不是最好的方式,因为它似乎没有使用最有价值的模板 - 输出页面内容本身。

所以,我分三部分来做:

links.php(简体):

<?
//include our settings, connect to database etc.
include dirname($_SERVER['DOCUMENT_ROOT']).'/cfg/settings.php';
//getting required data
$DATA = getdata("SELECT * FROM links");
$pagetitle = "Links to friend sites";
//etc
//and then call a template:
$tpl = "links.tpl.php";
include "main.tpl.php";
?>

其中main.tpl.php是您的主要网站模板,包括常见部分,如页眉,页脚,菜单等:

<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>My site. <?=$pagetitle?></title>
</head>
<body>
<div id="page">
<? include $tpl ?>
</div>
</body>
</html>

最后links.tpl.php是实际的页面模板:

<h2><?=$pagetitle?></h2>
<ul>
<? foreach($DATA as $row): ?>
<li><a href="<?=$row['link']?>" target="_blank"><?=$row['name']?></a></li>
<? endforeach ?>
<ul>

注意本机HTML语法,它突出显示,可读并集中在一个地方,而不是在众多功能和文件之间分开

重点是每个PHP页面都有单独的模板以及所有PHP页面的主站点模板。通过这样的设置,您将获得许多优势,例如自定义错误页面,相同数据的多个表示(例如,HTML,JSON或XML),只需切换模板而无需更改代码等等

答案 3 :(得分:0)

虽然“更好”可能在旁观者眼中,但我建议使用某种功能来设置页面位而不是暴露原始变量。例如,您可以拥有$pageTitle = 'Welcome';而不是set_page_title('Welcome');

对于JavaScript,您可以拥有一个添加到当前脚本集的函数 - 而不是可能全部替换它 - 例如add_javascript($code);。这将允许开发人员设置所有这些,而无需跟踪变量名称是什么,并且如果他们想要在函数内设置它,也不需要全局化它。

答案 4 :(得分:-1)

全局变量通常被认为是坏的,如果可能应该避免。

而不是列出界面中的每个变量,正如您所说的可能会发生变化,而是将单个数组传递给PrintHeader()函数:

<?php
function PrintHeader($opts=array()) {
    if(!isset($opts['title'])) $opts['title'] = 'Default Title';
    echo <<<HEADER
    <html>
     <head>
      <title>$opts['title']</title>
    HEADER;

    if(!empty($opts['scripts'])) {
        foreach($opts['scripts'] as $script) {
            echo "  <script type=\"text/javascript\" src=\"$script.js\"></script>\n";
        }
    }
    echo " </head>\n";
}

$opts = array('title'=>'Welcome',
              'scripts'=>array('script1', 'script2'));
require('header.php');
PrintHeader($opts);
?>

这样,您可以在函数中添加新功能,而不会破坏旧代码。