function findFile(string $className): ?string
    {
        if ($className[0] === '\\') {
            $className = substr($className, 1);
        }

        // check class map
        if (isset($this->classMap[$className])) {
            return $this->classMap[$className];
        }

        if ($this->usePrefixes) {
            // determine index
            $firstNsSep = strpos($className, '\\');
            if ($firstNsSep === false) {
                $isPsr4Compatible = false;
                $index = $className[0];
                $firstNsSep = null;
            } else {
                $isPsr4Compatible = true;
                $index = substr($className, 0, $firstNsSep);
            }

            // cache PSR-0 subpath
            $subpathPsr0 = null;

            // scan prefixes
            if (
                isset($this->prefixes[$index])
                || ($isPsr4Compatible && isset($this->prefixes[$index = $className[0]]))
            ) {
                foreach ($this->prefixes[$index] as $prefix) {
                    // 0 => type, 1 => prefix, 2 => prefix_len, 3 => paths
                    if (
                        ($isPsr4 = ($prefix[0] === static::PSR4)) && !$isPsr4Compatible
                        || strncmp($prefix[1], $className, $prefix[2]) !== 0
                    ) {
                        // no match or we are locating a PSR-0 class but the prefix is PSR-4
                        continue;
                    }

                    // compose subpath
                    if ($isPsr4) {
                        // PSR-4 subpath must be built for different prefix lengths
                        $subpath = $this->buildPsr4Subpath($className, $prefix[2]);
                    } else {
                        // PSR-0 subpath contains the entire namespace so it needs to be built only once
                        if ($subpathPsr0 === null) {
                            $subpathPsr0 = $this->buildPsr0Subpath($className, $firstNsSep);
                        }

                        $subpath = $subpathPsr0;
                    }

                    // iterate over possible paths
                    foreach ($prefix[3] as $path) {
                        if (($filePath = $this->findFileWithKnownSuffix($path . $subpath)) !== null) {
                            return $filePath;
                        }
                    }
                }
            }

            // scan fallbacks
            if (isset($this->fallbacks[static::PSR0])) {
                $subpath = $subpathPsr0 ?: $this->buildPsr0Subpath($className, $firstNsSep);

                foreach ($this->fallbacks[static::PSR0] as $fallback) {
                    if (($filePath = $this->findFileWithKnownSuffix($fallback . $subpath)) !== null) {
                        return $filePath;
                    }
                }
            }

            if (isset($this->fallbacks[static::PSR4])) {
                $subpath = $this->buildPsr4Subpath($className, 0);

                foreach ($this->fallbacks[static::PSR4] as $fallback) {
                    if (($filePath = $this->findFileWithKnownSuffix($fallback . $subpath)) !== null) {
                        return $filePath;
                    }
                }
            }

            // cache failed lookup
            $this->classMap[$className] = false;
        }

        return null;
    }
function findFile(string $className): ?string
    {
        if ($className[0] === '\\') {
            $className = substr($className, 1);
        }

        // check class map
        if (isset($this->classMap[$className])) {
            return $this->classMap[$className];
        }

        if ($this->usePrefixes) {
            // determine index
            $firstNsSep = strpos($className, '\\');
            if ($firstNsSep === false) {
                $isPsr4Compatible = false;
                $index = $className[0];
                $firstNsSep = null;
            } else {
                $isPsr4Compatible = true;
                $index = substr($className, 0, $firstNsSep);
            }

            // cache PSR-0 subpath
            $subpathPsr0 = null;

            // scan prefixes
            if (
                isset($this->prefixes[$index])
                || ($isPsr4Compatible && isset($this->prefixes[$index = $className[0]]))
            ) {
                foreach ($this->prefixes[$index] as $prefix) {
                    // 0 => type, 1 => prefix, 2 => prefix_len, 3 => paths
                    if (
                        ($isPsr4 = ($prefix[0] === static::PSR4)) && !$isPsr4Compatible
                        || strncmp($prefix[1], $className, $prefix[2]) !== 0
                    ) {
                        // no match or we are locating a PSR-0 class but the prefix is PSR-4
                        continue;
                    }

                    // compose subpath
                    if ($isPsr4) {
                        // PSR-4 subpath must be built for different prefix lengths
                        $subpath = $this->buildPsr4Subpath($className, $prefix[2]);
                    } else {
                        // PSR-0 subpath contains the entire namespace so it needs to be built only once
                        if ($subpathPsr0 === null) {
                            $subpathPsr0 = $this->buildPsr0Subpath($className, $firstNsSep);
                        }

                        $subpath = $subpathPsr0;
                    }

                    // iterate over possible paths
                    foreach ($prefix[3] as $path) {
                        if (($filePath = $this->findFileWithKnownSuffix($path . $subpath)) !== null) {
                            return $filePath;
                        }
                    }
                }
            }

            // scan fallbacks
            if (isset($this->fallbacks[static::PSR0])) {
                $subpath = $subpathPsr0 ?: $this->buildPsr0Subpath($className, $firstNsSep);

                foreach ($this->fallbacks[static::PSR0] as $fallback) {
                    if (($filePath = $this->findFileWithKnownSuffix($fallback . $subpath)) !== null) {
                        return $filePath;
                    }
                }
            }

            if (isset($this->fallbacks[static::PSR4])) {
                $subpath = $this->buildPsr4Subpath($className, 0);

                foreach ($this->fallbacks[static::PSR4] as $fallback) {
                    if (($filePath = $this->findFileWithKnownSuffix($fallback . $subpath)) !== null) {
                        return $filePath;
                    }
                }
            }

            // cache failed lookup
            $this->classMap[$className] = false;
        }

        return null;
    }
function findFile ( string $ className ) : ? string { if ( $ className [ 0 ] === '\\' ) { $ className = substr ( $ className , 1 ) ; } // check class map if ( isset ( $ this -> classMap [ $ className ] ) ) { return $ this -> classMap [ $ className ] ; } if ( $ this -> usePrefixes ) { // determine index $ firstNsSep = strpos ( $ className , '\\' ) ; if ( $ firstNsSep === false ) { $ isPsr4Compatible = false ; $ index = $ className [ 0 ] ; $ firstNsSep = null ; } else { $ isPsr4Compatible = true ; $ index = substr ( $ className , 0 , $ firstNsSep ) ; } // cache PSR-0 subpath $ subpathPsr0 = null ; // scan prefixes if ( isset ( $ this -> prefixes [ $ index ] ) || ( $ isPsr4Compatible && isset ( $ this -> prefixes [ $ index = $ className [ 0 ] ] ) ) ) { foreach ( $ this -> prefixes [ $ index ] as $ prefix ) { // 0 => type, 1 => prefix, 2 => prefix_len, 3 => paths if ( ( $ isPsr4 = ( $ prefix [ 0 ] === static :: PSR4 ) ) && ! $ isPsr4Compatible || strncmp ( $ prefix [ 1 ] , $ className , $ prefix [ 2 ] ) !== 0 ) { // no match or we are locating a PSR-0 class but the prefix is PSR-4 continue ; } // compose subpath if ( $ isPsr4 ) { // PSR-4 subpath must be built for different prefix lengths $ subpath = $ this -> buildPsr4Subpath ( $ className , $ prefix [ 2 ] ) ; } else { // PSR-0 subpath contains the entire namespace so it needs to be built only once if ( $ subpathPsr0 === null ) { $ subpathPsr0 = $ this -> buildPsr0Subpath ( $ className , $ firstNsSep ) ; } $ subpath = $ subpathPsr0 ; } // iterate over possible paths foreach ( $ prefix [ 3 ] as $ path ) { if ( ( $ filePath = $ this -> findFileWithKnownSuffix ( $ path . $ subpath ) ) !== null ) { return $ filePath ; } } } } // scan fallbacks if ( isset ( $ this -> fallbacks [ static :: PSR0 ] ) ) { $ subpath = $ subpathPsr0 ? : $ this -> buildPsr0Subpath ( $ className , $ firstNsSep ) ; foreach ( $ this -> fallbacks [ static :: PSR0 ] as $ fallback ) { if ( ( $ filePath = $ this -> findFileWithKnownSuffix ( $ fallback . $ subpath ) ) !== null ) { return $ filePath ; } } } if ( isset ( $ this -> fallbacks [ static :: PSR4 ] ) ) { $ subpath = $ this -> buildPsr4Subpath ( $ className , 0 ) ; foreach ( $ this -> fallbacks [ static :: PSR4 ] as $ fallback ) { if ( ( $ filePath = $ this -> findFileWithKnownSuffix ( $ fallback . $ subpath ) ) !== null ) { return $ filePath ; } } } // cache failed lookup $ this -> classMap [ $ className ] = false ; } return null ; }
Find a file for the given class name

Returns NULL on failure.
Find a file for the given class name