基於swoole框架hyperf源碼分析(1)

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

來看看作了哪些工做php

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方法app

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

//看下獲得的數組結構composer

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掃描上面獲得的配置內容。收集數據async

//使用 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,組成數組ide

$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);

下編介紹真正的執行

相關文章
相關標籤/搜索