使用自定义自动加载器加载php核心类

时间:2012-11-20 01:22:48

标签: php autoloader spl-autoloader

我一直在论坛上搜索问题数据库,但无法找到面向我问题的解决方案。

我来找你,因为我怀疑我正在开发的自动加载器。

关键在于,当我尝试实例化我定义的类时,自动加载器工作正常,但是当我尝试实例化PHP内核的类时,会抛出以下错误。

例如,当我尝试这样做时:

$conn = new PDO (...);

然后抛出以下错误:

Fatal error: Class 'PDO' not found in ...

我注意到自动加载器正在尝试加载我已经为我的类定义路由的类。

我的问题是,如果我使用自定义自动加载器,如何加载一个PHP内核类?

我希望你能引导我解决这个问题。

事先谢谢你。

请原谅我没有放置自定义自动加载器的代码,我错过了。

代码与symfony中使用的代码相同,但经过修改和简化。

class ClassLoader {

private $prefixes = array ();
private $fallbackDirs = array ();
private $useIncludePath = false;

public function getPrefixes  () {
    return $this->prefixes;
}

public function getFallbackDirs  () {
    return $this->fallbackDirs;
}

public function addPrefixes ( array $prefixes ) {
    foreach  ( $prefixes as $prefix => $path )  {
        $this->addPrefix ( $prefix, $path );
    }
}

public function addPrefix ( $prefix, $paths ) {
    if  ( !$prefix ) {
        foreach ( ( array ) $paths as $path ) {
            $this->fallbackDirs [] = $path;
        }
        return;
    }
    if  ( isset ( $this->prefixes [ $prefix ] ) ) {
        $this->prefixes [ $prefix ] = array_merge ( $this->prefixes [ $prefix ], ( array ) $paths );
    } else {
        $this->prefixes [ $prefix ] = ( array ) $paths;
    }
}

public function setUseIncludePath ( $useIncludePath ) {
    $this->useIncludePath = $useIncludePath;
}

public function getUseIncludePath () {
    return $this->useIncludePath;
}

public function register ( $prepend = false ) {
    spl_autoload_register ( array ( $this, 'loadClass' ) , true, $prepend );
}

public function unregister () {
    spl_autoload_unregister ( array ( $this, 'loadClass' ) );
}

public function loadClass ( $class ) {

    if  ( $file = $this->findFile ( $class ) ) {
        require $file;
        return true;
    }
}

public function findFile ( $class ) {
    if ( '\\' == $class [ 0 ]  )  {
        $class = substr ( $class, 1 );
    }
    if  ( false !== $pos = strrpos ( $class, '\\' ) ) {
        // namespaced class name
        $classPath = str_replace ( '\\', DIRECTORY_SEPARATOR, substr ( $class, 0, $pos ) ) . DIRECTORY_SEPARATOR;
        $className = substr ( $class, $pos + 1 );
    } else {
        // PEAR-like class name
        $classPath = null;
        $className = $class;
    }
    $classPath .= str_replace ( '_', DIRECTORY_SEPARATOR, $className ) . '.php';
    foreach ( $this->prefixes as $prefix => $dirs ) {
        if ( 0 === strpos ( $class, $prefix ) ) {
            foreach ( $dirs as $dir ) {
                if ( file_exists ( $dir . DIRECTORY_SEPARATOR . $classPath ) ) {
                    return $dir . DIRECTORY_SEPARATOR . $classPath;
                }
            }
        }
    }
    foreach ( $this->fallbackDirs as $dir ) {
        if ( file_exists ( $dir . DIRECTORY_SEPARATOR . $classPath ) ) {
            return $dir . DIRECTORY_SEPARATOR . $classPath;
        }
    }
    if ( $this->useIncludePath && $file = stream_resolve_include_path ( $classPath ) ) {
        return $file;
    }
}

}

但是如果你想看到原始文件在这里

https://github.com/symfony/symfony/blob/master/src/Symfony/Component/ClassLoader/ClassLoader.php

2 个答案:

答案 0 :(得分:3)

好吧,我的朋友们。

我明白了为什么我没有加载PHP核心的PDO类。

根据我的研究,我做了两件事之一:

或者在类实例时添加反斜杠

$conn = new \PDO (...);

或者将PDO类放在use子句中。

use api\ecobd\nucleo\Conexion, PDO;

我评论说我选择了第二个,因为第一个没有用。

无论如何,谢谢你提供的帮助,很好地帮助我更好地定位我的搜索来解决我的问题:)

答案 1 :(得分:2)

检查PDO扩展是否已加载且PDO是否正常运行而未注册您的自动加载程序。自动加载器不应该影响核心类,也不需要自动加载器来加载核心类。