1. 程式人生 > >Thinkphp5.0.18最高效的實現自定義類的自動載入方式

Thinkphp5.0.18最高效的實現自定義類的自動載入方式

今天看了下,tp5的原始碼。發現自定義類庫的載入方式 是有順序的。分別是按對映方式 psr4 psr0,其中最高效的,順序最前的當然是對映方式。

我貼出原始碼,大家看下。

private static function findFile($class)
    {
        //echo '<pre>';print_r(self::$map);
        // 類庫對映
        if (!empty(self::$map[$class])) {

            return self::$map[$class];
        }

        // 查詢 PSR-4
        $logicalPathPsr4 = strtr($class, '\\', DS) . EXT;
        //echo $logicalPathPsr4.'<br>';
        $first           = $class[0];
        //echo '<pre>';print_r(self::$prefixLengthsPsr4);
        if (isset(self::$prefixLengthsPsr4[$first])) {
            //echo $class.'<br>';
            foreach (self::$prefixLengthsPsr4[$first] as $prefix => $length) {
                if (0 === strpos($class, $prefix)) {
                    foreach (self::$prefixDirsPsr4[$prefix] as $dir) {
                        if (is_file($file = $dir . DS . substr($logicalPathPsr4, $length))) {
                            return $file;
                        }
                    }
                }
            }
        }

        // 查詢 PSR-4 fallback dirs
        foreach (self::$fallbackDirsPsr4 as $dir) {
            if (is_file($file = $dir . DS . $logicalPathPsr4)) {
                return $file;
            }
        }

        // 查詢 PSR-0
        if (false !== $pos = strrpos($class, '\\')) {
            // namespace class name
            $logicalPathPsr0 = substr($logicalPathPsr4, 0, $pos + 1)
            . strtr(substr($logicalPathPsr4, $pos + 1), '_', DS);
        } else {
            // PEAR-like class name
            $logicalPathPsr0 = strtr($class, '_', DS) . EXT;
        }

        if (isset(self::$prefixesPsr0[$first])) {
            foreach (self::$prefixesPsr0[$first] as $prefix => $dirs) {
                if (0 === strpos($class, $prefix)) {
                    foreach ($dirs as $dir) {
                        if (is_file($file = $dir . DS . $logicalPathPsr0)) {
                            return $file;
                        }
                    }
                }
            }
        }

        // 查詢 PSR-0 fallback dirs
        foreach (self::$fallbackDirsPsr0 as $dir) {
            if (is_file($file = $dir . DS . $logicalPathPsr0)) {
                return $file;
            }
        }

        // 找不到則設定對映為 false 並返回
        return self::$map[$class] = false;
    }

所以我們當然就採用對映方式啊。

第一步 在我們的應用模組新建一個用來存第三方類庫的目錄 如下圖



Mytool.php

<?php
/**
 * Created by PhpStorm.
 * User: Administrator
 * Date: 2018/4/15
 * Time: 22:35
 */
namespace Mytool;

class Mytool{
    public static function sh(){
        return 1000;
    }
}


這個是第三方的自己寫的類庫。。然後控制器呼叫

<?php
namespace app\index\controller;

use Mytool\Mytool;
use think\Loader;

class Index
{
    public function index()
    {
        //測試最高效的自動載入類庫的方式(新增類庫對映)
        $mapper = array('Mytool\\Mytool'=>APP_PATH.'index/Mytool/Mytool.php');
        Loader::addClassMap($mapper);
        return Mytool::sh();
    }
}

列印效果



完成。。。。。