简体   繁体   中英

PHP include best practices question

I have been learning syntax for PHP and practicing it. I come from a .NET background so masterpages always made things pretty easy for me when it came to headers and footers.

So far I have a mainHeader.php and mainFooter.php which have my head menu and my footer html. I created a mainBody.php and at the top I put

<?php include "mainHeader.php" ?>

and for the footer I put

<?php include "mainFooter.php" ?>

This worked perfectly and made me smile because my pages all came together nicely. the mainHeader has my <html> and <body> and my mainFooter has my closing tags for those.

Is this good practice?

I include my views from my controllers. I also define file locations to make maintenance easier.

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');

Now i have all the info i need just by including 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 );

You can also do it the other way round. Have a main page with header/footer and include only the body.

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

What you're doing is ok until you start using "Views" or "Templates" in which case you no longer arrange your content HTML inside the "controller" or "action" running.

Instead you will load a view and populate it with values which leaves all the HTML source ordering to the view and not your PHP file.

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

which then loads the layout file which looks something like this:

<!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>

To summarize all the above.
That's good way to use includes, but do not forget to use a template page for the page contents.

Partly based on Galen's and 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 something like this:

<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 ?>

The good practice nowadays is to use a templating engine, such as smarty . For the whole application consider using a framework , like codeigniter .

For small sites, include/include_once and require/require_once are great, I haven't built a site without them in years. I would, however, recommend making sure each of your include files is a discrete code block that is valid XML. What I mean is don't open a tag in one include and close it in another, or vice versa - it will make changes complex and more prone to break things because you have dependencies between files. Happy coding!

The accepted answer is form 2010 and things have changed in the past ten years.

The way to go, now with composer having replaced most hand wired autoloaders, the best practice is to use a single require_once utilizing __DIR__ from a script in a fixed, known place:

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

Using define() is not common anymore.

According to the environment agnostic approach, dependencies from the environment get injected to the application using .env or similiar.

I know this is very late, just wanted to add my "pennies worth" to this question.

My suggestion would be to create methods for this, eg my root is: var/www/htdocs/ and the functions file is in includes/functions/template-parts.php.
My functions would look as such:

<?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
}

?>

And used as such:

<?php

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

GetFooter();

?>

This is a perfectly fine method, as long as your site doesn't outgrow the 20 pages threshold. I'd however advise to use include() in function style, not as construct, and place these templates in a separate subfolder. If there is no PHP code in them, also use a .htm file extension (htm designating partial html).

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

The disadvantage with this approach is, that you somewhen end up injecting HTML through global variables into it. $HEAD='<link...>'; include("../header.htm") $HEAD='<link...>'; include("../header.htm") . Which is not bad per se, but can quickly amass cruft.

I like using functions to print headers and footers instead of includes. You can fine tune the variable scope better that way.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM