• Laravel Autoloader模块分析


    首先是中文注释:

    <?php namespace Laravel;
    
    class Autoloader {
    
    	/**
    	 * 类名到文件名得映射
    	 *
    	 * @var array
    	 */
    	public static $mappings = array();
    
    	/**
         * PSR-0命名转换目录
    	 *
    	 * @var array
    	 */
    	public static $directories = array();
    
    	/**
    	 * 命名空间和目录的映射
    	 *
    	 * @var array
    	 */
    	public static $namespaces = array();
    
    	/**
    	 * 下划线类库和目录映射
    	 *
    	 * @var array
    	 */
    	public static $underscored = array();
    
    	/**
    	 * 自动加载类的别名
    	 *
    	 * @var array
    	 */
    	public static $aliases = array();
    
    	/**
    	 * Load the file corresponding to a given class.
    	 *
    	 * This method is registered in the bootstrap file as an SPL auto-loader.
    	 *
    	 * @param  string  $class
    	 * @return void
    	 */
    	public static function load($class)
    	{
    		// 尝试类是否有别名
    		if (isset(static::$aliases[$class]))
    		{
    			return class_alias(static::$aliases[$class], $class);
    		}
    
    		// 查找映射
    		elseif (isset(static::$mappings[$class]))
    		{
    			require static::$mappings[$class];
    
    			return;
    		}
    
    		// 加载这个新的类
    		foreach (static::$namespaces as $namespace => $directory)
    		{
                # 支持函数 是否命名空间开头 在helpers.php中
    			if (starts_with($class, $namespace))
    			{
    				return static::load_namespaced($class, $namespace, $directory);
    			}
    		}
    
    		static::load_psr($class);
    	}
    
    	/**
    	 * 从给定的目录加载命名空间
    	 *
    	 * @param  string  $class
    	 * @param  string  $namespace
    	 * @param  string  $directory
    	 * @return void
    	 */
    	protected static function load_namespaced($class, $namespace, $directory)
    	{
    		return static::load_psr(substr($class, strlen($namespace)), $directory);
    	}
    
    	/**
    	 * 使用PSR-0标准来试图解析一个类
    	 *
    	 * @param  string  $class
    	 * @param  string  $directory
    	 * @return void
    	 */
    	protected static function load_psr($class, $directory = null)
    	{
            // 用PSR-0来解析类 使之变成路径字符串
    		$file = str_replace(array('\\', '_'), '/', $class);
    
    		$directories = $directory ?: static::$directories; // 获得类路径
    
    		$lower = strtolower($file); # 默认全部小写
    
    		// 尝试解析
    		foreach ((array) $directories as $directory)
    		{
    			if (file_exists($path = $directory.$lower.EXT))
    			{
    				return require $path;
    			}
    			elseif (file_exists($path = $directory.$file.EXT))
    			{
    				return require $path;
    			}
    		}
    	}
    
    	/**
    	 * 注册一个数组 包含类路径映射
    	 *
    	 * @param  array  $mappings
    	 * @return void
    	 */
    	public static function map($mappings)
    	{
    		static::$mappings = array_merge(static::$mappings, $mappings);
    	}
    
    	/**
    	 * 注册类的别名
    	 *
    	 * @param  string  $class
    	 * @param  string  $alias
    	 * @return void
    	 */
    	public static function alias($class, $alias)
    	{
    		static::$aliases[$alias] = $class;
    	}
    
    	/**
    	 * 注册目录
    	 *
    	 * @param  string|array  $directory
    	 * @return void
    	 */
    	public static function directories($directory)
    	{
    		$directories = static::format($directory);
    
    		static::$directories = array_unique(array_merge(static::$directories, $directories));
    	}
    
    	/**
    	 * 映射命名空间和目录
    	 *
    	 * @param  array   $mappings
    	 * @param  string  $append
    	 * @return void
    	 */
    	public static function namespaces($mappings, $append = '\\')
    	{
    		$mappings = static::format_mappings($mappings, $append);
    
    		static::$namespaces = array_merge($mappings, static::$namespaces); # 合并之后: (array "命名空间", array "命名空间","路径")
    	}
    
    	/**
    	 * 注册下划线命名空间
    	 *
    	 * @param  array  $mappings
    	 * @return void
    	 */
    	public static function underscored($mappings)
    	{
    		static::namespaces($mappings, '_'); # 下划线风格
    	}
    
    	/**
    	 * 格式目录映射
    	 *
    	 * @param  array   $mappings
    	 * @param  string  $append
    	 * @return array
    	 */
    	protected static function format_mappings($mappings, $append)
    	{
    		foreach ($mappings as $namespace => $directory)
    		{
    			# 清理命名空间
    			$namespace = trim($namespace, $append).$append;
    
    			unset(static::$namespaces[$namespace]); # 去除之前的 如果存在的话
    
    			$namespaces[$namespace] = head(static::format($directory)); # 一个命名空间只能对应一个目录
    		}
    
    		return $namespaces;
    	}
    
    	/**
    	 * 格式化一个目录数组
    	 *
    	 * @param  array  $directories
    	 * @return array
    	 */
    	protected static function format($directories)
    	{
    		return array_map(function($directory)
    		{
    			return rtrim($directory, DS).DS;# 清理目录
    		
    		}, (array) $directories); // 用map遍历目录数组
    	}
    
    }
    

    改类被自动装在到spl中:

    spl_autoload_register(array('Laravel\\Autoloader', 'load')); # spl_autoload_register array 命名空间,具体方法
    

    注册好之后,就载入一些预先设置好的配置:

    定义系统root

    Autoloader::namespaces(array('Laravel' => path('sys'))); # 定义Laravel系统根目录映射
    

    然后是默认使用的ORM框架

    # 定义EloquentORM框架
    Autoloader::map(array(
    	'Laravel\\Database\\Eloquent\\Relationships\\Belongs_To' 
                        => path('sys').'database/eloquent/relationships/belongs_to'.EXT,
    	'Laravel\\Database\\Eloquent\\Relationships\\Has_Many' 
                        => path('sys').'database/eloquent/relationships/has_many'.EXT,
    	'Laravel\\Database\\Eloquent\\Relationships\\Has_Many_And_Belongs_To' 
                        => path('sys').'database/eloquent/relationships/has_many_and_belongs_to'.EXT,
    	'Laravel\\Database\\Eloquent\\Relationships\\Has_One' 
                        => path('sys').'database/eloquent/relationships/has_one'.EXT,
    	'Laravel\\Database\\Eloquent\\Relationships\\Has_One_Or_Many' 
                        => path('sys').'database/eloquent/relationships/has_one_or_many'.EXT,
    ));
    

    随后是Symfony的HTTP组件和Console组件

    # Symfony组件加载
    Autoloader::namespaces(array(
    	'Symfony\Component\Console' 
                        => path('sys').'vendor/Symfony/Component/Console',
    	'Symfony\Component\HttpFoundation'
                        => path('sys').'vendor/Symfony/Component/HttpFoundation',
    ));
    

    当然,不要忘记了application.php中的配置

    'aliases' => array(
    		'Auth'       	=> 'Laravel\\Auth',
    		'Authenticator' => 'Laravel\\Auth\\Drivers\\Driver',
    		'Asset'      	=> 'Laravel\\Asset',
    		'Autoloader' 	=> 'Laravel\\Autoloader',
    		'Blade'      	=> 'Laravel\\Blade',
    		'Bundle'     	=> 'Laravel\\Bundle',
    		'Cache'      	=> 'Laravel\\Cache',
    		'Config'     	=> 'Laravel\\Config',
    		'Controller' 	=> 'Laravel\\Routing\\Controller',
    		'Cookie'     	=> 'Laravel\\Cookie',
    		'Crypter'    	=> 'Laravel\\Crypter',
    		'DB'         	=> 'Laravel\\Database',
    		'Eloquent'   	=> 'Laravel\\Database\\Eloquent\\Model',
    		'Event'      	=> 'Laravel\\Event',
    		'File'       	=> 'Laravel\\File',
    		'Filter'     	=> 'Laravel\\Routing\\Filter',
    		'Form'       	=> 'Laravel\\Form',
    		'Hash'       	=> 'Laravel\\Hash',
    		'HTML'       	=> 'Laravel\\HTML',
    		'Input'      	=> 'Laravel\\Input',
    		'IoC'        	=> 'Laravel\\IoC',
    		'Lang'       	=> 'Laravel\\Lang',
    		'Log'        	=> 'Laravel\\Log',
    		'Memcached'  	=> 'Laravel\\Memcached',
    		'Paginator'  	=> 'Laravel\\Paginator',
    		'Profiler'  	=> 'Laravel\\Profiling\\Profiler',
    		'URL'        	=> 'Laravel\\URL',
    		'Redirect'   	=> 'Laravel\\Redirect',
    		'Redis'      	=> 'Laravel\\Redis',
    		'Request'    	=> 'Laravel\\Request',
    		'Response'   	=> 'Laravel\\Response',
    		'Route'      	=> 'Laravel\\Routing\\Route',
    		'Router'     	=> 'Laravel\\Routing\\Router',
    		'Schema'     	=> 'Laravel\\Database\\Schema',
    		'Section'    	=> 'Laravel\\Section',
    		'Session'    	=> 'Laravel\\Session',
    		'Str'        	=> 'Laravel\\Str',
    		'Task'       	=> 'Laravel\\CLI\\Tasks\\Task',
    		'URI'        	=> 'Laravel\\URI',
    		'Validator'  	=> 'Laravel\\Validator',
    		'View'       	=> 'Laravel\\View',
    	),
    

    基本上流程就出来了。

    牵扯的重要的文件地址:

    laravel/core.php
    laravel/autoloader.php
    application/config/application.php

    配合Ioc,够用了。下次分析一下laravel的Ioc,不过个人感觉功能太少。使用仿spring的Ding更好

  • 相关阅读:
    Ubuntu16.04搭建NetCore2.2运行环境
    Centos7安装Redis5.0.3
    Centos7常用命令
    logstash6.5.4同步mysql数据到elasticsearch 6.4.1
    Windows下安装Elasticsearch6.4.1和Head,IK分词器
    【selenium】-自动化测试的前提
    【软件测试基础】回顾总结
    【软件测试基础】其它测试分类
    【软件测试基础】文档测试
    【软件测试基础】兼容性测试
  • 原文地址:https://www.cnblogs.com/snakevash/p/2993485.html
Copyright © 2020-2023  润新知