【问题标题】:Included php files wont work after moved files subfolder移动文件子文件夹后,包含的 php 文件将不起作用
【发布时间】:2018-05-27 08:12:24
【问题描述】:

我的 php 包含部分有问题。为了充分解释问题,我为您创建了一个测试页面。

首先,我想向您展示文件的架构。您也可以从这个LINK下载测试文件并在线测试TEST LINK

如您所见,htdocs(根)文件中有一个子文件夹,所有的 php 文件都在其中。现在我将分别向您展示文件中的php代码。

appname/index.php

<?php include_once 'includes/config.php';?>
<div class="callPage">Click Here</div>
<div id="testBox"></div>

<script type="text/javascript">
  $(document).ready(function(){
      var siteurl = '<?php echo $url;?>';
      $("body").on("click",".callPage", function(){
       $.ajax({
            url: siteurl+'content/test',
            beforeSend: function() {
                //Do something
            },
            complete:function(){
              //Do something 
            },
            success:function(response){
                $("#testBox").html(response);
            }
            });
    });
     function LoadPage(){
       $.get(siteurl+'content/test', function(data) {
          $('#testBox').html(data);
       });
    }
    LoadPage(); 
  });
</script>  

应用名称/内容/test.php

<?php 
include_once 'includes/config.php';
echo $text.'</br>';
echo $worked.'</br>';
?>

appname/includes/config.php

<?php 
$url = 'http://localhost:8888/';
$text = 'Well Come! How are you today ?';
$worked = 'It is working :)';
?>

当您打开TEST LINK时,LoadPage(); javascript函数会调用内容文件中的test.php,并显示在#testBox中。首先,您不会在 #testBox 中看到来自 index.php 的任何内容。因为config.php 不能包含在test.php 中。

我知道如果我将这一行 include_once 'includes/config.php';test.php 更改为这样的 include_once '/appname/includes/config.php';,那么问题将得到解决。

但是如果页面增加,并且我想使用根(htdocs 或 www)文件夹中的文件,我需要从所有文件中删除 appname(子文件夹名称)=> include_once 'appname/includes/config.php';。当这些文件大量增加时,这将是一个大问题。

其实问题就是:

当应用程序相对于DOCUMENT_ROOT 的路径是可变的或未知的并且include_path 不能被所有应用程序用户可靠地修改时,我们如何在不指定包含的完整路径的情况下包含php 文件?

【问题讨论】:

  • define('ROOT_PATH', dirname(DIR) . '/inc/inc.php'); 真的不包含任何文件.剩下的问题还不清楚。
  • @panther Normaly 包括 inc.php 文件但在 LoadPage() 之后;不包括
  • @DevStud 你到底想用这个定义做什么?
  • @madalinivascu 我想在 ajax LoadPage(); 之后将 inc.php 文件包含在 test.php
  • 使用 Ajax 加载方法而不是 php 包含。 jquery-tutorial.net/ajax/the-load-method

标签: javascript php jquery ajax .htaccess


【解决方案1】:

当您没有在系统上使用绝对路径时,这有时是包含问题。

说明

取决于 PHP 的运行方式可能会影响include&require 的工作方式,如果 PHP 从 appname 目录内运行,如果通过连接器告诉 php 它在 appname 目录内运行,它会正常工作.但是,如果运行 PHP,例如 www-data@/usr/bin/# php /var/www/somesite.com/htdocs/appname/index.php,则路径可能会被破坏。

修复

如果您使用define("FS_ROOT", realpath(dirname(__FILE__))); 作为第一件事,而不是 index.php 中的命名空间,那么您可以使用include FS_ROOT."/includes/config.php"; 这意味着文件路径从系统的根目录开始使用,因此它被评估为@987654326 @

为什么不同

这与 ROOT_PATH 不同,因为 ROOT_PATH 有时由 Web 主机的 PHP 配置设置,这可能是问题所在。因为 PHP 执行路径可能错误地封装了 PHP 主机应用程序以在错误的位置查找包含和请求。

这也意味着任何includerequire 都不应该使用../,因为您应该知道代码库中的路径。

您的应用名称/index.php

<?php define("FS_ROOT", realpath(dirname(__FILE__)));
include_once FS_ROOT.'includes/config.php';?>
<div class="callPage">Click Here</div>
<div id="testBox"></div>

<script type="text/javascript">
  $(document).ready(function(){
      var siteurl = '<?php echo $url;?>';
      $("body").on("click",".callPage", function(){
       $.ajax({
            url: siteurl+'content/test',
            beforeSend: function() {
                //Do something
            },
            complete:function(){
              //Do something 
            },
            success:function(response){
                $("#testBox").html(response);
            }
            });
    });
     function LoadPage(){
       $.get(siteurl+'content/test', function(data) {
          $('#testBox').html(data);
       });
    }
    LoadPage(); 
  });
</script>

您的应用名称/内容/test.php

<?php 
# as this file is loaded directly and is not in the root directory
# we apend the dirname result with ../ so realpath can resolve the root directory for this site
define("FS_ROOT", realpath(dirname(__FILE__)."../"));
include_once FS_ROOT.'includes/config.php';
echo $text.'</br>';
echo $worked.'</br>';
?>

理想情况下,您应该通过引导程序和 .htaccess,这样您就不必在每个加载的文件中重新定义 FS_ROOT

您可以通过确保在 apache 中启用 mod_rewrite 来做到这一点

在 appname 文件夹中创建文件 .htaccess

RewriteCond %{REQUEST_URI} \.(php)$
RewriteRule .* bootstap.php [L]

创建bootstrap.php

define("FS_ROOT", realpath(dirname(__FILE__)));
include_once FS_ROOT.'includes/config.php';
if(file_exists(FS_ROOT.$_SERVER['REQUEST_URI']){
    include(FS_ROOT.$_SERVER['REQUEST_URI']);
}else{
    // 404
}

这意味着您不需要包含配置,因为它会在需要该请求的脚本之前自动包含这只是一个基本大纲并且不安全(并且可以很容易地被利用来显示系统文件内容)我强烈建议阅读有关如何使用 MVC 以及它们如何工作的内容,这将使您更好地了解按需加载文件和需要文件。

【讨论】:

  • 非常好,但我不明白如何使用你的表达方式。你能通过我的代码给我一个例子吗?
  • 为您的代码和演示添加了示例,说明如何将其设置为不需要在不同文件中定义的FS_ROOT,因此您的自动包括配置,因为大多数文件都需要访问它。 @Azzo
  • 在测试您的答案后,我得到了空白页。我做的一切都一样。
  • 空白页表示存在 PHP 错误并且您的显示错误已关闭使用 error_reporting(E_ALL)ini_set("display_errors", true) 顶部的 bootstrap.php 或您的 404 被触发并且什么都不做检查稍微调试一下路径是正确的,我确实说过这是一个粗略的轮廓。
  • @Azzo 你有没有得到这个工作我只是注意到你的 ajax URL 参数是错误的 url: siteurl+'content/test', 应该是 url: siteurl+'content/test.php', Ajax 需要完整的文件路径,除非你使用 .htaccess mod rewrite更改 php 文件路径的规则。
【解决方案2】:

如果文档文件路径需要是动态的,则需要使用数据库。据我了解,您正计划扩大项目,因此您需要一个规范化的数据库,以最大限度地减少服务器上编写的代码量并保持数据一致。

你需要:

  • filePaths 的父表
  • fileNames 的父表
  • akas 的父表
  • 文件夹的父表
  • 解决akas-fileNames-filePaths-folders关系的映射表。

我将展示来自MySQLi 的示例。

使用此代码,您可以在MySQL consolephpmyadmin 中创建表:

// Create parent tables
create table `fileNames` 
(
    `fileName` VARCHAR(70) NOT NULL,
    `description` VARCHAR(250) NULL,
    PRIMARY KEY(`fileName`)
) ENGINE=InnoDB;

create table `fileAkas` 
(
    `aka` VARCHAR(100) NOT NULL,
    `description` VARCHAR(250) NULL,
    PRIMARY KEY(`aka`)
)  ENGINE=InnoDB;

create table `filePaths` 
(
    `filePath` VARCHAR(250) NOT NULL,
    `description` VARCHAR(250) NULL,
    PRIMARY KEY(`filePath`)
)  ENGINE=InnoDB;

create table `folderNames` 
(
    `folderName` VARCHAR(250) NOT NULL,
    `description` VARCHAR(250) NULL,
    PRIMARY KEY(`folderName`)
)  ENGINE=InnoDB;

// Create mapping table
create table `fileNames_x_fileAkas_x_filePaths_x_folderNames`
(
    `aka` VARCHAR(100) NOT NULL,
    `fileName` VARCHAR(70) NOT NULL,
    `filePath` VARCHAR(250) NOT NULL,
    `folderName` VARCHAR(250) NOT NULL,
    PRIMARY KEY (`aka`, `fileName`, `filePath`, `folderName`),
    FOREIGN KEY (`aka`) REFERENCES `fileAkas` (`aka`) ON UPDATE CASCADE,
    FOREIGN KEY (`fileName`) REFERENCES `fileNames` (`fileName`) ON UPDATE CASCADE,
    FOREIGN KEY (`filePath`) REFERENCES `filePaths` (`filePath`) ON UPDATE CASCADE,
    FOREIGN KEY (`folderName`) REFERENCES `folderNames` (`folderName`) ON UPDATE CASCADE
) ENGINE=InnoDB;

虽然这段代码只是为了确保您没有制作MyISAM 表,因为MyISAM 没有关系约束:

ENGINE=InnoDB

现在制作一个PHP 程序来轻松添加/更改数据。将此作为单独的程序使用,仅在需要时将其上传到服务器:

<?php
    // Database connection
    $con = mysqli_connect("localhost","my_user","my_password","my_db");

    // Function helper
    function testIfAddedAndInsert($colName, $tableName, $value, $con)
    {
        $result = mysqli_query($con, "SELECT ".$colName." FROM ".$tableName." WHERE ".$colName."='".$value."'");
        if(mysqli_num_rows($result) == 0)
            mysqli_query($con, "INSERT INTO ".$tableName." (".$colName.") VALUES ('".$value."')");
    }

    // Call this to add new file
    function addNewFile($name, $aka, $path, $folderName, $con)
    {
         testIfAddedAndInsert('fileName', 'fileNames', $name, $con);
         testIfAddedAndInsert('fileAka', 'fileAkas', $aka, $con);
         testIfAddedAndInsert('filePath', 'filePaths', $path, $con);
         testIfAddedAndInsert('folderName', 'folderNames', $folderName, $con);
    }

    // Call this to change a file path
    function changeFilePath($aka, $path, $con)
    {
         testIfAddedAndInsert('filePath', 'filePaths', $path, $con));
         mysqli_query($con, "UPDATE `fileNames_x_fileAkas_x_filePaths_x_folderNames` SET `filePath`= '".$path."' WHERE `fileAka`='".$fileAka."' ");
    }

    // Call this to change all paths of all files that belong to a certain folder
    function changeFolderPath($folderName, $path, $con)
    {
         testIfAddedAndInsert('folderPath', 'folderPaths', $folderPath, $con))
             mysqli_query($con, "INSERT INTO `folderPaths` (`folderPath`) VALUES ('".$folderPath."')");
         mysqli_query($con, "UPDATE `fileNames_x_fileAkas_x_filePaths_x_folderNames` SET `filePath`= '".$path."' WHERE `folderName`='".$folderName."' ");
    }

    // ...

    // You can make as many different functions as you want

    // To populate/change the database example:

    addNewFile('config.php', 'conf_PHP_IndexPage', './../conf/', 'conf', $con);

    // or change all the paths of the items in the folder (not counting subfolder items)
    changeFolderPath('conf', './../../../', $con);

    // You could use FOR loops with arrays to enter/change big chunks at a time
?>

然后,在使用有效信息填充数据库后,将其添加到您的每个 main PHP 文件(包括其他文件)中:

<?php
    // Database connection
    $con = mysqli_connect("localhost","my_user","my_password","my_db");

    // Function returns path of file from database
    function returnPathToFile($fileAka, $con)
    {
        $result = mysqli_query($con, "SELECT fileName, filePath FROM fileNames_x_fileAkas_x_filePaths_x_folderNames WHERE fileAka='".$fileAka."'");
        if(mysqli_num_rows($result) > 0)
        {
            $row = mysqli_fetch_array($result);
            return $row[1].$row[0];
        }
        return '';
    }
?>

然后只需调用该函数即可获得结果:

<?php
    $include = returnPathToFile('configFileForTheMainPage', $con);
    include_once($include);
?>

如果文件路径发生任何更改,很容易更改它们的值,而不必再次打开文件(为此)。

【讨论】:

  • Downvote:你会从哪里获得$con 变量?还是一样的问题
  • 感谢投反对票,他可以将连接(一行代码)添加到每个php文件中。
  • 我将重新编辑以包含我从一开始就忘记包含的那条信息。谢谢。
  • 我想还是有同样的问题.. 根据你的代码,如果他需要更改任何 mysql 连接信息,他将不得不编辑他的所有文件..
  • 嗯,是的,这是真的,但由于 mysql 服务器的路径实际上只是(例如)localhost 并且没有涉及目录我猜想更改 mysql 服务器或 mysql 信息,如用户名等将是此方法的唯一缺点。我根本看不到任何更好的方法,因为他说他希望他的路径是可变的。我立即问自己,如果他这样做会怎样,如果他这样做会怎样。这就是所需的灵活性的来源。
【解决方案3】:

ROOT_PATH 定义没问题。您可以在定义之后包含路径,例如:

include ROOT_PATH;

【讨论】:

  • 你能更清楚地回答我吗?谢谢。
  • 我已经测试了你的代码,我得到了一些通知,但回显是有效的。 Notice: Use of undefined constant ROOT_PATH - assumed 'ROOT_PATH' in /home/****/public_html/subfolder/theme/themes/files/contents/test.php on line 1
  • 正如 panther 指出的那样,尽管路径正确,但定义不包含任何文件。所以你需要做的就是包含它。
  • 问题是这个,我正在尝试包含它。但我不能。
  • 您是否将define('ROOT_PATH', dirname(__DIR__) . '/inc/inc.php'); 保留在include ROOT_PATH; 之上?
【解决方案4】:

Test.php 位于内容文件夹中。 如果你想从includes文件夹中包含config.php,你必须相对做,所以你需要上一层。

include '../include/config.php';

发生这种情况是因为您使用 ajax 独立运行脚本,并且文件夹结构与 test.php 相关。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2021-11-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-08-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多