Laravel框架中Autoloader模块的代码分析

本篇文章给大家分享的内容是关于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 =&gt; $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('LaravelAutoloader', 'load')); # spl_autoload_register array 命名空间,具体方法

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

定义系统root

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

然后是默认使用的ORM框架

# 定义EloquentORM框架 Autoloader::map(array( 	'LaravelDatabaseEloquentRelationshipsBelongs_To'                      =&gt; path('sys').'database/eloquent/relationships/belongs_to'.EXT, 	'LaravelDatabaseEloquentRelationshipsHas_Many'                      =&gt; path('sys').'database/eloquent/relationships/has_many'.EXT, 	'LaravelDatabaseEloquentRelationshipsHas_Many_And_Belongs_To'                      =&gt; path('sys').'database/eloquent/relationships/has_many_and_belongs_to'.EXT, 	'LaravelDatabaseEloquentRelationshipsHas_One'                      =&gt; path('sys').'database/eloquent/relationships/has_one'.EXT, 	'LaravelDatabaseEloquentRelationshipsHas_One_Or_Many'                      =&gt; path('sys').'database/eloquent/relationships/has_one_or_many'.EXT, ));

随后是symfonyhttp组件和console组件

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

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

'aliases' =&gt; array( 		'Auth'       	=&gt; 'LaravelAuth', 		'Authenticator' =&gt; 'LaravelAuthDriversDriver', 		'Asset'      	=&gt; 'LaravelAsset', 		'Autoloader' 	=&gt; 'LaravelAutoloader', 		'Blade'      	=&gt; 'LaravelBlade', 		'Bundle'     	=&gt; 'LaravelBundle', 		'Cache'      	=&gt; 'LaravelCache', 		'Config'     	=&gt; 'LaravelConfig', 		'Controller' 	=&gt; 'LaravelRoutingController', 		'Cookie'     	=&gt; 'LaravelCookie', 		'Crypter'    	=&gt; 'LaravelCrypter', 		'DB'         	=&gt; 'LaravelDatabase', 		'Eloquent'   	=&gt; 'LaravelDatabaseEloquentModel', 		'Event'      	=&gt; 'LaravelEvent', 		'File'       	=&gt; 'LaravelFile', 		'Filter'     	=&gt; 'LaravelRoutingFilter', 		'Form'       	=&gt; 'LaravelForm', 		'Hash'       	=&gt; 'LaravelHash', 		'HTML'       	=&gt; 'LaravelHTML', 		'Input'      	=&gt; 'LaravelInput', 		'IoC'        	=&gt; 'LaravelIoC', 		'Lang'       	=&gt; 'LaravelLang', 		'Log'        	=&gt; 'LaravelLog', 		'Memcached'  	=&gt; 'LaravelMemcached', 		'Paginator'  	=&gt; 'LaravelPaginator', 		'Profiler'  	=&gt; 'LaravelProfilingProfiler', 		'URL'        	=&gt; 'LaravelURL', 		'Redirect'   	=&gt; 'LaravelRedirect', 		'Redis'      	=&gt; 'LaravelRedis', 		'Request'    	=&gt; 'LaravelRequest', 		'Response'   	=&gt; 'LaravelResponse', 		'Route'      	=&gt; 'LaravelRoutingRoute', 		'Router'     	=&gt; 'LaravelRoutingRouter', 		'Schema'     	=&gt; 'LaravelDatabaseSchema', 		'Section'    	=&gt; 'LaravelSection', 		'Session'    	=&gt; 'LaravelSession', 		'Str'        	=&gt; 'LaravelStr', 		'Task'       	=&gt; 'LaravelCLITasksTask', 		'URI'        	=&gt; 'LaravelURI', 		'Validator'  	=&gt; 'LaravelValidator', 		'View'       	=&gt; 'LaravelView', 	),

基本上流程就出来了。

牵扯的重要的文件地址:

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

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

© 版权声明
THE END
喜欢就支持一下吧
点赞8 分享