使用PHP的include语句遇到麻烦

时间:2019-09-26 23:11:13

标签: php apache lamp

我终生无法使用PHP的“ include”语句在除使用“ include”语句与该文件位于同一目录中的文件之外的任何其他文件上工作。当我尝试包含其他目录中的任何文件时,整个应用程序会中断,并且不会加载任何内容。

我把那个脚本转储进去,说:

  

/var/www/html/fooA/testClass.php

并尝试使用以下内容将其包括在内:

  

/var/www/html/different_than_fooA/include_testClass.php

,应用中断。但是,如果我包括以下内容:

  

/html/foo_1.php

在:

  

/html/foo_2.php

一切正常...

我保证这不是一个简单的语法问题,我尝试过以各种方式编写它,在前面使用斜杠,或者在整个目录和部分目录,IP地址前面不使用斜杠,甚至尝试从其他服务器加载。我的猜测是它与PHP或Apache的配置方式有关。在这个问题上几乎找不到任何东西,我可以在网上找到,任何建议都很好。

<?php
    // THIS FILE IS TEST/TEST02.php

    require 'TEST01.php';
    $V = new X();
    $V->Z();
?>

2 个答案:

答案 0 :(得分:1)

您始终可以使用PHP的魔术常数,这样可以确保它会为您找到正确的路径。

/* lets say we have a folder structure like below
 *
 * - FolderA
 *  -- fileA.php
 * - FolderB
 *  -- fileB.php
 */

 // We require fileA.php in fileB.php, here is how we can do it

 require __DIR__.'/../FolderA/fileA.php';

这是文档的链接。 https://www.php.net/manual/en/language.constants.predefined.php

答案 1 :(得分:1)

默认情况下,PHP将include_path设置如下:

在* nix系统上

include_path=".:/php/includes"

在寡妇系统上

include_path=".;c:\php\includes"

您可以并且应该覆盖这些默认值以适合您的环境,因为不太可能将所有相关文件放在这些位置。

  

使用。在包含路径中允许相对包含   当前目录。但是,显式使用会更有效   包括“ ./file”,而不是让PHP始终检查当前目录   每个包含在内。

要覆盖默认位置,请使用set_include_path("/path/to/includes/")等,然后允许通过简单的调用包含如下文件:

set_include_path("/path/to/includes/");
include 'class.foobar.php';
require 'functions.php'; // etc

如果您需要加载类文件,一种替代方法是使用等效的__autoload方法并编写您自己的回调来处理文件加载。最初的__autoload方法已被弃用,但存在改进的spl_autoload类来简化此方法。

以下引用ALIASED_SITE_ROOTROOT_PATH是我系统上全局定义的常量,它们指向特定目录,因此与您无关,如果您决定采用这种加载方式,则需要进行编辑课程。

More info on "spl_autoload_register"

function autoloader( $classname=false ){

    $included=get_included_files();
    $classname=rtrim( $classname, '.php' );

    $dirs = array(
        '/path/to/includes/',
        ALIASED_SITE_ROOT . '/inc/',
        ALIASED_SITE_ROOT . '/inc/forms/',
        ALIASED_SITE_ROOT . '/inc/lib/',
        ROOT_PATH . '/inc/',
        ROOT_PATH . '/'
    );
    /* add other locations to the above array */
    foreach( $dirs as $dir ) {
        $fullpath = $dir . $classname . '.php';

        if ( file_exists( $fullpath ) ) {
            if( !in_array( $fullpath, $included ) ) {
                require_once( $fullpath );
                clearstatcache();
                break;
            }
        }
    }
    set_include_path( $dirs[ 0 ] );
}
spl_autoload_register( 'autoloader' );

在需要加载类的情况下,在公共包含文件中注册了以上内容,当您需要使用该文件时,就不再需要require '/path/to/includes/foobar.php';

$foo=new foobar(); // no need to use `require` or `include` as it has been autoloaded

因此,以上内容适用于类-如果您采用这种方法,那么一致的命名策略将极大地帮助您!例如,我倾向于将所有类放在上面显示为ALIASED_SITE_ROOT . '/inc/'的位置,并使用class.foobar.php的命名约定,以便在自动加载功能中使用

$fullpath = $dir . $classname . '.php';

实际上是

$fullpath = $dir . 'class.' . $classname . '.php';

因此,类名称必须与$classname给出的名称匹配,例如:

class foobar{
    public function __construct(){
       /* etc */
    }
}