26

我正在做一个项目,我有以下文件结构:

index.php
|---lib
|--|lib|type|class_name.php
|--|lib|size|example_class.php

我想自动加载类,class_name 和 example_class(与 PHP 类命名相同),以便在 index.php 中类已经被实例化,所以我可以这样做:

$class_name->getPrivateParam('name');

我在网上看了看,但找不到正确的答案 - 谁能帮帮我?

编辑

感谢您的回复。让我扩展我的场景。我正在尝试编写一个 WordPress 插件,该插件可以放入项目中,并通过将类放入文件夹“功能”中添加附加功能,例如,在插件内部。永远不会有 1000 个课程,一推就可能 10 个?

我可以编写一个方法来遍历“lib”文件夹的文件夹结构,包括每个类,然后将其分配给一个变量(类名),但不认为这是一种非常有效的方法,但它也许这似乎是实现我需要的最佳方式?

4

8 回答 8

36

请,如果您需要自动加载类 - 使用 SPL 自动加载的命名空间和类名约定,它将节省您的重构时间。当然,您需要将每个类实例化为一个对象。谢谢你。

就像在这个线程中一样: 命名空间中的 PHP 自动加载

但是如果你想要一个复杂的解决方法,请看一下 Symfony 的自动加载类: https ://github.com/symfony/ClassLoader/blob/master/ClassLoader.php

或者像这样(我在我的一个项目中做到了):

<?
spl_autoload_register(function($className)
{
    $namespace=str_replace("\\","/",__NAMESPACE__);
    $className=str_replace("\\","/",$className);
    $class=CORE_PATH."/classes/".(empty($namespace)?"":$namespace."/")."{$className}.class.php";
    include_once($class);
});
?>

然后你可以像这样实例化你的类:

<?
$example=new NS1\NS2\ExampleClass($exampleConstructParam);
?>

这是你的课程(在 /NS1/NS2/ExampleClass.class.php 中找到):

<?
namespace NS1\NS2
{
    class Symbols extends \DB\Table
    {
        public function __construct($param)
        {
            echo "hello!";
        }
    }
}
?>
于 2013-07-23T09:27:23.230 回答
12

如果您可以访问命令行,则可以在 classMap 部分中使用 composer 进行尝试,如下所示:

{
    "autoload": {
        "classmap": ["yourpath/", "anotherpath/"]
    }
}

那么你有一个 wordpress 插件可以在 wordpress cli 中启用作曲家:http ://wordpress.org/plugins/composer/

于 2013-07-23T09:49:20.743 回答
4
function __autoload($class_name) {
   $class_name = strtolower($class_name);
   $path       = "{$class_name}.php";
   if (file_exists($path)) {
       require_once($path);
   } else {
       die("The file {$class_name}.php could not be found!");
   }
}

更新: __autoload()自 PHP 7.2 起已弃用

于 2014-12-14T17:48:37.943 回答
3

http://php.net/manual/de/function.spl-autoload-register.php

spl_autoload_register(function ($class) {
    @require_once('lib/type/' . $class . '.php');   
    @require_once('lib/size/' . $class . '.php');
});
于 2013-07-23T09:27:30.577 回答
3

我在这里有一个示例,用于自动加载和初始化。
基本上是一个更好的 spl_autoload_register 版本,因为它只在初始化类时尝试要求类文件。
在这里,它会自动获取类文件夹中的每个文件,需要这些文件并对其进行初始化。您所要做的就是将类命名为与文件相同。
索引.php

<?php
require_once __DIR__ . '/app/autoload.php';

$loader = new Loader(false);

User::dump(['hello' => 'test']);

自动加载.php

<?php
class Loader 
{

    public static $library;

    protected static $classPath = __DIR__ . "/classes/";

    protected static $interfacePath = __DIR__ . "/classes/interfaces/";

    public function __construct($requireInterface = true) 
    {
        if(!isset(static::$library)) {
            // Get all files inside the class folder
            foreach(array_map('basename', glob(static::$classPath . "*.php", GLOB_BRACE)) as $classExt) {
                // Make sure the class is not already declared
                if(!in_array($classExt, get_declared_classes())) {
                    // Get rid of php extension easily without pathinfo
                    $classNoExt = substr($classExt, 0, -4); 
                    $file = static::$path . $classExt;

                    if($requireInterface) {
                        // Get interface file
                        $interface = static::$interfacePath . $classExt;
                        // Check if interface file exists
                        if(!file_exists($interface)) {
                            // Throw exception
                            die("Unable to load interface file: " . $interface);
                        }

                        // Require interface
                        require_once $interface;
                        //Check if interface is set
                        if(!interface_exists("Interface" . $classNoExt)) {
                            // Throw exception
                            die("Unable to find interface: " . $interface);
                        }
                    }

                    // Require class
                    require_once $file;
                    // Check if class file exists
                    if(class_exists($classNoExt)) {
                        // Set class        // class.container.php
                        static::$library[$classNoExt] = new $classNoExt();
                    } else {
                        // Throw error
                        die("Unable to load class: " . $classNoExt);
                    }

                }
            }
        }
    }

    /*public function get($class) 
    {
        return (in_array($class, get_declared_classes()) ? static::$library[$class] : die("Class <b>{$class}</b> doesn't exist."));
    }*/
}

您可以通过一些编码轻松管理,也需要不同文件夹中的类。
希望这对你有一些用处。

于 2017-02-17T08:14:23.870 回答
0

您可以使用此自动加载器指定对命名空间友好的自动加载。

<?php
spl_autoload_register(function($className) {
    $file = __DIR__ . '\\' . $className . '.php';
    $file = str_replace('\\', DIRECTORY_SEPARATOR, $file);
    if (file_exists($file)) {
        include $file;
    }
});

确保正确指定类文件的位置。

资源

于 2019-06-03T02:04:55.000 回答
0
spl_autoload_register(function ($class_name) {
    $iterator = new DirectoryIterator(dirname(__FILE__));
    $files = $iterator->getPath()."/classes/".$class_name.".class.php";
    
    if (file_exists($files)) {
        include($files);
    } else {
       die("Warning:The file {$files}.class.php could not be found!");
    
    }
});
于 2021-03-08T00:29:32.893 回答
0

在一个文件中执行此操作并将其命名为(mr_load.php)之类的,这是你把所有的类

spl_autoload_register(function($class){ 
     $path = '\Applicaton/classes/';
    $extension = '.php';
    $fileName = $path.$class.$extension;
    include $_SERVER['DOCUMENT_ROOT'].$fileName;
})

;

  • 然后创建另一个文件并包含 mr_load.php;$load_class = new BusStop(); $load_class->方法()
于 2021-11-22T13:41:41.010 回答