ThinkPHP6源码研读

<?php
// +----------------------------------------------------------------------
// | ThinkPHP [ WE CAN DO IT JUST THINK ]
// +----------------------------------------------------------------------
// | Copyright (c) 2006-2019 http://thinkphp.cn All rights reserved.
// +----------------------------------------------------------------------
// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )
// +----------------------------------------------------------------------
// | Author: liu21st <liu21st@gmail.com>
// +----------------------------------------------------------------------

// [ 应用入口文件 ]
namespace think;

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

// 执行HTTP应用并响应
$http = (new App())->http;

$response = $http->run();

$response->send();

$http->end($response);

[1]第一步 引入

项目根目录/vendor/autoload.php

autoload文件如下

<?php

// autoload.php @generated by Composer

require_once __DIR__ . '/composer/autoload_real.php';

return ComposerAutoloaderInitb4bb23f5554b6a38d22fe61fc7fad9b3::getLoader();

[2] 由此可见,要引入autoload_real.php,然后执行 

 ComposerAutoloaderInitb4bb23f5554b6a38d22fe61fc7fad9b3类下的getLoader方法
    /**
     * @return ComposerAutoloadClassLoader
     */
    public static function getLoader()
    {
        if (null !== self::$loader) {
            return self::$loader;
        }
       
        require __DIR__ . '/platform_check.php';

        spl_autoload_register(array('ComposerAutoloaderInitb4bb23f5554b6a38d22fe61fc7fad9b3', 'loadClassLoader'), true, true);
        self::$loader = $loader = new ComposerAutoloadClassLoader();
        spl_autoload_unregister(array('ComposerAutoloaderInitb4bb23f5554b6a38d22fe61fc7fad9b3', 'loadClassLoader'));

        $useStaticLoader = PHP_VERSION_ID >= 50600 && !defined('HHVM_VERSION') && (!function_exists('zend_loader_file_encoded') || !zend_loader_file_encoded());
        if ($useStaticLoader) {
            require __DIR__ . '/autoload_static.php';

            call_user_func(ComposerAutoloadComposerStaticInitb4bb23f5554b6a38d22fe61fc7fad9b3::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 = ComposerAutoloadComposerStaticInitb4bb23f5554b6a38d22fe61fc7fad9b3::$files;
        } else {
            $includeFiles = require __DIR__ . '/autoload_files.php';
        }
        foreach ($includeFiles as $fileIdentifier => $file) {
            composerRequireb4bb23f5554b6a38d22fe61fc7fad9b3($fileIdentifier, $file);
        }

        return $loader;
    }

[3] 在getLoader方法 首先判断存在不存在$loader静态属性,如果不存在,[3-1]则去引入当前目录下的(项目根目录/vendor/composer)platform_check.php 文件
platform_check.php主要是为了检测当前运行PHP的版本。

<?php

// platform_check.php @generated by Composer

$issues = array();
 
if (!(PHP_VERSION_ID >= 70205)) {
    $issues[] = 'Your Composer dependencies require a PHP version ">= 7.2.5". You are running ' . PHP_VERSION . '.';
}

if ($issues) {
    if (!headers_sent()) {
        header('HTTP/1.1 500 Internal Server Error');
    }
    if (!ini_get('display_errors')) {
        if (PHP_SAPI === 'cli' || PHP_SAPI === 'phpdbg') {
            fwrite(STDERR, 'Composer detected issues in your platform:' . PHP_EOL.PHP_EOL . implode(PHP_EOL, $issues) . PHP_EOL.PHP_EOL);
        } elseif (!headers_sent()) {
            echo 'Composer detected issues in your platform:' . PHP_EOL.PHP_EOL . str_replace('You are running '.PHP_VERSION.'.', '', implode(PHP_EOL, $issues)) . PHP_EOL.PHP_EOL;
        }
    }
    trigger_error(
        'Composer detected issues in your platform: ' . implode(' ', $issues),
        E_USER_ERROR
    );
}

[3-2]如果检测通过,则去执行spl_autoload_register()自动加载函数


spl_autoload_register用法如下

eg 1

<?php

class Reaaa{

    public static function aaa($class=""){
        var_dump("类名为 :".$class);
        require_once __DIR__."/".$class.".php";
    }
}

spl_autoload_register(['Reaaa','aaa'],true,true);
$a = new Person();
echo "<br>";
var_dump($a->say());
string(19) "类名为 :Person"
string(18) "this is Person-say"

eg 2

<?php

  function abc($class=""){
    var_dump("类名为 :".$class);
    require_once __DIR__."/".$class.".php";
}
spl_autoload_register('abc',true,true);
$a = new Person();
echo "<br>";
var_dump($a->say());

 [3-2-1]spl_autoload_register函数调用当前类下的 loadClassLoader方法

    public static function loadClassLoader($class)
    {
        if ('ComposerAutoloadClassLoader' === $class) {
            require __DIR__ . '/ClassLoader.php';
        }
    }
loadClassLoader方法内容是 如果类名是 ComposerAutoloadClassLoader,则引入当前目录下的ClassLoader.php文件。

[3-3]此时还不会调用loadClassLoader方法。直到下一步

self::$loader = $loader = new CompoerAutoloadClassLoader();

此时直接实例化ClassLoader类。并且把其赋值给$loader变量,以及自身的静态私有$loader属性。这时候便会去执行上面的spl_autoload_register方法,实际上就是执行loadClassLoader方法,这是则会去引入当前目录下ClassLoader.php文件.

接下来去执行spl_autoload_unregister()方法。

[3-4]然后去判断php的版本,是否定义HHVM_VERSION,是否存在zend_load_file_encoded 把其结果赋值给$userStaticLoader变量

        $useStaticLoader = PHP_VERSION_ID >= 50600 && !defined('HHVM_VERSION') && (!function_exists('zend_loader_file_encoded') || !zend_loader_file_encoded());

 如果userStaticLoader变量为真,就是以上判断都通过,则去引入当前目录下的autoload_static.php文件

原文地址:https://www.cnblogs.com/aln0825/p/14782207.html