【问题标题】:PHP include best practices questionPHP 包括最佳实践问题
【发布时间】:2011-04-08 08:37:48
【问题描述】:

我一直在学习 PHP 的语法并练习它。我来自 .NET 背景,所以当涉及到页眉和页脚时,母版页对我来说总是很容易。

到目前为止,我有一个 mainHeader.php 和 mainFooter.php,其中包含我的头菜单和页脚 html。我创建了一个 mainBody.php 并在顶部放置了

<?php include "mainHeader.php" ?>

对于页脚我放了

<?php include "mainFooter.php" ?>

这很有效,让我微笑,因为我的页面都很好地结合在一起。 mainHeader 有我的&lt;html&gt;&lt;body&gt;,而我的 mainFooter 有我的结束标签。

这是好的做法吗?

【问题讨论】:

  • 那些文件名应该用引号括起来,不是吗?
  • 是的,否则它们将评估为连接字符串定义,发出警告,并包括mainHeaderphpmainFooterphp(无点)。
  • 谢谢。是的,它们在引号中,只是没有在这里输入。

标签: php include


【解决方案1】:

接受的答案是 2010 年表格,过去十年情况发生了变化。

要走的路,现在composer 已经取代了大多数手动连线自动加载器,最佳做法是使用单个require_once,利用来自固定、已知位置的脚本中的__DIR__

require_once __DIR__ . '/vendor/autoload.php';

使用define() 已经不常见了。

根据与环境无关的方法,来自环境的依赖项使用.env 或类似方法注入到应用程序中。

【讨论】:

    【解决方案2】:

    我包含来自我的控制器的视图。我还定义了文件位置以便于维护。

    config.php

    define('DIR_BASE',      dirname( dirname( __FILE__ ) ) . '/');
    define('DIR_SYSTEM',    DIR_BASE . 'system/');
    define('DIR_VIEWS',     DIR_SYSTEM . 'views/');
    define('DIR_CTLS',      DIR_SYSTEM . 'ctls/');
    define('DIR_MDLS',      DIR_SYSTEM . 'mdls/');
    define('VIEW_HEADER',   DIR_VIEWS . 'header.php');
    define('VIEW_NAVIGATION',   DIR_VIEWS . 'navigation.php');
    define('VIEW_FOOTER',   DIR_VIEWS . 'footer.php');
    

    现在我只需添加 config.php 就可以获得我需要的所有信息。

    controller.php

    require( '../config.php' );
    include( DIR_MDLS . 'model.php' );
    
    $model = new model();
    if ( $model->getStuff() ) {
        $page_to_load = DIR_VIEWS . 'page.php';
    }
    else {
        $page_to_load = DIR_VIEWS . 'otherpage.php';
    }
    
    include( VIEW_HEADER );
    include( VIEW_NAVIGATION );
    include( DIR_VIEWS . $page_to_load );
    include( VIEW_FOOTER );
    

    【讨论】:

    • 谢谢!这是非常有用的信息,我已经实现了类似的东西。
    • 快速提问:您使用的是框架吗?我正在尝试 codeigniter,我想知道是否需要我在 config.php 中定义这些目录信息?
    • 不,那是使用我自己的“框架”。您不必使用代码点火器这样做
    • 我喜欢这个概念……但是,有时我挠了挠头,想弄清楚行尾的语法错误: $page_to_load = DIR_VIEWS 。 'page.php'
    • 必须在末尾添加一个分号 ^,以防万一你是认真的。另外,我知道这是一篇旧帖子,但这仍然非常有帮助。
    【解决方案3】:

    我知道这已经很晚了,只是想在这个问题上加上我的“便士价值”。

    我的建议是为此创建方法,例如,我的根目录是:var/www/htdocs/,函数文件位于 includes/functions/template-parts.php。
    我的函数看起来像这样:

    <?php
    
    define("DOC_ROOT", "/var/www/htdocs/"); # Add a trailing slash to make it a little easier
    
    function GetHeader()
    {
        return include DOC_ROOT . 'includes/parts/header.htm'; # Header found at include/parts/header.htm
    }
    
    function GetFooter()
    {
        return include DOC_ROOT . 'includes/parts/footer.htm'; # Footer found at include/parts/footer.htm
    }
    
    ?>
    

    并这样使用:

    <?php
    
    # From the main page (/var/www/htdocs/index.php)
    require_once 'includes/functions/template-parts.php';
    GetHeader();
    ?>
    <!-- Page content -->
    <?php
    
    GetFooter();
    
    ?>
    

    【讨论】:

      【解决方案4】:

      对于小型网站,include/include_once 和 require/require_once 非常棒,我已经多年没有建立没有它们的网站了。但是,我建议确保您的每个包含文件都是有效 XML 的离散代码块。我的意思是不要在一个包含中打开标签并在另一个包含中关闭它,反之亦然 - 它会使更改变得复杂并且更容易破坏事情,因为您在文件之间存在依赖关系。编码愉快!

      【讨论】:

        【解决方案5】:

        总结以上所有内容。
        这是使用包含的好方法,但不要忘记为页面内容使用模板页面。

        部分基于 Galen 和 Balus':

        page.php

        require $_SERVER['DOCUMENT_ROOT'].'/../config.php';
        $data = get_data(); // assume we get all required data here.
        $pagetitle = "This is a sample page";
        $template = "page.tpl.php";
        include "main.tpl.php";
        

        main.tpl.php

        <!DOCTYPE html> 
        <html lang="en"> 
            <head> 
                 <title><?php echo $pagetitle?></title>
            </head> 
            <body> 
                <?php include $template ?> 
            </body> 
        </html> 
        

        page.tpl.php 类似这样的:

        <h1><?php echo $pagetitle?></h1>
        <?php if (!$data): ?>
        No news yet :-(
        <?php else: ?>
        <ul>
        <? foreach ($data as $row): ?>
        <li><a href="news.php?id=<?php echo $row['name']?>"><?php echo $row['name']?></a></li>
        <?php endforeach ?>
        </ul>
        <?php endif ?>
        

        【讨论】:

          【解决方案6】:

          我喜欢使用函数来打印页眉和页脚而不是包含。您可以通过这种方式更好地微调变量范围。

          【讨论】:

          • 这就是你的答案?
          【解决方案7】:

          这是一个非常好的方法,只要您的网站不超过 20 页的阈值。但是,我建议在函数样式中使用 include(),而不是作为构造,并将这些模板放在单独的子文件夹中。如果其中没有 PHP 代码,也请使用 .htm 文件扩展名(htm 指定部分 html)。

           include("template/main/header.htm");   // would still parse PHP code!
          

          这种方法的缺点是,有时您最终会通过全局变量将 HTML 注入其中。 $HEAD='&lt;link...&gt;'; include("../header.htm")。这本身还不错,但可以很快积累。

          【讨论】:

            【解决方案8】:

            在您开始使用“视图”或“模板”之前,您所做的一切正常,在这种情况下,您不再将内容 HTML 安排在运行的“控制器”或“动作”中。

            相反,您将加载一个视图并使用值填充它,从而将所有 HTML 源代码排序留给视图而不是您的 PHP 文件。

            $view = new View('layout.php');
            $view->header = $header;
            $view->content = 'This is the main content!';
            $view->footer = $footer;
            print $view;
            

            然后加载看起来像这样的布局文件:

            <!DOCTYPE html>
            <html lang="en">
                <head>
                    ...
                </head>
                <body>
                    <div id="header"><?php print $header; ?></div>
                    <div id="content"><?php print $content; ?></div>
                    <div id="footer"><?php print $footer; ?></div>
                </body>
            </html>
            

            【讨论】:

            • 这很棒。只是碰巧想知道如何组织视图及其对应的 HTML。
            • 我怎么没想到!这很棒。
            【解决方案9】:

            你也可以反过来做。有一个带有页眉/页脚的主页,并且只包含正文。

            <!DOCTYPE html>
            <html lang="en">
                <head>
                    ...
                </head>
                <body>
                    <?php include $page ?>
                </body>
            </html>
            

            【讨论】:

            • 啊,我知道这对生成动态数据有什么用处。非常感谢!
            【解决方案10】:

            现在的好习惯是使用模板引擎,例如smarty。对于整个应用程序,请考虑使用framework,例如codeigniter

            【讨论】:

            • 对 smarty 不能再不同意了
            • 是的,我知道。我自己的日子不好过 :) 这只是我想到的模板引擎的第一个例子。在建议使用框架之后,我认为模板引擎示例没有那么重要,所以我没有考虑太多。无论如何感谢您的反馈:)
            • 我不太喜欢 smarty,但是使用模板引擎的想法很棒。除了 PHP ......因为 PHP 已经是一个模板引擎,这有点奇怪。不过,MVC 类型模式要好得多……嗯……让我们都使用框架!但是 h20 模板对于 PHP 来说非常酷。
            • 无论您喜欢或不喜欢特定的模板引擎,使用一个来处理变量替换、循环、条件和子模板/包含/宏作为标记(与 php 代码相比)是一个巨大的进步 IMO .我使用 PHPTAL,我相信很多人也讨厌它,但是模板是您的 php 相当于母版页。
            • Smarty、PHPTemplate 或任何其他模板引擎旨在在多人处理一个项目时强制分离关注点。它允许 PHP 开发人员隐藏业务逻辑,只向前端开发人员公开某些位。如果您是该项目的唯一工作人员,Smarty 是不必要的复杂层。
            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2014-04-25
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2013-07-22
            相关资源
            最近更新 更多