【问题标题】:spl_autoloader not loading any classesspl_autoloader 没有加载任何类
【发布时间】:2015-04-28 15:35:07
【问题描述】:

所以我已经开始使用命名空间并阅读了一些文档,但我似乎做错了什么。

首先是我的应用程序结构,它是这样构建的:

root
-dashboard(this is where i want to use the autoloader)
-index.php
--config(includes the autoloader)
--WePack(package)
---src(includes all my classes)

现在在 src 目录中,我包含以下类:

namespace WePack\src;
class Someclass(){

}

config.php的内容是:

<?php
// Start de sessie
ob_start();
session_start();

// Locate application path
define('ROOT', dirname(dirname(__FILE__)));
set_include_path(ROOT);
spl_autoload_extensions(".php"); // comma-separated list
spl_autoload_register();
echo get_include_path();

我在 index.php 中像这样使用它

require_once ('config/config.php');
use WePack\src;
$someclass = new Someclass;

这就是 echo get_include_path();返回:

/home/wepack/public_html/dashboard

我想这就是我想要的。但是类没有加载,也没有发生任何事情。我显然错过了一些东西,但我似乎无法弄清楚。你们可以看看它并向我解释为什么这不起作用吗?

【问题讨论】:

    标签: php namespaces autoloader spl-autoload-register spl-autoloader


    【解决方案1】:

    这里的问题是,您没有使用spl_autoload_register() 注册回调函数。看看官方docs

    为了更加灵活,您可以编写自己的类来注册和自动加载类,如下所示:

    class Autoloader
    {
        private $baseDir = null;
    
        private function __construct($baseDir = null)
        {
            if ($baseDir === null) {
                $this->baseDir = dirname(__FILE__);
            } else {
                $this->baseDir = rtrim($baseDir, '');
            }
        }
    
        public static function register($baseDir = null)
        {
            //create an instance of the autoloader
            $loader = new self($baseDir);
    
            //register your own autoloader, which is contained in this class
            spl_autoload_register(array($loader, 'autoload'));
    
            return $loader;
        }
    
        private function autoload($class)
        {
            if ($class[0] === '\\') {
                $class = substr($class, 1);
            }
    
            //if you want you can check if the autoloader is responsible for a specific namespace
            if (strpos($class, 'yourNameSpace') !== 0) {
                return;
            }
    
            //replace backslashes from the namespace with a normal directory separator
            $file = sprintf('%s/%s.php', $this->baseDir, str_replace('\\', DIRECTORY_SEPARATOR, $class));
    
            //include your file
            if (is_file($file)) {
                require_once($file);
            }
        }
    }
    

    在此之后,您将像这样注册您的自动加载器:

    Autoloader::register("/your/path/to/your/libraries");
    

    【讨论】:

    • 我删除了类文件中的命名空间并开始工作。但我想使用命名空间
    • 你传递给注册函数的究竟是什么?我将它与很多命名空间一起使用,但只有在第一个命名空间是我的情况下才加载类的附加条件。
    • Autoloader::register("/home/wealert/public_html/dashboard/WeAlert/src");并尝试使用 $template = new Template;和 $template = new WeAlert\src\Template;
    • 好的,尝试只使用Autoloader::register("/home/wealert/public_html/dashboard");,也许您想在自动加载方法中输出$file 变量以找出问题所在。
    • 它适用于“/home/wealert/public_html/dashboard/src”,但前提是我没有设置'namespace WeAlert\src;'在 Template.php 文件中
    【解决方案2】:

    这不是你的意思吗:

    spl_autoload_register(function( $class ) {
        include_once ROOT.'/classes/'.$class.'.php';
    });
    

    这样你就可以像这样调用一个类:

    $user = new User(); // And loads it from "ROOT"/classes/User.php
    

    【讨论】:

    • 那么在这种情况下,命名空间的用途是什么?以及如何使用具有相同加载器但文件结构不同的额外库
    • 由于我没有命名空间方面的经验,我无法就此给出完整的答案。但它应该仍然以同样的方式工作。我认为如果您使用use \User $user = new User(),它仍然可以工作。而“额外库”是指 PHPmailer 之类的东西吗?
    • hmm 不,因为 phpmailer 在命名空间之前就存在,所以它不使用它,更像是 Ivory 和 Geocoder-php 之类的库
    猜你喜欢
    • 2016-10-04
    • 1970-01-01
    • 2012-04-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-11-08
    • 1970-01-01
    • 2011-02-07
    相关资源
    最近更新 更多