框架运行命令 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);
下编介绍真正的执行