更新1 ,要清楚了解正在发生的事情,您可以download a snippet of the script from here.
我在一个新网站上工作,在所有PHP页面中都有相同的header
,footer
。
在标题中,我引用了网站中的其他常见文件,例如.css
,.js
,functions
,classes
,db connection
等。
例如,default.css
位于/common/stylesheets/
我的header.php和footer.php在/common/html/
文件夹
所以我的header.php文件是这样的
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>The Header</title>
<link rel="stylesheet" href="common/stylesheets/default.css">
</head>
<body>
在我的网站index.php
中,我添加了标题<?php include('common/html/header.php'); ?>
,这很正常......但是当我在其他目录或子目录中的其他php页面中包含标题时,问题就会出现,例如/pages/admin/dashboard.php
,一切都搞砸了,而且该页面不再与default.css
文件相关联。
所以,我正在寻找的是一种方法或逻辑,我在每个PHP页面中引用这些常见文件和文件夹,无论它的位置如何;例如站点根目录,站点根目录或子目录......等等......
这是我的网站根
的图片
非常感谢您的帮助......
P.S。我试图在$_SERVER['']
文件中使用一些超级全局变量(例如config.inc.php
)来定义路径,然后我将该文件包含在header.php
中。但我无法弄清楚哪一个会动态地引用那些常见文件夹和文件,而不是PHP页面所在的位置。
更新1 ,要清楚了解正在发生的事情,您可以download a snippet of the script from here.
答案 0 :(得分:3)
使用完全限定或绝对的URL来引用您的资产通常是个好主意:
<link rel="stylesheet" href="http://www.sitenamecom/some/path/to/common/stylesheets/default.css">
由于有许多地方需要正确的URL基础来访问不同的文件,因此您可以定义具有Web根目录的常量:
define('WEB_ROOT', 'http://www.sitename.com');
然后你可以定义其他常量来访问系统的不同部分:
define('WEB_ASSETS', WEB_ROOT . '/common');
因此,对于header.php
中的样式表链接,它将是:
<link rel="stylesheet" href="<?php echo WEB_ASSETS; ?>/stylesheets/default.css">
对于include
个文件,原则是相同的,在这种情况下,您不使用URL但使用文件系统的路径。这并不是解决这个问题的动态方式,它都归结为绝对路径。
这里的问题是本地开发环境中的树结构可能(并且肯定不会)与您的服务器匹配。因此,在配置文件中,您可以定义:
,它位于应用程序的根目录中define('APP_ROOT', dirname(__FILE__));
然后让我们使用admin/index.php
文件作为示例:
include '../../../config.inc.php';
include APP_ROOT . '/sitename/common/html/header.php';
这里棘手的部分包括配置。因为,直到你这样做APP_ROOT
不可用,才需要相对路径才能到达它,并且不可能逃脱这个路径;除非你完全相信首选的绝对形式:
include '/some/path/to/config.inc.php';
如前所述,如果应用程序在不同的环境中进行测试,那么领先的斜杠就会出现问题,因为很少some/path/to
总是相同的。
答案 1 :(得分:2)
这是不使用index.php进行集中化的结构的常见问题。也许您可以尝试添加另一个将您的目录定义为伪常量的include,并将它们添加到您的资产URL。
或者您可以解析请求网址的深度,并自动将所需的../级别预先添加到您的资产网址中。我为过去的一个项目做过这个。
我要警告你,最好解决问题的根源(缺乏集中化)而不是添加变通方法。它肯定会比你想象的更早地回来困扰你。
答案 2 :(得分:2)
$ _ SERVER [&#39; DOCUMENT_ROOT&#39;]很可能就是你要找的。 p>
<?php
require_once($_SERVER['DOCUMENT_ROOT'] . "/sitename/common/html/header.php");
这应该适用于任何目录。如果你希望它比输入&#34; sitename&#34;更有活力,你可以这样做:
<?php
$sitename = explode("/", $_SERVER['REQUEST_URI']);
require_once($_SERVER['DOCUMENT_ROOT'] . "/" . $sitename[1] . "/common/html/header.php");
答案 3 :(得分:1)
您需要将<link rel="stylesheet" href="common/stylesheets/default.css">
更改为<link rel="stylesheet" href="../../common/stylesheets/default.css">
答案 4 :(得分:1)
这是php.ini中的一个简单修改,包括每个脚本的footer.php和header.php
auto_append_file=ABSOLUTE_PATH/footer.php
auto_prepend_file=ABSOLUTE_PATH/header.php
如果您在easyPhp,xampp,....下运行,请重新启动Apache
警告:此配置将应用于使用修改后的PHP 执行的所有项目
答案 5 :(得分:0)
尝试<link rel="stylesheet" href="/common/stylesheets/default.css">
请注意前导斜杠...这会将服务器定向到文档根目录。
我尝试了它并且它有效。
我的树:
/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;
}
在浏览器中查看http://localhost/subdir/body.php
,我得到了预期的结果:&#34;标题&#34;和&#34;身体&#34;是红色的。
答案 6 :(得分:0)
我会将您网站的文档根目录存储在某个定义中:
define('DOCROOT', $_SERVER['DOCUMENT_ROOT']);
在包含在任何地方的PHP文件中执行此操作,最好是在某些引导程序的PHP文件中。
然后你需要在你的包含行中添加你的路径:
<?php include(DOCROOT . "/common/html/header.php"); ?>
您是否也查看了include_once
?
答案 7 :(得分:0)
您是否尝试过PHP的set_include_path?
您可以在一个set_include_path中添加多个路径,用“:”分隔它们。 通过set_include_path( '/家庭/ mysite的/ includes1:/家庭/ mysite的/ includes2')。 PHP.net -> set_include_path
答案 8 :(得分:0)
即使没有移动到完整的前端控制器(和MVC)设置(这将是好的),如果你引入一个简单的类似引导程序的文件,你将节省很多麻烦。
对于您当前的设置,它并不完美,因为您的文件包含系统的不同部分(即header.php),位于不同的位置和子文件夹中。
有标头加载第一个输出的东西 - 即doctype,head和head链接等 - 在你的基本结构中很好,但你现在遇到了一些你无法解决的约束,而不会让你的header.php
凌乱,或者包括header.php
之前的许多其他文件。
在更加可靠的框架设计中,html和doctype输出是在启动和加载许多其他内容之后,以允许控制所述html和doctype。
但是为了帮助您,只需在加载/包含任何其他内容之前加载引导程序。
引导程序将在整个应用程序中加载共享资源以及常用的数据和路径(等) 如果找到方案,您可以在将来添加引导程序中的任何其他内容。
引导程序中的一个简单示例:
bootstrap.php
(必须位于您的根网站文件夹中,以便跟随常量工作)
// Define root folder
define ('FOLDER_ROOT', __DIR__);
然后在整个应用程序中,您可以引用该常量(FOLDER_ROOT
)来确定根文件夹,并根据需要处理子文件夹。
因此,使用您当前的设置:
index.php
(我认为是在根文件夹中)
include('bootstrap.php');
include(FOLDER_ROOT.'/common/html/header.php');
// Everything else
然后在您的引导程序中,您可以设置其他内容,例如定义默认文档类型或字符编码,设置错误管理。
虽然你通常会在bootstrap,类,路由器,某些控制器甚至模板之后设置doctype之类的东西。
但是,当您使用通用文件包含而不是使用更传统的框架设计模式时,这种方式至少可以为您节省一些麻烦,并且可能更进一步。
再次在bootstrap.php
:
// Define root folder
define ('FOLDER_ROOT', __DIR__);
// Define CSS folder using root folder constant above
define ('FOLDER_CSS', FOLDER_ROOT.'/common/stylesheets/');
然后在header.php
:
echo '<link rel="stylesheet" type="text/css" href="'.FOLDER_CSS.'default.css">';
现在在子文件夹(例如/pages/admin/dashboard.php
等)中,您无法访问这些常量,因为您正在加载您的头文件和其他模板,例如所有内容和#34;在整个应用程序中#34 ;.
因此,设置根文件夹变成了一场战斗,而且你现在正在管理它们两次!
您可以尝试在管理文件夹中加载根引导文件
所以在dashboard.php
中,例如:
include('/bootstrap.php');
// OR (more likely)
include('../../bootstrap.php');
但这变得凌乱,在不同的地方调用bootstrap,不得不以不同的方式调用它。
这不太理想,但它是可行的,因为如果您在管理区域内加载了引导程序,那么您可以在管理区域中设置根路径,从而管理管理文件中的其他文件应该更容易。
您可以尝试使用新的管理员特定引导程序文件,例如在/pages/admin/
中,adminBootstrap.php
。
但是你要为root设置两个不同的常量,并且可能需要更多的常量来获取你的common和css文件和文件夹。可以轻松地在Web根路径中的文件中设置Web根路径,并且可能很棘手(有时)从另一个文件夹设置Web根路径。
您提到使用/common/stylesheets/defaults.css
(带有前面的斜杠)并不起作用,导致源代码显示localhost/common/stylesheets/defaults.css
。
这可能表示您需要配置DocumentRoot。
在Linux上/etc/apache2/sites-available/
,然后是default
文件,或者如果您配置了自己的虚拟网站,那么请进入每个虚拟网站。
您的DocumentRoot设置为什么?
虽然如果你在管理区域内运行引导程序,这个问题可能会消失,使用常量FOLDER_CSS
。
我还认为你应该整理你的文件夹,因为你似乎把事情分成了不合逻辑的文件夹名称(对你来说可能是合乎逻辑的,但是当你在一年内学到更多并回到它或其他开发时它会是试着用它?)。
E.G。我不知道文件夹html
到底包含什么,因为HTML是一种协议,最终你的应用程序将提供HTML。
稍微阅读一下MVC。不要深入阅读/学习,但如果你掌握了基础知识,那么你就可以整理自己的结构,创建自己的逻辑分离,从逻辑上讲比业务更具逻辑性。现在是。
如果没有使用包含文件,你有一个框架,它加载引导和应用程序范围的配置,错误管理,其他东西,然后当你来加载HTML(你的页眉,页脚等),他们将拥有所有这些无论您尝试从哪个子文件夹加载网页,预加载应用程序(根文件夹常量等)。
然而,正如您所做的那样,只要您需要在子文件夹中的不同文件中手动包含这些内容。
当你通过在包含文件中使用doctype,head等来介绍一小部分DRY(不要重复自己)时,你仍然需要重复使用这些包含文件作为您可以在任何需要的地方重复使用它们。
另外,如果您想以不同方式为主网站重新设置管理员,该怎么办?您必须包含不同的头文件或不同的样式表,或者只是将所有代码放在同一样式表中。
我是胡扯,但希望我能够清楚,你可以看到为什么使用标题包含只是向正确方向和小网站迈出的一小步。我确信你在每个文件中输入head / doctype等使用这些包含文件会自然而然地进步。
然而,现在您正试图突破其他方向,就像您的管理区域一样,您可以看到约束,包括那些相同的文件在整个应用程序增长时变得越来越难以管理。
因此,如果您有一个前端控制器类型设置,在dashboard.php
中您可以简单地使用根引导文件中设置的常量,以及核心应用程序之后将访问的任何其他子文件夹已加载。
EG(如果使用前控制器像模式)
dashboard.php
:
include(FOLDER_ROOT.'/common/html/header.php');
我知道我已经对前端控制器感兴趣了,但几年前我就处于你现在的阶段,并且从拥有所有文件(包括header.php,然后是页面内容)转移到了包括footer.php等,而我开始使用前端控制器 它真的太好了!
这是一个公平的学习曲线(在各种方向和方法,要求等方面都有学习曲线),如果你想进一步了解它,将会由你决定。
我现在拥有自己的基本MVC前端控制器系统,我只是简单地将新网站页面的新文件存入view / pages文件夹,该页面可以立即在浏览器中使用(系统会执行其他所有操作) )。