51

I'm trying to make the whole <head> section its own include file. One drawback is the title and description and keyword will be the same; I can't figure out how to pass arguments to the include file.

So here is the code:

index.php

<?php include("header.php?header=aaaaaaaaaaaaaaaaaaaaa"); ?>

<body>
.....
..
.

header.php

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<link rel="shortcut icon" href="favicon.ico">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
<meta name="Keywords" content=" <?php $_GET["header"]?> " >
<meta name="Description" content=" <?php $_GET["header"]?> " >
<title> <?php $_GET["header"]?> </title>
<link rel="stylesheet" type="text/css" href="reset.css" />
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.4.3/jquery.min.js"></script>
</head>

Obviously this doesn't work; how can I pass arguments to an included file?

Michael Mrozek
  • 169,610
  • 28
  • 168
  • 175
menardmam
  • 9,860
  • 28
  • 85
  • 113
  • possible duplicate of [PHP - include a php file and also send query parameters](http://stackoverflow.com/questions/1232097/php-include-a-php-file-and-also-send-query-parameters) – Gary Jul 27 '15 at 04:47

9 Answers9

122

Include has the scope of the line it's called from.

If you don't want to create new global variables, you can wrap include() with a function:

function includeHeader($title) {
    include("inc/header.php");
}

$title will be defined in the included code whenever you call includeHeader with a value, for example includeHeader('My Fancy Title').

If you want to pass more than one variable you can always pass an array instead of a string.

Let's create a generic function:

function includeFile($file, $variables) {
    include($file);
}

Voila!

Using extract makes it even neater:

function includeFileWithVariables($fileName, $variables) {
   extract($variables);
   include($fileName);
}

Now you can do:

includeFileWithVariables("header.php", array(
    'keywords'=> "Potato, Tomato, Toothpaste",
    'title'=> "Hello World"
));

Knowing that it will cause variables $keywords and $title to be defined in the scope of the included code.

Rolf
  • 5,550
  • 5
  • 41
  • 61
  • What happend to the comments? This answer is the most upvoted one for this question, and it had a handful of comments (mostly praise!), they're all gone now! – Rolf Nov 11 '16 at 16:58
  • 2
    A moderater with sufficient rights must have been deleting those. Maybe you can check within the history. – Blackbam Nov 22 '17 at 14:49
  • 1
    Just to make this explicit, too: even though those vars would appear to be global (i.e. visible without declaration in the script's "global" scope) in the child script, they aren't. They'll also *shadow globals with the same name* in the child script, the usual PHP way, i.e. the masked globals would be accessible after declaring them explicitly (as `global`), or via `$GLOBALS`. – Sz. Sep 28 '18 at 10:42
  • 1
    this answer is great – anvd Aug 21 '19 at 15:47
58

index.php:

<?php
$my_header = 'aaaaaaaaaaaaaaaaaaaa';
include 'header.php';
?>

and header.php

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<link rel="shortcut icon" href="favicon.ico" />
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
<meta name="Keywords" content=" <?php echo $my_header ?> " />
<meta name="Description" content=" <?php echo $my_header ?> " />
<title> <?php echo $my_header ?> </title>
<link rel="stylesheet" type="text/css" href="reset.css" />
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.4.3/jquery.min.js"></script>
</head>

It's not an ideal solution, but I understand it's your first steps in php.

PS. Your Doctype doesn't match the code. I've adjusted your header html to be XHTML.

Michal M
  • 9,322
  • 8
  • 47
  • 63
  • 1
    This explains your basic problem. But you should keep looking for better ways how to put html and php together. – Josef Sábl Nov 30 '10 at 15:41
  • @JosefSábl For example? – HEX Jan 22 '14 at 17:07
  • 5
    MVC frameworks. The problem with above example is that included file doesn't know where the variable $my_header comes from, which makes all sorts of headaches. It's okay to have one variable like that or very simple webpage, but maintenance of full scaled application which relies on such techniques will quickly become nightmare. Believe me, I have to maintain one :-) – Josef Sábl Jan 24 '14 at 09:59
16

You can't pass arguments to include, but it has access to all variables you've already set. From the include documentation:

When a file is included, the code it contains inherits the variable scope of the line on which the include occurs. Any variables available at that line in the calling file will be available within the called file, from that point forward.

Thus:

index.php

<?php
$header = 'aaaaaaaaaaaaaaaaaaaaa';
include("header.php");
?>

header.php

<title> <?php echo $header; ?> </title>
Michael Mrozek
  • 169,610
  • 28
  • 168
  • 175
3

Well marc, when you are using include, you can simply just set up a variable to use:

<?php
  $var = "Testing";
  include("header.php");
?>

In your header file:

<?php
  echo $var;
?>

Allow your previously defined variables are usable in any include you have.

Richard Key
  • 103
  • 5
2

you are over thinking it

<?php 
$header = "aaaaaaaaaaaaaaaaa";
include("header.php"); 
?>

::EDIT::

Decided I would add value

The included file will gain the scope of where you included it. So if you include a file INSIDE a function:

<?php
$get_me = "yes";
function haha()
{
include("file.php");
}
haha();

// And file.php looks like

echo $get_me; // notice + blank

?>

More over, you include the same file more than once to great effect.

<?php

$output = "this";
include("cool_box.php");

$output = "will";
include("cool_box.php");

$output = "work";
include("cool_box.php");

?>

And even use this to load templates that become part of a method in a class. So you can do something like:

<?php

class template
{

    private $name;

    function __construct($name)
    {
        $this->name = preg_replace("/[^a-zA-Z0-9]/", "", $name);
    }

    function output(array $vars)
    {
        include($this->name.".php"); // Where $vars is an expected array of possible data
    }

}

$head = new template("header");
$body = new template("body");
$head->output();
$head->output(array("content" => "this is a cool page"));

?>
DampeS8N
  • 3,621
  • 17
  • 20
  • 2
    Take that another step, and output buffer the included file, then return the string, and you can build a full template engine. Take that one more step and you have 90% of the frameworks out there. – DampeS8N Nov 30 '10 at 15:38
  • i look to get better and that method thing look really nice... at least when the function is done, code is poetry ! – menardmam Nov 30 '10 at 16:47
  • PHP is great for writing poetic code. It is also great for writing poetry that no one else can understand. Double-edged sword. – DampeS8N Nov 30 '10 at 17:52
  • @DampeS8N - re: `double-edged sword` - That's what in-line documentation is for. ;-D. – Jesse Chisholm May 07 '15 at 17:17
2

defining a variable as a pseudo-argument/workaround before an include() - as recommended by many - is a bad idea. it introduces a variable in the global scope. define a function in the included file instead to catch the arguments u want to pass.

bcosca
  • 17,371
  • 5
  • 40
  • 51
  • Yea, but I think you are too ahead for him, right now. I think his approach deserves some exploration before discovering more proper ways how to assemble a webpage together. – Josef Sábl Nov 30 '10 at 15:38
  • 2
    Uhm wait, how do you do that? – Rolf Mar 31 '11 at 16:49
2

This is good approach. I however would do it a bit inside out. Define a layout, a wrapper for your webpage and include your content file into it:

layout.phtml

<html>
    <head>
      ... your headers go here
    </head>
    <body>
      <? include $content ?>
    </body>
</html>

Your content template file can look like this e.g.

content.phtml

<h1>hello world</h1>

<p>My name is <?= $name ?></p>

Then, you would have your main script (index) that will handle logic, connects to database etc.

index.php

$content = 'content.phtml';
$name = 'Marc'; //Can be pulled from database

include 'layout.phtml';

This way, you can nicely separate business logic and presentation. And it can help you cut repetitive code for parts of page like logo or navigation which are repeated on the whole site.

Josef Sábl
  • 7,538
  • 9
  • 54
  • 66
  • that approch look nice, but imply too many modification to my code... will continue whit the other suggestions... – menardmam Nov 30 '10 at 16:45
  • 1
    @marc: ok, but next time you start planning a new project, take advices some people shared in this thread into consideration and design you application framework a bit better. – Josef Sábl Dec 01 '10 at 11:20
0

I noticed nobody suggested using a template engine. I came looking here because for the project I'm working with, a template engine isn't possible and that might be your situation too, however I thought it might be worth mentioning these: Twig (my preferred engine) and Smarty both allow passing specific variables to includes.

I highly recommend the use of a template engine whenever possible, as it simplifies your front end code, adds a layer of abstraction between your front end and back end, and both Twig and Smarty automatically clean the variables you pass to them which helps mitigate XSS attacks.

Twig Example

header.html

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<link rel="shortcut icon" href="favicon.ico">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
<meta name="Keywords" content="{{ header }}" >
<meta name="Description" content="{{ header }}" >
<title> {{ header }} </title>
<link rel="stylesheet" type="text/css" href="reset.css" />
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.4.3/jquery.min.js"></script>
</head>

index.html

{% include 'header.html' with { 'header' : '<script>alert("this shouldnt work")</script>'} only %}
Body Text
{% include 'footer.html' %}

Smarty Example

header.tpl

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<link rel="shortcut icon" href="favicon.ico">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
<meta name="Keywords" content="{$header}" >
<meta name="Description" content="{$header}" >
<title> {$header} </title>
<link rel="stylesheet" type="text/css" href="reset.css" />
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.4.3/jquery.min.js"></script>
</head>

index.tpl

{include 'header.tpl' header='<script>alert("this shouldnt work")</script>'}
Body Text
{include 'footer.tpl'}
DanielM
  • 6,380
  • 2
  • 38
  • 57
0

If you include a file it is just like inserting that code into the parent file. You could simply do this:

<?php
$parameter = "Hello World";
include("header.php");
?>

and then in the header.php

<?php
$parameter = isset($parameter) ? $parameter : "Default Text";
// Use accordingly
?>

I used the isset() method to verify that it has a value already and is instantiated.

Aaron Hathaway
  • 4,280
  • 2
  • 19
  • 17