Dynamically links to header and footer across all PHP pages in different directories and subdirectories

UPDATE 1: To have a clear idea of ​​what is going on, you can download the script snippet from here.

I'm working on a new website, which has the same header

, footer

on every page of PHP.

In the title, I refer to other common files on the website, such as .css

, .js

, functions

, classes

, db connection

, etc.

for example default.css

located in/common/stylesheets/

and my header.php and footer.php are in the folder /common/html/

so my header.php file is like this

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>The Header</title>
  <link rel="stylesheet" href="common/stylesheets/default.css">
</head>
<body>

      

On my website index.php

I have included the header <?php include('common/html/header.php'); ?>

and it works fine ... BUT problems appear when I include the header on other php pages in other directories or subdirectories for example. /pages/admin/dashboard.php

, everything is messed up and this page is no longer associated with the file default.css

.

So, I'm looking for a method or logic where I refer to these shared files and folders in every PHP page regardless of its location; e.g. site root, directory at site root or subdirectory ... etc.

here is an image of my root site

sample website root

Your help is greatly appreciated ...

PS I tried to use some superglobals like $_SERVER['']

in a config.inc.php

file to define paths, then included that file in header.php

. BUT I couldn't figure out which one would dynamically keep referring to these shared folders and files without mater where the PHP page is located.


UPDATE 1: To have a clear idea of ​​what is going on, you can download the script snippet from here.

+3


source to share


9 replies


This is a common problem with structures that do not use index.php for centralization. Perhaps you can try adding another include, which defines your directories as pseudo-persistent and adds them to your resource urls.

Or, you can parse the request url how deep it is and automatically add the required ../ levels to your resource urls. I did this for one of my past projects.



I have to warn you, but it's better to tackle the root of the problem (lack of centralization) than to add workarounds. He will undoubtedly return to haunt you sooner than you think.

+2


source


It is generally recommended to use fully qualified or absolute URLs to link to your assets:

<link rel="stylesheet" href="http://www.sitenamecom/some/path/to/common/stylesheets/default.css">

      

Since there are many places where you need the correct URL base to access various files, you can define a constant that has the root of the website:

define('WEB_ROOT', 'http://www.sitename.com');

      

Then you can define other constants to access different parts of the system:

define('WEB_ASSETS', WEB_ROOT . '/common');

      

So, to reference the stylesheet in yours, header.php

this would be:

<link rel="stylesheet" href="<?php echo WEB_ASSETS; ?>/stylesheets/default.css">

      



In include

files, the principle is the same as in this case, you don't work with URLs, but with file paths. There's no really dynamic way of solving this, it all comes down to absolute paths.

The problem here is that the tree structure in your local development environment may (and certainly won't) match your server's tree structure. Therefore, in the config file that is at the root of your application, you can define:

define('APP_ROOT', dirname(__FILE__));

      

Then you can use the file admin/index.php

as an example:

include '../../../config.inc.php'; 
include APP_ROOT . '/sitename/common/html/header.php';

      

The hard part here involves configuration. Since it will APP_ROOT

not be available until you do this, it will require relative paths to reach it, and it cannot be avoided; if you cannot completely trust the preferred absolute form:

include '/some/path/to/config.inc.php'; 

      

The presence of this forward slash, as I said, will be a problem if the application is tested in different environments, because it rarely happens that it is some/path/to

always the same.

+2


source


$ _ SERVER ['DOCUMENT_ROOT'] you are probably looking for.

<?php
require_once($_SERVER['DOCUMENT_ROOT'] . "/sitename/common/html/header.php");

      

This should work from any directory. If you want it to be a little more dynamic than typing "sitename", you can do this:

<?php
$sitename = explode("/", $_SERVER['REQUEST_URI']);
require_once($_SERVER['DOCUMENT_ROOT'] . "/" . $sitename[1] . "/common/html/header.php");

      

+2


source


You need to change <link rel="stylesheet" href="common/stylesheets/default.css">

to<link rel="stylesheet" href="../../common/stylesheets/default.css">

+1


source



here is a simple modification in php.ini to include footer.php and header.php for each script

auto_append_file=ABSOLUTE_PATH/footer.php
auto_prepend_file=ABSOLUTE_PATH/header.php

      

restart your Apache if you are running easyPhp, xampp, ....
Attention: this configuration will be applied in all projects that run with modified PHP

+1


source


Try <link rel="stylesheet" href="/common/stylesheets/default.css">

Notice the leading slash ... This directs the server to the document root.

I tried it and it works.

My tree:

/var/www/html/
    subdir/
        body.php
    layout/
        header.php
        footer.php
    css/
        style.css

      

header.php

<html>
  <head>
    <link rel="stylesheet" href="/css/style.css">
  </head>
  <body>
    <p>Header.</p>
    <hr>

      

body.php

<?php
include($_SERVER['DOCUMENT_ROOT'].'/layout/header.php');
echo "Body.<br>";
include($_SERVER['DOCUMENT_ROOT'].'/layout/footer.php');
?>

      

footer.php

  </body>
</html>

      

style.css

body {
  color: red;
}

      

Viewing http://localhost/subdir/body.php

in a browser, I get the expected result: "Title" and "Body" are colored red.

0


source


I would keep the document root of your site in some definitions:

define('DOCROOT', $_SERVER['DOCUMENT_ROOT']);

      

Do this in a PHP file that you include everywhere, preferably some PHP bootstrap file.

Then you need to add your paths to this in your included lines:

<?php include(DOCROOT . "/common/html/header.php"); ?>

      

Have you also viewed include_once

?

0


source


Have you tried PHP set_include_path?

You can add multiple paths to one set_include_path by separating them with :. set_include_path ('/ home / MySite / includes1: / home / MySite / includes2'). PHP.net -> set_include_path

0


source


Even if you don't go for a full front controller (and MVC) setup (which would be nice), you can save yourself a lot of headaches if you provide a simple bootstrap file.

This will not be ideal with your current setup, as your files include different parts of your system (like header.php) in different locations and subfolders.

When the header is loaded the first things are output - i.e. doctype, head and head links, etc. - in your base structure are fine, but now you're running into limitations you can't work with without messing up yours header.php

or including numerous other files before header.php

.

In a more solid wireframe design, the html and doctype outputs after many other things are initiated and loaded will allow the specified html and doctype to be controlled.

But to help in your case, just load the loading tray before anything else is loaded / enabled.

Bootstrap

The bootstrap file will load shares and common used data and paths (etc.) throughout the application.
Then you can add anything else to bootstrap in the future if you find a script.

A simple example of something in your bootstrap:
bootstrap.php

(MUST be in the root folder for the constant to work)

// Define root folder
define ('FOLDER_ROOT', __DIR__);

      

Then throughout the application, you can refer to this constant ( FOLDER_ROOT

) to determine the root folder, and work through subfolders as needed.

So, using your current setup:
index.php

(I assume this is in the root folder)

include('bootstrap.php');
include(FOLDER_ROOT.'/common/html/header.php');
// Everything else

      

So, then in your bootstrap you can set other things like doctype or character encoding definitions, install error management.
Though you usually set things like doctype after bootstrapping in a class, router, controller or even template.
But since you are using a shared file and not using the more traditional wireframe design pattern, this way will at least save you some headaches and possibly further down the line.

So, again in bootstrap.php

:

// Define root folder
define ('FOLDER_ROOT', __DIR__);
// Define CSS folder using root folder constant above
define ('FOLDER_CSS', FOLDER_ROOT.'/common/stylesheets/');

      

Then in header.php

:

echo '<link rel="stylesheet" type="text/css" href="'.FOLDER_CSS.'default.css">';

      

Subfolders (i.e. / admin)

Now in subfolders like /pages/admin/dashboard.php

etc you don't have access to these constants because you load your header files and other templates like things all separately "through your application".
So it becomes a battle to set your root folder, plus you now manage it all twice!

You can try downloading the root boot file in the admin folder.
So, into dashboard.php

something like:

include('/bootstrap.php');
// OR (more likely)
include('../../bootstrap.php');

      

But it gets messy, calling the bootstrap in different places, and calling it differently.

It's not ideal, but it's smart because if you are uploading a bootstrap in your admin area, you have a root path setting in the admin area, so managing other files from admin files should be easier.

You can try using a new admin boot file like in /pages/admin/

, have adminBootstrap.php

.
But then you set two different constants for root and probably more constants to get to your shared and css files and folders. It is easy to configure your root path in a file that is on the Internet root path, and it can be tricky (sometimes) to configure your network root path from another folder.

Stylesheets

You mentioned that using /common/stylesheets/defaults.css

(with the previous forward slash) doesn't work and forces the original code to show localhost/common/stylesheets/defaults.css

.
This may indicate a need to tweak the DocumentRoot.

On Linux, it is located in /etc/apache2/sites-available/

, then either file default

, or if you have configured your own virtual sites, go to each.

What's your DocumentRoot like?

Although, if you load the boot block within the admin area, this problem can go away by using a constant FOLDER_CSS

.

Folder structure

I also think that you should tidy up your folders as you seem to have split things up into illogical folder names (perhaps logical for you, but will that be when you learn more and come back to it a year later or another dev tries to use it ?).

eg. I wouldn't know what the folder would contain html

, since HTML is a protocol and your application will eventually serve HTML.

Read a little into MVC. Don't get too deep into how much you read / learn, but if you understand the basics, you can then remove your own structure to create your own logical separation of view from business a little more logical than it is now.

Front controller

If instead of using include files, you had a framework that loads bootstrap and app configurations, error management, and so on, then when you load your HTML (your header, footer, etc.), they'll have this whole app (root folder constants, etc.) pre-loaded no matter which subfolder you are trying to load the web pages into.

However, the way you do it, you instead include these things manually when you need it in different files, in subfolders.

For now, you introduce a slight presence of DRY (Do not Repeat Yourself), keeping in mind that the doctype, head, etc. include files and reuse them, you still have to repeat yourself with those that include files as you do - use them wherever you need them.

Also, what if you want to change the admin style differently to the main site? You have to include another header file or a different stylesheet, or just put all the code in the same stylesheet.

I'm waffling, but hopefully I'm clear on this and you can see why using a header is only a small step in the right direction for smaller sites. I'm sure you naturally learned to use these include files from the head / doctype set, etc. In every file.

However, now you are trying to break into other directions, as in your area of ​​administration, you can see that the restrictions and including the same files become more difficult to manage as your entire application grows.

So, if you had a front controller type setting, in yours dashboard.php

you could just use the constants set in the root boot file and any other subfolder that can be accessed after the main application is loaded.

EG (when using a front controller such as the picture) dashboard.php

:

include(FOLDER_ROOT.'/common/html/header.php');

      

I know I already talked about the front controller, but a few years ago I was at the stage where you are now and went from all my files including header.php, then page content, and then the .php footer etc. and I started using the front controller instead.
It really is much better!

It's a fair learning curve (with learning curves in all directions and methods, requirements, etc.) and, as such, will leave it up to you if you want to go further.

Now I have my own basic MVC control system, which I just simply overlay on a new file for a new website page in the view / pages folder and the page can be used right away in the browser (the system does the rest).

0


source







All Articles