当前位置: 首页 > 后端技术 > PHP

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

时间:2023-03-30 02:32:58 PHP

框架运行命令phpbin/hyperf.phpstart查看做了哪些工作hyperf.php内容1.闭包用于防止外部变量影响内部,主要是实例化一个ioc容器,创建控制台应用程序(function(){/**@var\Psr\Container\ContainerInterface$container*/$container=requireBASE_PATH.'/config/container.php';$application=$container->get(\Hyperf\Contract\ApplicationInterface::class);$application->run();})();2.查看container.php文件,了解如何实例化ioc容器$container=newContainer((newDefinitionSourceFactory(true))());该对象将运行__invoke方法`publicfunction__invoke(){$configDir=$this->baseUri。组成一个数组,执行依赖类的__invoke方法$configFromProviders=[];如果(class_exists(ProviderConfig::class)){$configFromProviders=ProviderConfig::load();}//查看得到的数组结构array(28){[0]=>array(2){["annotations"]=>array(1){["scan"]=>array(1){["路径"]=>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)"异步队列的配置。"["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”}[“注释”]=>数组(1){[“扫描”]=>数组(2){[“路径”]=>数组(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)“缓存的配置。”[“源”]=>字符串(64)“/www/wwwroot/carder/vendor/hyperf/cache/src/../publish/cache.php”[“目的地”]=>字符串(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的文件=新的查找器();$finder->files()->in($paths)->name('*.php');$元=[];foreach($finderas$file){try{//找到的文件用PHPParser类解析成抽象语法树。使用这个aop函数,主要是通过改变抽象语法树的节点来实现aop。不懂就去PHPParser类,很强大$stmts=$this->parser->parse($file->getContents());$className=$this->parser->parseClassByStmts($stmts);如果(!$className){继续;}$meta[$className]=$stmts;}catch(\RuntimeException$e){继续;}}将扫描的php文件作为key,ast作为val,组成一个数组$reader=newAnnotationReader();//因为注解类在使用前需要加载,所以之前通过$finder加载文件,然后在这里解析注解。foreach($classCollectionas$className){$reflectionClass=ReflectionManager::reflectClass($className);}$class注解=$reader->getClassAnnotations($reflectionClass);如果(!empty($classAnnotations)){foreach($classAnnotationsas$classAnnotation){如果($classAnnotationinstanceofAnnotationInterface){$classAnnotation->collectClass($className);通过反射收集注解类,然后缓存扫描到的数据$data=implode(PHP_EOL,[$pathsHash,serialize(array_keys($meta))]);file_put_contents($cachePath,$data);下一部分介绍真正的实现