【问题标题】:How can we include php files without specifying the subfolder path我们如何在不指定子文件夹路径的情况下包含 php 文件
【发布时间】:2018-05-27 20:52:23
【问题描述】:

通常我们使用以下代码将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 文件移动到子文件夹时,include_once 想要查看子文件夹名称,例如 (include_once 'subfolder/include/config.php';)。这是一个具有挑战性的情况,因为我们需要对许多文件中包含的页面执行此操作。

例如,我包含来自index.phpinclude_once $_SERVER['DOCUMENT_ROOT'].'/functions/includes.php';,还包含来自所有php 文件(如header.php, posts.php, and ajax_post.php)的includes.php 文件。它在根文件夹中工作正常,但如果我们移动子文件夹中的文件,则 include.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 文件?

【问题讨论】:

  • 一种方法是使用set_include_path 配置这些路径。
  • 为什么不使用相对路径
  • @cteski 嗯,它看起来是一个不错的解决方案。我要测试一下。
  • 我通常使用 DIRECTORY_SEPARATOR 常量相对于文档根目录。使其在操作环境之间变得干净且可移植。 include_once($_SERVER['DOCUMENT_ROOT'].DIRECTORY_SEPARATOR."include_folder".DIRECTORY_SEPARATOR."included_file.php");
  • @Typel include_folder 是什么,我在问我的职责是,我们如何才能包含没有子文件夹名称的 php 文件 但你的答案有子文件夹名称??

标签: php .htaccess


【解决方案1】:

您可以在 .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/ OR /Applications/MAMP/htdocs/subdir/script/

然后在您必须包含其他文件的任何地方使用此变量$baseDir,例如:

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

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

【讨论】:

  • 我认为您的回答会帮助很多人。非常感谢你。你是我最好的人
  • 自动前置可能非常危险,请确保不要有自动前置脚本的任何输出,因为这可能会导致标题问题,并且在某些情况下会导致下载问题。
  • 同意这一点,尽管这种情况相当简单,因为 OP 只想访问单个全局。
  • @Azzo:这个答案也适用于 php-gpm,只需稍作改动。看到这个帖子:medium.com/@jacksonpauls/…
  • @anubhava 如果可能的话,您能否检查我的问题,因为您是正则表达式方面的天才。 stackoverflow.com/questions/67026794/…
【解决方案2】:

您必须使用函数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'; 的值更改为您目录的新路径。

【讨论】:

    【解决方案3】:

    好的,我不喜欢这样做,但它会按照要求完成工作:

    $newpath="";
    
    $dirs = array_filter(glob('*'), 'is_dir');
    foreach ($dirs as $location) {
        $newpath .= PATH_SEPARATOR . $location; 
    }
    set_include_path(get_include_path() . $newpath);
    

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

    glob('*') 
    

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

    您可以将其限制为仅包含下的子文件夹。

    以上内容未经测试,我只是将代码放在一起,但它说明了一种实现您要求的方法。

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

    【讨论】:

      【解决方案4】:

      __DIR__ 肯定是您要找的。使用它来提供所需文件的相对路径。我强烈建议对所有库文件使用require_onceinclude_once

      include_once dirname(dirname(__DIR__))."/include/config.php";
      

      【讨论】:

      • __DIR__ 在这种情况下不起作用,因为它的 __DIR__.'/include/config.php'__DIR__.'/subfolder/include/config.php' 如果不是这种情况(config.php 与此文件位于同一文件夹中,则为相对路径会工作)
      【解决方案5】:

      这就是我的做法。

      //----- 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 框架都是这样做的。

      【讨论】:

      • 全局变量是全局变量,如果没有足够的名称间距,它们会使集成其他框架/库/脚本变得困难。
      【解决方案6】:

      这是一个需要通过 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"
      

      【讨论】:

      • 这很好,告诉您下载并意识到 bootstrap.php 中的某些内容正在输出内容。然后它会炸毁您的标题或在您的下载文件中包含内容。也很难追踪这些内容的来源。
      • 是的,了解任何方法的局限性是件好事。好的文档/评论在这里会有所帮助。
      • 我有一个网络人用我们的反向代理“修复”了一些东西,我们花了大约 2 周的时间才弄明白。
      • 您会惊讶于在打开 PHP 标记之前对 \n&lt;?php 行返回进行罚款是多么困难。甚至最后是&lt;?php ... ?&gt;\n。我现在从不关闭我的 PHP 标签...大声笑
      • 尾随和前面的空白输出/问题并不是我在这里介绍的解决方案所特有的。
      【解决方案7】:

      如果您的文件名在所有服务器中都是唯一的,您可以使用this 之类的研究来对此进行研究。

      我认为当这个脚本运行很多时这个解决方案并不好,但是如果包含函数失败,你可以包含,使用try and catch (if you use this method watch the php version),或者如果你知道这个路径每天更改一次,你可以制作一个文件以例程启动。

      如果做这个,需要保存这个路径,但是不知道有没有make全局变量的方法。我的解决方案是存储或存储在数据库或文件中。

      希望对你有所帮助。

      【讨论】:

      • 我记得如果你有不同的文件到同名的不同文件夹中,这个方法不起作用。
      【解决方案8】:

      我从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';
      

      【讨论】:

        【解决方案9】:

        使用 Apache 修复您的应用程序是在错误的级别上解决它。

        如果您必须在文件位置更改时更新代码中的一堆文件,这就是您的代码告诉您做出了错误的架构决策。所以解决实际问题,不要重复自己。

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

        一种方法是在应用的根目录中设置一个常量。这假设您在每个页面上调用的应用程序的根目录中有一些代码。这可能是index.phpindex.php 包含的脚本:

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

        然后您的其他脚本可以使用常量调用 include:

        // 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 或类似的脚本来处理每个请求,并且可以作为定义函数或常量的单点控制。如果不是这样,那应该是!

        更新您的代码以使用路由器 (here is one) 可能需要 10 分钟,并且可能会简化您发布的那个粗糙的 .htaccess 文件。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2020-03-22
          • 2018-04-18
          • 1970-01-01
          • 2017-10-08
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2020-04-01
          相关资源
          最近更新 更多