【问题标题】:How to include() all PHP files from a directory?如何包含()目录中的所有 PHP 文件?
【发布时间】:2010-10-10 14:58:45
【问题描述】:

我可以在 PHP 中包含一个脚本目录吗?

即而不是:

include('classes/Class1.php');
include('classes/Class2.php');

有没有类似的东西:

include('classes/*');

似乎找不到为特定类包含大约 10 个子类的集合的好方法。

【问题讨论】:

  • 如果您使用的是 php 5,您可能希望使用 autoload

标签: php include


【解决方案1】:
foreach (glob("classes/*.php") as $filename)
{
    include $filename;
}

【讨论】:

  • 我认为使用 include() 会有一种更简洁的方式。但这会很好。谢谢大家。
  • 我会用配置文件构建一个合适的模块系统,但这只是因为我发现这比仅仅包含everything要灵活得多。 :-)
  • 注意,仅适用于包含当前目录中的文件。可以迭代 get_include_path(),但这很快就会变得乏味。
  • 这种方法在需要扩展基类的类时不好用:例如,如果 BaseClass 出现在数组 AFTER ExtendedClass 之后,它将不起作用!
  • @nalply get_include_path() 仍然无法自动确定加载顺序(基类可能在扩展类之后加载,导致错误)
【解决方案2】:

这是我在 PHP 5 中包含来自多个文件夹的大量类的方式。这只有在你有类时才有效。

/*Directories that contain classes*/
$classesDir = array (
    ROOT_DIR.'classes/',
    ROOT_DIR.'firephp/',
    ROOT_DIR.'includes/'
);
function __autoload($class_name) {
    global $classesDir;
    foreach ($classesDir as $directory) {
        if (file_exists($directory . $class_name . '.php')) {
            require_once ($directory . $class_name . '.php');
            return;
        }
    }
}

【讨论】:

  • 自动加载不相关,因为这个问题是关于将所有内容包含在一个目录中 - 通常这将在不同的目录中:例如在 BE 目录中定义的 DataClass 和在 BL 目录中定义的 BL.class.php。跨度>
  • 使用全局变量不是解决方案
  • 如果您需要自动加载而不是像此处显示的自定义自动加载解决方案,我建议您使用 composer (getcomposer.org)。
  • 这不包括目录中不包含类的任何文件
【解决方案3】:

我知道这是一篇较旧的帖子,但是...不要包含您的课程...而是使用 __autoload

function __autoload($class_name) {
    require_once('classes/'.$class_name.'.class.php');
}

$user = new User();

然后,每当你调用一个尚未包含的新类时,php 将自动触发 __autoload 并为你包含它

【讨论】:

  • 虽然在发布时这是一个可靠的答案,但从 PHP7.2.0 开始,此方法已被弃用,不应使用。相反,请使用spl_autoload_register
  • 如果目的是包含 CLASSES,这是一个更好的答案。
  • 这不包括目录中不包含类的任何文件
【解决方案4】:

这只是对 Karsten 代码的修改

function include_all_php($folder){
    foreach (glob("{$folder}/*.php") as $filename)
    {
        include $filename;
    }
}

include_all_php("my_classes");

【讨论】:

  • 这不会添加任何与接受的答案相关的内容。
  • 感谢这是唯一一个由于某种原因实际工作的代码。
【解决方案5】:

如何在 2017 年做到这一点:

spl_autoload_register( function ($class_name) {
    $CLASSES_DIR = __DIR__ . DIRECTORY_SEPARATOR . 'classes' . DIRECTORY_SEPARATOR;  // or whatever your directory is
    $file = $CLASSES_DIR . $class_name . '.php';
    if( file_exists( $file ) ) include $file;  // only include if file exists, otherwise we might enter some conflicts with other pieces of code which are also using the spl_autoload_register function
} );

此处由 PHP 文档推荐:Autoloading classes

【讨论】:

  • 这没有回答问题,因为autoload 只会在有人尝试创建尚未加载的类的对象时发挥作用。
  • 这里不包括目录中不包含类的任何文件,只包括那些包含使用的类的文件
【解决方案6】:

您可以使用set_include_path

set_include_path('classes/');

http://php.net/manual/en/function.set-include-path.php

【讨论】:

  • 它不会自动包含目录中的所有php文件,只是在使用include/require时可以省略classes/
  • 请解释如果这些文件中的任何一个不包含类,这将如何工作
【解决方案7】:

如果文件之间没有没有依赖关系...这是一个递归函数,用于在所有子目录中包含_一次所有 php 文件:

$paths = array();

function include_recursive( $path, $debug=false){
  foreach( glob( "$path/*") as $filename){        
    if( strpos( $filename, '.php') !== FALSE){ 
       # php files:
       include_once $filename;
       if( $debug) echo "<!-- included: $filename -->\n";
    } else { # dirs
       $paths[] = $filename; 
    }
  }
  # Time to process the dirs:
  for( $i=count($paths)-1; $i>0; $i--){
    $path = $paths[$i];
    unset( $paths[$i]);
    include_recursive( $path);
  }
}

include_recursive( "tree_to_include");
# or... to view debug in page source:
include_recursive( "tree_to_include", 'debug');

【讨论】:

    【解决方案8】:
    <?php
    //Loading all php files into of functions/ folder 
    
    $folder =   "./functions/"; 
    $files = glob($folder."*.php"); // return array files
    
     foreach($files as $phpFile){   
         require_once("$phpFile"); 
    }
    

    【讨论】:

    • 请为您的代码添加更多解释,特别是因为这个问题已经有很多赞成的答案
    【解决方案9】:

    如果您想在一个目录及其子目录中包含所有内容:

    $dir = "classes/";
    $dh  = opendir($dir);
    $dir_list = array($dir);
    while (false !== ($filename = readdir($dh))) {
        if($filename!="."&&$filename!=".."&&is_dir($dir.$filename))
            array_push($dir_list, $dir.$filename."/");
    }
    foreach ($dir_list as $dir) {
        foreach (glob($dir."*.php") as $filename)
            require_once $filename;
    }
    

    不要忘记它将使用字母顺序来包含您的文件。

    【讨论】:

    • "别忘了它会使用字母顺序" 错误...The entries are returned in the order in which they are stored by the filesystem. - php.net/manual/en/function.readdir.php
    • 如果文件相互依赖并且顺序与依赖不匹配,这可能不起作用
    【解决方案10】:

    如果您希望包含一堆类而不必一次定义每个类,您可以使用:

    $directories = array(
                'system/',
                'system/db/',
                'system/common/'
    );
    foreach ($directories as $directory) {
        foreach(glob($directory . "*.php") as $class) {
            include_once $class;
        }
    }
    

    这样你可以只在包含该类的 php 文件中定义该类,而不是 $thisclass = new thisclass(); 的完整列表

    至于它处理所有文件的能力如何?我不确定这是否会稍微降低速度。

    【讨论】:

      【解决方案11】:

      我建议您使用 readdir() 函数,然后循环并包含文件(请参阅该页面上的第一个示例)。

      【讨论】:

        【解决方案12】:

        尝试为此目的使用库。

        这是我构建的相同想法的简单实现。 它包括指定的目录和子目录文件。

        全部包含

        通过终端[cmd]安装

        composer install php_modules/include-all
        

        或者在package.json文件中设置为依赖

        {
          "require": {
            "php_modules/include-all": "^1.0.5"
          }
        }
        

        使用

        $includeAll = requires ('include-all');
        
        $includeAll->includeAll ('./path/to/directory');
        

        【讨论】:

          【解决方案13】:

          这是一个较晚的答案,指的是 PHP > 7.2 到 PHP 8。

          OP 没有在标题中询问课程,但从他的措辞中我们可以看出他想要包含课程。 (顺便说一句。此方法也适用于命名空间)。

          通过使用 require_once,您可以用一条毛巾杀死三只蚊子。

          • 首先,如果文件不存在,您会在日志文件中以错误消息的形式获得有意义的打击。这在调试时非常有用。(include 只会生成一个可能不那么详细的警告)
          • 您只包含包含类的文件
          • 避免两次加载一个类
          spl_autoload_register( function ($class_name) {
              require_once  '/var/www/homepage/classes/' . $class_name . '.class.php';
          } );
          
          

          这将适用于类

          new class_name;
          

          或命名空间。例如...

          use homepage\classes\class_name;
          

          【讨论】:

            【解决方案14】:

            不要编写函数()来包含目录中的文件。您可能会丢失变量范围,并且可能必须使用“全局”。只需循环文件即可。

            此外,当包含的文件的类名将扩展到另一个文件中定义的另一个类时,您可能会遇到困难 - 尚未包含。所以,小心点。

            【讨论】:

            • “失去变量范围”是什么意思?
            • 如果你要重用,你应该总是使用一个函数,或者只是为了让代码更“自我记录”。我认为“全球范围”的问题是一个红鲱鱼。每当您使用“全局范围”时,您都想认真考虑重写代码以避免它。
            猜你喜欢
            • 2021-04-18
            • 2021-01-05
            • 1970-01-01
            • 2011-09-08
            • 2011-03-04
            • 1970-01-01
            • 1970-01-01
            • 2011-08-05
            相关资源
            最近更新 更多