首页  >  文章  >  php框架  >  Laravel框架中Autoloader模块的代码分析

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

不言
不言原创
2018-07-31 15:57:211978浏览

本篇文章给大家分享的内容是关于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(&#39;\\&#39;, &#39;_&#39;), &#39;/&#39;, $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 = &#39;\\&#39;)
	{
		$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, &#39;_&#39;); # 下划线风格
	}

	/**
	 * 格式目录映射
	 *
	 * @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(&#39;Laravel\\Autoloader&#39;, &#39;load&#39;)); # spl_autoload_register array 命名空间,具体方法

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

定义系统root

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

然后是默认使用的ORM框架

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

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

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

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

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

基本上流程就出来了。

牵扯的重要的文件地址:

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

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

以上就是本篇文章的全部内容了,更多laravel内容请关注laravel框架入门教程

相关文章推荐:

实时聊天室:基于Laravel+Pusher+Vue通过事件广播实现

laravel框架中TokenMismatchException的异常处理内容

Laravel框架中外观模式的深入解析

相关课程推荐:

2017年最新的五个Laravel视频教程推荐

以上是Laravel框架中Autoloader模块的代码分析的详细内容。更多信息请关注PHP中文网其他相关文章!

声明:
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn