我们如何在不指定子文件夹路径的情况下包含PHP文件



通常,我们使用以下代码将php文件彼此包含:

<?php 
include_once 'include/config.php';
// OR
include 'include/config.php'; 
// OR 
include_once $_SERVER['DOCUMENT_ROOT'].'include/config.php';
// ect...
?>

但是,仅当PHP文件位于根文件中时,上述代码才适用。我的意思是,如果我们将文件移至子文件夹中。我们需要更改PHP文件中包含的代码。例如这样:

<?php 
    include_once 'subfolder/include/config.php';
    // OR
    include 'subfolder/include/config.php'; 
    // OR 
    include_once $_SERVER['DOCUMENT_ROOT'].'/subfolder/include/config.php';
    // ect...
?>

我的意思是,当我们将php文件移动到子文件夹中时,Incluest_once希望看到类似(include_once 'subfolder/include/config.php';)的子文件夹名称。这是一个具有挑战性的情况,因为我们需要为许多文件中的包含页面执行此操作。

例如,我包括index.php中的include_once $_SERVER['DOCUMENT_ROOT'].'/functions/includes.php';,还包括所有PHP文件(例如header.php, posts.php, and ajax_post.php)的php文件。它可以从根文件夹中工作正常,但是如果我们在子文件夹中移动文件,则包括.php文件不包括没有子文件夹名称。

也许也可以使用.htaccess进行此操作。

我制作了此HTACCESS代码,也许您有一个使用HTACCESS的解决方案。我必须说我尝试使用 RewriteBase /subfoldername/,但包括文件没有起作用。

Options +FollowSymLinks -MultiViews
RewriteEngine On 
RewriteBase /
RewriteCond %{REQUEST_METHOD} !POST
RewriteCond %{THE_REQUEST} s/+(.+?).php[s?] [NC]
RewriteRule ^ /%1 [R=302,NE,L]
RewriteCond %{REQUEST_METHOD} !POST
RewriteCond %{THE_REQUEST} /index.php [NC]
RewriteRule ^(.*)index.php$ /$1 [L,R=302,NC,NE]
RewriteCond %{REQUEST_FILENAME} -d [OR]
RewriteCond %{REQUEST_FILENAME} -f
RewriteRule ^ - [L]
RewriteRule ^group/([w-]+)/?$ sources/group.php?group_username=$1 [L,QSA]  
RewriteRule ^profile/([w-]+)/?$ sources/user_profile.php?username=$1 [L,QSA]
RewriteRule ^profile/(followers|friends|photos|videos|locations|musics)/([w-]+)/?$ sources/$1.php?username=$2 [L,QSA]     
RewriteRule ^admin/(.*)$ admin/index.php?page=$1 [L,QSA]
RewriteCond %{REQUEST_FILENAME}.php -f
RewriteRule ^(.+?)/?$ $1.php [L]  
RewriteRule ^(.+?)/?$ index.php?pages=$1 [L,QSA]

我的责任是,我们如何在没有子文件符号的情况下包括PHP文件?

您可以使用您.htaccess中的auto_prepend_file指令在所有PHP文件之前制作一个.php文件。

如果您使用的是mod_php,则在.htaccess中使用此行:

php_value auto_prepend_file "/Applications/MAMP/htdocs/script/env.php"

注意对于PHP-FPM,您需要在.user.ini文件中具有这些等效行:

auto_prepend_file = "/Applications/MAMP/htdocs/script/env.php"

然后在您的项目基础目录中创建一个新文件env.php,只有一行:

<?php
   $baseDir = __dir__ . '/';
?>

此行设置一个具有您项目基础目录值的变量$baseDir,即/Applications/MAMP/htdocs/script/ /Applications/MAMP/htdocs/subdir/script/

然后使用此变量$baseDir您必须包括其他文件,例如:

include_once $baseDir.'functions/includes.php';
include_once $baseDir.'functions/get.php';

您必须使用函数set_include_path()bootstrap.phpindex.php中的某个地方添加下一个代码:

<?php
$path = '/usr/pathToYourDir';
set_include_path(get_include_path() . PATH_SEPARATOR . $path);

现在到处都可以写这篇文章:

include_once 'include/config.php';
// or
include_once 'include/db/index.php';
// etc

,如果您需要将代码移动到另一个目录 - 您只需要将varibalbe $path = '/usr/pathToYourDir';的路径值更改为到达目录的新路径。

<<p>好吧,我不是这样做的粉丝,但是它会按要求完成工作:
$newpath="";
$dirs = array_filter(glob('*'), 'is_dir');
foreach ($dirs as $location) {
    $newpath .= PATH_SEPARATOR . $location; 
}
set_include_path(get_include_path() . $newpath);

上面的代码将从该文件运行的位置找到所有子文件夹,并将它们全部添加到当前包含路径中。通过从:

更改全球
glob('*') 

to

glob('includes/*')  or glob('includes' . DIRECTORY_SEPARATOR . '*')

您只能将其限制为仅包括的子文件夹。

以上未测试,我只是将代码扔了在一起,但它说明了一种做您要求的方法。

我仍然建议将文件放在确定的位置中,而不是尝试从任何地方包括它们。

这就是我的方式。

//----- some global location like index.php
if(!defined("CONFIG_PATH")) define("PATH_CONFIG", __DIR__."/include/");
//------------ then later in some other file
if(!defined("CONFIG_PATH"))die("Config path is not defined.");
include_once CONFIG_PATH.'config.php';

然后,当您更改它时,您只需更新

if(!defined("CONFIG_PATH")) define("PATH_CONFIG", __DIR__."/include/subfolder/");

我会说这是这样做的"传统"方式,为此使用全球常数是完全很好的。这不是您想要在运行时更改的东西。您可能需要在许多地方访问它。您可以检查您的文件是否正确访问。等等。

MVC框架以这种确切的方式执行此操作。

以下是通过auto_prepend_file指令进行预先提前文件的方法的示例。

bootstrap.php

<?php
$require_upfront = function($dir) {
    require_once $dir . '/one.php';
    require_once $dir . '/two.php';
};
$require_upfront(__DIR__ . '/inc');

添加到php配置,此处.htaccess示例:

php_value auto_prepend_file "/abs/path/to/bootstrap.php"

如果您在所有服务器中都有该文件的名称,则可以使用这样的研究对此进行研究。

我认为,当此脚本运行很多时,此解决方案不会更好,但是如果包含函数失败,使用尝试和捕获(如果您使用此方法观看PHP版本),或者如果您知道这一点,则可以包括每天更改此路径一次,您可以制作一个用例程启动的文件。

如果您这样做,则需要存储此路径,但是我不知道是否有使全局变量的方法。我的解决方案是存储或在数据库或文件中。

我希望我能为您提供帮助。

我从答案中了解的https://stackoverflow.com/a/50632691/7362396是您需要根据入门点脚本的目录包含文件。

解决方案无需apache或php.ini auto_prepend_file可能是使用getcwd()。它返回当前的工作目录,即使在随附的文件中调用时,该目录也应该是入口点/主脚本的路径。

如果简单地使用getcwd()而不是$baseDir工作?:

include_once getcwd().'/functions/includes.php';
include_once getcwd().'/functions/get.php';

使用Apache修复您的应用程序正在以错误的级别求解。

如果您必须在文件位置更改时更新代码中的一堆文件,那就是您的代码告诉您您做出了不良的架构决定。因此,解决实际问题并停止重复自己。

定义您在一个地方包含的位置,然后在需要时,相应地更新该位置。

做到这一点的一种方法是在应用程序的根部设置一个常数。这是假设您在应用程序的词根上有一些代码。这可能是index.phpindex.php包含的脚本:

// index.php or a file included by index.php
const MY_INCLUDE_PATH = __DIR__ . '/path/to/subfolder`

然后您的其他脚本可以使用常数包括:

// some other script included to handle the page
include MY_INCLUDE_PATH . '/config.php';
include MY_INCLUDE_PATH . '/some-other-include.php';

尽管他们都想包含config.php文件,但也许继续将其包含在您的index.php中。

这是不是您要避免的"坏"全局。它使用常数按预期。常数是命名空间的一部分,如果您为应用程序使用名称空间。

这是假设有一个包括子文件夹,有时会更改位置和脚本,这是每个请求的一部分。那是对的吗?如果没有,请发布您的目录结构。

函数也将起作用,并且可以根据诸如调用脚本的路径之类的内容包括逻辑:

// index.php or a file included by index.php
my_include_function($path) {
  //do stuff
}

其他脚本可能称此函数为:

// some other script included to handle the request
my_include_function(__FILE__);

然后,当事情发生变化时,您只需在一个文件中更新一个函数。

这一切都假定您有一个index.php或类似的脚本来处理每个请求,并且可以成为定义函数或常数的单个控制点。如果不是这样,应该是!

更新您的代码以使用路由器(以下是一个)可能需要10分钟,并有可能简化您发布的gnarly .htaccess文件。

相关内容

最新更新