资讯专栏INFORMATION COLUMN

Symfony2.8 源码分析之类的加载

Blackjun / 487人阅读

摘要:今天来写写这个框架的类加载机制版本原理在项目启动时,通过注册了要使用的类的自动加载处理方法,在类第一次被使用的时候,类文件通过该方法被引入,然后类才得以使用源码分析在的入口文件,我们找到我们随着这个路径我们找打了这个主要内容如下其中是为了注

今天来写写Symfony2.8 这个框架的类加载机制

版本

Symfony 2.8

原理

在项目启动时,Symfony 通过spl_autoload_register 注册了要使用的类的自动加载处理方法, 在类第一次被使用的时候, 类文件通过该方法被引入, 然后类才得以使用

源码分析

1.在symfony的入口文件, 我们找到

#web/app_dev.php or web/app.php
$loader = require __DIR__."/../app/autoload.php"

2.我们随着这个路径,我们找打了这个autoload.php, 主要内容如下:

# app/autoload.php
$loader = require __DIR__."/../vendor/autoload.php";
AnnotationRegistry::registerLoader(array($loader, "loadClass"));
return $loader;

其中

$loader = require __DIR__."/../vendor/autoload.php";

是为了注册symfony的核心类的自动加载方法

AnnotationRegistry::registerLoader(array($loader, "loadClass"));

这个应该是为了用户配置自定义的类的自动加载配置,暂时不看

3.我们再根据$loader 找到对应的autoload.php

# vendor/autoload.php
require_once __DIR__ . "/composer" . "/autoload_real.php";
return ComposerAutoloaderInit447e0408cbcbbdf0d6df9a85eb1d2ead::getLoader();

这里的getLoader()函数就是在autoload_real.php定义的,我们继续深入这个文件

4.找到autoload_real.php

# vendor/composer/autoload_real.php

我们找打getLoader 函数, 在这里, 我加入了一些代注释, 方便理解

public static function getLoader()
    {
        if (null !== self::$loader) {
            return self::$loader;
        }

        //这里注册的自动加载处理函数仅仅是为了能加载 ComposerAutoloadClassLoader
    spl_autoload_register(array("ComposerAutoloaderInit447e0408cbcbbdf0d6df9a85eb1d2ead", "loadClassLoader"), true, true);
        self::$loader = $loader = new ComposerAutoloadClassLoader();
        //$loader 才是实际的要加载的自动加载处理类
//得到自动加载处理类后ComposerAutoloadClassLoader就不需要了
spl_autoload_unregister(array("ComposerAutoloaderInit447e0408cbcbbdf0d6df9a85eb1d2ead", "loadClassLoader"));

        //以下是注册 命名空间与命名空间下的类文件的目录的映射关系
        //或者注册类名与类文件的路径的映射关系
        $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);
        }

        //该函数真正执行了`spl_autoload_register`
        $loader->register(true);

        //处理composer 的类加载
        $includeFiles = require __DIR__ . "/autoload_files.php";
        foreach ($includeFiles as $fileIdentifier => $file) {
            composerRequire447e0408cbcbbdf0d6df9a85eb1d2ead($fileIdentifier, $file);
        }

        return $loader;
    }

打开autoload_namespaces.php,autoload_psr4.php,autoload_classmap.php, 我们可以看到的是其中保存的是命名空间与命名空间下的类文件存储的目录的映射关系,或者是类名称与类文件路径的映射关系

实际上, 这种映射关系为后面的类文件定位提供直接的查询帮助,ClassLoader 注册(记录)了这种映射关系, 再将其loadClass 注册为自动加载处理函数(执行$loader->register(true);时), 最后,我们再使用到类的时候, 根据类名或者类的命名空间,到已经注册了的映射关系可以直接定位到类文件, 将其include 我们就实现了所谓的自动加载

总结

以上就是Symfony2.8 的内核类的自动加载的处理

这是第一次写框架源码分析, 比较粗糙, 如果各位有疑问, 请及时指出

另外, 这个分析只能作为大家研究symfony源码的参考,一定要对着源码一块看才能理解,切忌仅仅通过直接阅读本文就能理解

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/21801.html

相关文章

  • Linux 安装 Symfony2.8

    摘要:环境说明操作系统安装准备均使用安装至少要有个的环境是少不了了安装步骤下载官方命令工具创建项目这里执行项目创建时,会从官网下载源码包,执行完后就能在当前目录看到了这里我创建了一个新的项目叫,最后的不是项目名字中的是要下载指定的版本的源 环境说明 操作系统 tony@ubuntu:~$ lsb_release -a No LSB modules are available. Distrib...

    Yang_River 评论0 收藏0
  • Java开发

    摘要:大多数待遇丰厚的开发职位都要求开发者精通多线程技术并且有丰富的程序开发调试优化经验,所以线程相关的问题在面试中经常会被提到。将对象编码为字节流称之为序列化,反之将字节流重建成对象称之为反序列化。 JVM 内存溢出实例 - 实战 JVM(二) 介绍 JVM 内存溢出产生情况分析 Java - 注解详解 详细介绍 Java 注解的使用,有利于学习编译时注解 Java 程序员快速上手 Kot...

    LuDongWei 评论0 收藏0
  • 编程语言分类

    摘要:转载转载目前编程语言可以分为两大类第一类是像,,之类的编译型语言,它们的共性是运行之前必须对源代码进行编译,然后运行编译后的目标文件。初始化完成后读取脚本文件,引擎对脚本文件进行词法分析,语法分析。 转载 http://www.php-internals.com/book/?p=chapt02/02-03-00-how-php-script-g... 转载 http://www.l...

    XiNGRZ 评论0 收藏0

发表评论

0条评论

最新活动
阅读需要支付1元查看
<