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);
下编介绍真正的执行