Собственный универсальный заголовок/footer.php

Я хочу сделать универсальные файлы заголовка/нижнего колонтитула.
Universal здесь означает, что он применим в файлах на любом уровне каталога без необходимости добавлять "../" на любом более глубоком уровне при вызове "header.php" из каталога "includes".

Хорошо.
Я могу использовать  <?php include $_SERVER[‘DOCUMENT_ROOT’]."/includes/header.php";?>

иметь его где угодно, но header.php содержит относительную ссылку на .css файл, а файл .css содержит его относительные ссылки (например, background: url (../images/o.gif); "и все это заставляет меня в трясине".. /../" на каждом новом уровне. Конечно, я мог бы реплицировать .css и.. /images на каждом уровне, но это кажется немного неудобным и противоречит самому принципу и духу великого php (контролируйте все в одном месте).

С уважением, sehrguey ogoltsoff

Ответ 1

У вас может быть url в CSS абсолютный путь (тот, который начинается с /). Затем он будет работать независимо от того, где на вашем сайте просматривался пользователь.

В качестве альтернативы вы можете использовать переписывание URL-адресов mod_rewrite, чтобы URL-адрес посетителя пользователя находился на верхнем уровне.

Ответ 2

Вызов изображений css и таких применений.. /, тогда как программная правильность - это плохая форма. Вы всегда должны использовать абсолютные пути /css/style.css/images/image.png/js/ script.js и т.д.

Я обычно определяю каталог приложения с константой для верхних и нижних колонтитулов.

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

Делает несколько проще включать другие файлы, не задумываясь о том, что все переменные для корня doc повторяются снова и снова.

Хотя, на мой взгляд, все движется в сторону каркасов, вы должны действительно рассматривать пение Symfony, Codeigniter или тому подобное. Если это 3-страничная сделка, сделайте это прямо вверх по php, но если вы делаете все приложение и это новая разработка, вы оказываете себе плохую услугу, не используя фреймворк.

Ответ 3

Вы хотите инкапсулировать то, что меняется, это относительный путь к некоторому местоположению запроса (просматривается из браузера) до корневого URL вашего сайта (снова просматривается в браузере).

Для этого вам в первую очередь нужно знать корневой URL-адрес и URL-адрес запроса, в PHP это может быть примерно так:

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

Затем PHP предлагает различные строковые функции, чтобы превратить это в относительный путь:

'../' + X

Например, вы можете поместить это в класс, который делает это:

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

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

Примером такого класса может быть:

/**
 * 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;
    }
}