Composer 를 분석 하여 자동 로드 원 리 를 실현 하 다.

9334 단어 Composer자동 로드
1.입구 파일
(/public/index.php)에 autoload.php 가 도입 되 었 습 니 다.

require __DIR__.'/../vendor/autoload.php';
2.  autoload.php

require_once __DIR__ . '/composer/autoload_real.php';
return ComposerAutoloaderInit1215780529014c2b50a6fca7ce889273::getLoader();
3. autoload_real.php

<?php
// autoload_real.php @generated by Composer
class ComposerAutoloaderInit1215780529014c2b50a6fca7ce889273{
    private static $loader;
    public static function loadClassLoader($class){
        if ('Composer\Autoload\ClassLoader' === $class) {
            require __DIR__ . '/ClassLoader.php';
        }
    }
    public static function getLoader(){
        if (null !== self::$loader) {
            return self::$loader;
        }
        spl_autoload_register(array('ComposerAutoloaderInit1215780529014c2b50a6fca7ce889273', 'loadClassLoader'), true, true);
        self::$loader = $loader = new \Composer\Autoload\ClassLoader();
        spl_autoload_unregister(array('ComposerAutoloaderInit1215780529014c2b50a6fca7ce889273', 'loadClassLoader'));
        $useStaticLoader = PHP_VERSION_ID >= 50600 && !defined('HHVM_VERSION') && (!function_exists('zend_loader_file_encoded') || !zend_loader_file_encoded());
        if ($useStaticLoader) {
            require_once __DIR__ . '/autoload_static.php';
 
            call_user_func(\Composer\Autoload\ComposerStaticInit1215780529014c2b50a6fca7ce889273::getInitializer($loader));
        } else {
            $map = require __DIR__ . '/autoload_namespaces.php';
            foreach ($map as $namespace => $path) {
                $loader->set($namespace, $path);
            }
            $map = require __DIR__ . '/autoload_psr4.php';
            foreach ($map as $namespace => $path) {
                $loader->setPsr4($namespace, $path);
            }
            $classMap = require __DIR__ . '/autoload_classmap.php';
            if ($classMap) {
                $loader->addClassMap($classMap);
            }
        }
        $loader->register(true);
        if ($useStaticLoader) {
            $includeFiles = Composer\Autoload\ComposerStaticInit1215780529014c2b50a6fca7ce889273::$files;
        } else {
            $includeFiles = require __DIR__ . '/autoload_files.php';
        }
        foreach ($includeFiles as $fileIdentifier => $file) {
            composerRequire1215780529014c2b50a6fca7ce889273($fileIdentifier, $file);
        }
 
        return $loader;
    }
}
function composerRequire1215780529014c2b50a6fca7ce889273($fileIdentifier, $file){
    if (empty($GLOBALS['__composer_autoload_files'][$fileIdentifier])) {
        require $file;
 
        $GLOBALS['__composer_autoload_files'][$fileIdentifier] = true;
    }
}
 
이 단락 은 composer 자동 로드 의 중점 임 을 알 수 있 습 니 다.우선 autoload.php 에서 호출 합 니 다.
Composer Autoloader Init 1215780529014 c2b50a6fca7ce 889273:getLoader()방법,getLoader()는 현재 loader 가 null 인지 아 닌 지 를 먼저 판단 하고 null 이 아니면 바로 돌아 갑 니 다.그렇지 않 으 면 ClassLoader 류 가 loader 에 할당 하 는 값 이 null 인지 초기 화 합 니 다.null 이 아니면 바로 돌아 갑 니 다.그렇지 않 으 면 ClassLoader 류 가 loader 에 할당 하 는 값 을 초기 화 합 니 다.이어서 autoloadnamespaces.php、autoload_psr4.php、autoload_classmap.php 파일 의 내용 을$loader 에 대응 하 는 배열 에 추가 한 다음 loadClass 함 수 를 등록 하고 autoloadfiles.php 의 모든 경로 에 표 시 된 파일 이 포함 되 어 있 습 니 다.new 클래스 를 찾 지 못 했 을 때 관련 클래스 를 찾 지 못 하면 이 loadClass 함 수 를 촉발 합 니 다.loadClass()에서 findFile()을 호출 하여 해당 파일 을 찾 으 면 해당 파일 을 되 돌려 줍 니 다.그리고 loadClass 에서 includeFile()방법 으로 이 파일 을 include 로 호출 합 니 다.그렇지 않 으 면 findFile 이 false 로 돌아 가 자동 로 딩 이 완 료 됩 니 다.
4.  findFile ()

public function findFile($class){
    // class map lookup
    if (isset($this->classMap[$class])) {
        return $this->classMap[$class];
    }
    if ($this->classMapAuthoritative || isset($this->missingClasses[$class])) {
        return false;
    }
    if (null !== $this->apcuPrefix) {
        $file = apcu_fetch($this->apcuPrefix.$class, $hit);
        if ($hit) {
            return $file;
        }
    }
    $file = $this->findFileWithExtension($class, '.php');
    // Search for Hack files if we are running on HHVM
    if (false === $file && defined('HHVM_VERSION')) {
        $file = $this->findFileWithExtension($class, '.hh');
    }
    if (null !== $this->apcuPrefix) {
        apcu_add($this->apcuPrefix.$class, $file);
    }
    if (false === $file) {
        // Remember that this class does not exist.
        $this->missingClasses[$class] = true;
    }
    return $file;
}

private function findFileWithExtension($class, $ext){
    // PSR-4 lookup
    $logicalPathPsr4 = strtr($class, '\\', DIRECTORY_SEPARATOR) . $ext;

    $first = $class[0];
    if (isset($this->prefixLengthsPsr4[$first])) {
        $subPath = $class;
        while (false !== $lastPos = strrpos($subPath, '\\')) {
            $subPath = substr($subPath, 0, $lastPos);
            $search = $subPath.'\\';
            if (isset($this->prefixDirsPsr4[$search])) {
                $pathEnd = DIRECTORY_SEPARATOR . substr($logicalPathPsr4, $lastPos + 1);
                foreach ($this->prefixDirsPsr4[$search] as $dir) {
                    if (file_exists($file = $dir . $pathEnd)) {
                        return $file;
                    }
                }
            }
        }
    }
    // PSR-4 fallback dirs
    foreach ($this->fallbackDirsPsr4 as $dir) {
        if (file_exists($file = $dir . DIRECTORY_SEPARATOR . $logicalPathPsr4)) {
            return $file;
        }
    }

    // PSR-0 lookup
    if (false !== $pos = strrpos($class, '\\')) {
        // namespaced class name
        $logicalPathPsr0 = substr($logicalPathPsr4, 0, $pos + 1)
        . strtr(substr($logicalPathPsr4, $pos + 1), '_', DIRECTORY_SEPARATOR);
    } else {
        // PEAR-like class name
        $logicalPathPsr0 = strtr($class, '_', DIRECTORY_SEPARATOR) . $ext;
    }

    if (isset($this->prefixesPsr0[$first])) {
        foreach ($this->prefixesPsr0[$first] as $prefix => $dirs) {
            if (0 === strpos($class, $prefix)) {
                foreach ($dirs as $dir) {
                    if (file_exists($file = $dir . DIRECTORY_SEPARATOR . $logicalPathPsr0)) {
                        return $file;
                    }
                }
            }
        }
    }

    // PSR-0 fallback dirs
    foreach ($this->fallbackDirsPsr0 as $dir) {
        if (file_exists($file = $dir . DIRECTORY_SEPARATOR . $logicalPathPsr0)) {
            return $file;
        }
    }
    // PSR-0 include paths.
    if ($this->useIncludePath && $file = stream_resolve_include_path($logicalPathPsr0)) {
        return $file;
    }
    return false;
}
findFile()함 수 는 classMap 에서 먼저 찾 습 니 다.찾 지 못 하면 apcu 캐 시 에서 찾 습 니 다.찾 지 못 하면 findFileWithExtension()함수 로 찾 습 니 다.찾 으 면 apcu 캐 시 에 이 파일 을 추가 합 니 다.찾 을 수 없 으 면 missing Classes 배열 에 표 시 를 설정 합 니 다.이 종 류 는 find FileWith Extension()방법 을 찾 을 수 없습니다.이전에 loader->set(loader−>set(namespace,path)와 loader->setPsr 4(namespace,namespace,path)방법 으로 설정 한 정보 에 따라 클래스 파일 의 경로 정 보 를 찾 습 니 다.
5. spl_autoload_register 와 splautoload_등록 되 지 않 은 함수
1. spl_autoload_register 함수
1.spl_autoload_register―주어진 함 수 를 로 등록 합 니 다.autoload 의 실현,
bool spl_autoload_register([callable autoloadfunction[,boolautoloadfunction[,boolthrow = true [, bool $prepend = false ]]])
2.prepend
트 루 라면,splautoload_register()는 대기 열 끝 이 아 닌 함수 가 추 가 됩 니 다.
3.프로그램 에서 autoload()함수 가 구현 되 었 다 면 autoload()대기 열 에 명시 적 으로 등록 해 야 합 니 다.spl 때문에autoload_register()함 수 는 Zend Engine 의 를autoload()함수 가 spl 로 대 체 됩 니 다.autoload()또는 splautoload_call ()
예:
function __autoload($name) { require 'class/'.$name.'.php'; echo '1'; } function autoload_test($name) { echo '2'; } spl_autoload_register('autoload_test'); spl_autoload_register('__autoload'); $ca=new Ca();
2. spl_autoload_등록 되 지 않 은 함수
spl_autoload_등록 한 autoload()함 수 를 취소 합 니 다.이 함수 대기 열 이 활성화 상태 에 있 고 주어진 함수 가 로그아웃 한 후에 이 대기 열 이 비어 있 으 면 이 함수 대기 열 은 무효 가 됩 니 다.이 함수 가 로그아웃 되면 자동 으로 함수 대기 열 을 불 러 올 수 없습니다.autoload 함수 가 있어 도 자동 으로 활성화 되 지 않 습 니 다.
bool spl_autoload_unregister ( mixed $autoload_function )
이상 은 Composer 가 자동 로드 원 리 를 실현 하 는 상세 한 내용 을 분석 하 는 것 입 니 다.Composer 가 자동 로드 원 리 를 실현 하 는 데 관 한 자 료 는 저희 의 다른 관련 글 을 주목 하 세 요!

좋은 웹페이지 즐겨찾기