do-it-yourself universal header/footer.php

2020-04-19 06:25发布

I wanna make universal header/footer include files.
Universal here means to be applicable in files on any directory level without need to add “../” at any deeper level when calling “header.php” from “includes” directory.

Ok, fine.
I can use
<?php include $_SERVER[‘DOCUMENT_ROOT’].”/includes/header.php”;?>

to have it anywhere but the header.php contains a relative reference to a .css file and the .css file contains its relative references (for instance “background: url(../images/o.gif);” and all that lands me in a quagmire of “../../” at every new level.

Of course, I could replicate the .css and ../images at every level yet it seems a bit awkward and contrary to the very principle and spirit of the great php (control all at one place).

Respectfully yours` sehrguey ogoltsoff

标签: php uri
3条回答
男人必须洒脱
2楼-- · 2020-04-19 06:58

You could have the url in the CSS be an absolute path (one that starts with /). Then it will work regardless of where on your site the user has browsed.

Alternatively, you could use URL rewriting mod_rewrite to make the URL the user visits stay in the top level.

查看更多
Deceive 欺骗
3楼-- · 2020-04-19 07:17

You want to encapsulate what varies, which is the relative path to some location of the request (viewed from the browser) to the root URL of your website (again viewed from the browser).

For that you first of all need to know the root URL and the URL of the request, in PHP this could be something like this:

$rootURL = 'http://example.com/mysite/basedir/';
$requestURI = $_SERVER['REQUEST_URI']; # e.g. /mysite/basedir/subdir/index.php

PHP then offers diverse string functions to turn this into the relative path:

'../' + X

For example you could put that into a class that does this:

$relative = new RelativeRoot($rootURL, $requestURI);

echo $relative; # ../
echo $relative->getRelative('style/default.css'); # ../style/default.css

An example of such a class would be:

/**
 * Relative Path to Root based on root URL and request URI
 * 
 * @author hakre
 */
class RelativeRoot
{
    /**
     * @var string
     */
    private $relative;

    /**
     * @param string $rootURL
     * @param string $requestURI
     */
    public function __construct($rootURL, $requestURI)
    {
        $this->relative = $this->calculateRelative($rootURL, $requestURI);
    }

    /**
     * @param string $link (optional) from root
     * @return string
     */
    public function getRelative($link = '')
    {
        return $this->relative . $link;
    }

    public function __toString()
    {
        return $this->relative;
    }

    /**
     * calculate the relative URL path
     * 
     * @param string $rootURL
     * @param string $requestURI
     */
    private function calculateRelative($rootURL, $requestURI)
    {
        $rootPath = parse_url($rootURL, PHP_URL_PATH);
        $requestPath = parse_url($requestURI, PHP_URL_PATH);

        if ($rootPath === substr($requestPath, 0, $rootPathLen = strlen($rootPath)))
        {
            $requestRelativePath = substr($requestPath, $rootPathLen);
            $level = substr_count($requestRelativePath, '/');
            $relative = str_repeat('../', $level);

            # save the output some bytes if applicable
            if (strlen($relative) > strlen($rootPath))
            {
                $relative = $rootPath;
            }
        }
        else
        {
            $relative = $rootPath;
        }

        return $relative;
    }
}
查看更多
爷的心禁止访问
4楼-- · 2020-04-19 07:19

Calling css images and the such uses ../ while programatically correct is bad form. You should always use absolute paths /css/style.css /images/image.png /js/script.js etc...

I usually define the application directory with a constant for headers and footers.

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

Makes it a bit easier to include other files without all having to write out all variable for the doc root over and over.

Though in my opinion everything is moving towards frameworks, you should really consider sung Symfony, Codeigniter or the like. If it's a 3 page deal, do it straight up php but if you're doing an all out app and it's new development, you do yourself a disservice by not using a framework.

查看更多
登录 后发表回答