基于swoole框架hyperf源码分析(1)

框架运行命令 php bin/hyperf.php start

来看看做了哪些工作

hyperf.php 内容

1.用了一个闭包的写法,避免外部变量影响内部,主要是实例化了一个ioc容器,创建控制台应用程序

(function () {
    /** @var \Psr\Container\ContainerInterface $container */
    $container = require BASE_PATH . '/config/container.php';

    $application = $container->get(\Hyperf\Contract\ApplicationInterface::class);
    $application->run();
})();

2.看看container.php文件,看看如何实例化ioc容器

$container = new Container((new DefinitionSourceFactory(true))());

对象用函数的方法执行会运行对象里 __invoke方法
`public function __invoke()

{
    $configDir = $this->baseUri . '/config';`

//加载composer.lock,把依赖类的配置属性组成一个数组,并执行依赖类的__invoke方法

    $configFromProviders = [];
    if (class_exists(ProviderConfig::class)) {
        $configFromProviders = ProviderConfig::load();
    }

//看下得到的数组结构

array(28) {
  [0]=>
  array(2) {
    ["annotations"]=>
    array(1) {
      ["scan"]=>
      array(1) {
        ["paths"]=>
        array(1) {
          [0]=>
          string(49) "/www/wwwroot/carder/vendor/hyperf/async-queue/src"
        }
      }
    }
    ["publish"]=>
    array(1) {
      [0]=>
      array(4) {
        ["id"]=>
        string(6) "config"
        ["description"]=>
        string(27) "The config for async queue."
        ["source"]=>
        string(76) "/www/wwwroot/carder/vendor/hyperf/async-queue/src/../publish/async_queue.php"
        ["destination"]=>
        string(51) "/www/wwwroot/carder/config/autoload/async_queue.php"
      }
    }
  }
  [1]=>
  array(4) {
    ["dependencies"]=>
    array(1) {
      ["Psr\SimpleCache\CacheInterface"]=>
      string(18) "Hyperf\Cache\Cache"
    }
    ["listeners"]=>
    array(1) {
      [0]=>
      string(36) "Hyperf\Cache\Listener\DeleteListener"
    }
    ["annotations"]=>
    array(1) {
      ["scan"]=>
      array(2) {
        ["paths"]=>
        array(1) {
          [0]=>
          string(43) "/www/wwwroot/carder/vendor/hyperf/cache/src"
        }
        ["collectors"]=>
        array(1) {
          [0]=>
          string(35) "Hyperf\Cache\CacheListenerCollector"
        }
      }
    }
    ["publish"]=>
    array(1) {
      [0]=>
      array(4) {
        ["id"]=>
        string(6) "config"
        ["description"]=>
        string(21) "The config for cache."
        ["source"]=>
        string(64) "/www/wwwroot/carder/vendor/hyperf/cache/src/../publish/cache.php"
        ["destination"]=>
        string(45) "/www/wwwroot/carder/config/autoload/cache.php"
      }
    }
  }

//下面就是把配置文件的依赖关系 扫描目录等和上面得到的配置合并,*注意下,配置文件的配置等级高于扫描到的配置内容*

 $serverDependencies = $configFromProviders['dependencies'] ?? [];
        if (file_exists($configDir . '/autoload/dependencies.php')) {
            $definitions = include $configDir . '/autoload/dependencies.php';
            $serverDependencies = array_replace($serverDependencies, $definitions ?? []);
        }

3扫描上面得到的配置内容。收集数据

//使用 Symfony\Component\Finder\Finder文件组件遍历所有的文件,找到php后缀的文件
$finder = new Finder();
        $finder->files()->in($paths)->name('*.php');

        $meta = [];
        foreach ($finder as $file) {
            try {
 //找到的文件用 PHP Parser 类解析成抽象语法树,这个aop功能用的到,主要是通过改变抽象语法树的节点,来实现aop,不明白的去看下PHP Parser类,功能很强大
                $stmts = $this->parser->parse($file->getContents());
                $className = $this->parser->parseClassByStmts($stmts);
                if (! $className) {
                    continue;
                }
                $meta[$className] = $stmts;
            } catch (\RuntimeException $e) {
                continue;
            }
        }

把扫描到的php文件用类名作为key,ast作为val,组成数组

$reader = new AnnotationReader();
        // Because the annotation class should loaded before use it, so load file via $finder previous, and then parse annotation here.
        foreach ($classCollection as $className) {
            $reflectionClass = ReflectionManager::reflectClass($className);
            $classAnnotations = $reader->getClassAnnotations($reflectionClass);
            if (! empty($classAnnotations)) {
                foreach ($classAnnotations as $classAnnotation) {
                    if ($classAnnotation instanceof AnnotationInterface) {
                        $classAnnotation->collectClass($className);
                    }
                }
            }

通过反射收集注解类,然后把扫描的数据缓存起来

$data = implode(PHP_EOL, [$pathsHash, serialize(array_keys($meta))]);
        file_put_contents($cachePath, $data);

下编介绍真正的执行

你可能感兴趣的:(php,后端,swoole)