• Swoole实战之手撸HttpServer框架 8 构建框架的基本结构、Bean工厂基本设计、初步实现Bean注释


    视频 https://www.bilibili.com/video/BV14E411t7T4?p=10

    1 构建框架的基本结构

    1.1 准备工作

    2 代码

    2.1 修改Request.php 

    把之前的项目的Request.php文件复制过来,并修改命名空间为 :namespace Core\Http;  

    2.2 修改composer.json

            "psr-4": {
                "App\\" : "app/" ,
                "Core\\":"core/"
            }
    composer require doctrine/annotations 1.6
    composer require nikic/fast-route 
    composer require php-di/php-di

     然后别忘了执行

    composer dump-autoload

    2.3  env配置文件

    配置扫描的路径

    scan_dir = ./app/controllers
    scan_root_namespace = App\

    2.4 使用类注解

    把原来的Bean.php复制过来

    \core\annotations\Bean.php

    <?php
    
    namespace Core\annotations;
    use Doctrine\Common\Annotations\Annotation\Target;
    /**
     * @Annotation
     * @Target({"CLASS"})
     */
    class Bean
    {
    
    }

    2.5 使用属性注解

    \core\annotations\Value.php

    <?php
    
    namespace Core\annotations;
    use Doctrine\Common\Annotations\Annotation\Target;
    /**
     * @Annotation
     * @Target({"PROPERTY"})
     */
    class Value
    {
        
    }

    2.6 注释的do方法 AnnotationHandler

    \pro\core\annotations\AnnotationHandler.php

    <?php
    
    namespace Core\annotations;
    return [
        //类注解
        Bean::class=>function($instance,$container){
            //get_class返回对象的类名
           $arr = explode("\\",get_class($instance));
           $beanName = end($arr);
           $container->set($beanName,$instance);
        },
        //属性注解
        Value::class=>function(){
        
        }
    ];

    2.7 使用类注释要加载的类

    \pro\app\controllers\UserController.php

    <?php
    
    namespace App\controllers;
    use Core\annotations\Bean;
    
    /**
     * Class UserController
     * 使用Bean注解加载类
     * @Bean()
     * @package App\controllers
     */
    class UserController
    {
        public $version = '1.0';
    }

    2.8  define.php

    pro\app\config\define.php

    <?php
    //pro根目录 定义一个ROOT_PATH
    define("ROOT_PATH",dirname(dirname(__DIR__)));
    View Code

    2.9 启动文件

    pro\test.php

    <?php
    require_once __DIR__.'/vendor/autoload.php';
    require_once __DIR__."/app/config/define.php";
    \Core\BeanFactory::init();
    
    $user = \Core\BeanFactory::getBean("UserController");
    var_dump($user);

    2.10 最重要的 \BeanFactory

    pro\core\BeanFactory.php

    <?php
    
    namespace Core;
    
    
    use DI\ContainerBuilder;
    use \Doctrine\Common\Annotations\AnnotationReader;
    use \Doctrine\Common\Annotations\AnnotationRegistry;
    
    
    class BeanFactory
    {
        
        //配置文件
        private static $env=[];
        //IOC容器
        private static  $container;
        
        //初始化函数
        public static function init()
        {
            self::$env = parse_ini_file(ROOT_PATH."/.env");
            //var_dump(self::$env);
            /**
             * array(2) {
            ["scan_dir"]=>
            string(17) "./app/controllers"
            ["scan_root_namespace"]=>
            string(4) "App\"
            }
             */
            //初始容器Builder
            $builder = new ContainerBuilder();
            //启用注释 主要是用它的Inject注释
            $builder->useAnnotations(true);
            //容器初始化
            self::$container=$builder->build();
            //扫描(重点)
            self::ScanBeans();
            
        }
        
        //获取env文件的配置内容
        private static function _getEnv(string $key,string $default='')
        {
            if (isset(self::$env[$key]))
                return self::$env[$key];
            return $default;
        }
        
        public static function ScanBeans()
        {
            $annoHandles = require_once (ROOT_PATH."/core/annotations/AnnotationHandler.php");
            $scanDir = self::_getEnv("scan_dir",ROOT_PATH."/app");
            $scanRootNamespace = self::_getEnv("scan_root_namespace","APP\\");
            //glob() 函数返回匹配指定模式的文件名或目录
            //搜索要扫描目录下的php文件 返回文件名称
            $files = glob($scanDir."/*.php");
            foreach ($files as $file){
                require_once $file;
            }
            //注释类对象
            
            $reader = new AnnotationReader();
            //AnnotationRegistry::registerAutoloadNamespace('Core\annotations');
            
            AnnotationRegistry::registerLoader('class_exists'); //回调需返回true
            //get_declared_classes返回由已定义类的名字所组成的数组
            foreach (get_declared_classes() as $class){
               if (strstr($class,$scanRootNamespace)){
                   $refClass = new \ReflectionClass($class);
                   //获取所有类的注释
                   $classAnnos = $reader->getClassAnnotations($refClass);
                   foreach ($classAnnos as $classAnno){
                       //根据注释的类型获取对应处理方法
                       $hander = $annoHandles[get_class($classAnno)];
                       $hander(self::$container->get($refClass->getName()),self::$container);
                       
                       
                   }
                   
               }
            }
        }
        
        public static function getBean($name)
        {
            return self::$container->get($name);
        }
    }
  • 相关阅读:
    小组站立会议 星期四
    小组站立会议 星期三
    小组站立会议 星期二
    小组站立会议 星期一
    小组站立会议
    爱壁纸 站立会议(六)--Spring阶段总结会议
    爱壁纸 站立会议(五)
    爱壁纸 小组会议(四)
    爱壁纸-小组会议(三)
    MD5加密代码
  • 原文地址:https://www.cnblogs.com/polax/p/15729692.html
Copyright © 2020-2023  润新知