php bin/hyperf.php start
來看看作了哪些工做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);
下編介紹真正的執行