diff --git a/src/ZM/Container/Container.php b/src/ZM/Container/Container.php index 72d05345..af95aab7 100644 --- a/src/ZM/Container/Container.php +++ b/src/ZM/Container/Container.php @@ -4,8 +4,6 @@ declare(strict_types=1); namespace ZM\Container; -use ReflectionException; - class Container extends WorkerContainer { /** @@ -51,7 +49,6 @@ class Container extends WorkerContainer * @param string $abstract 类或接口名 * @param array $parameters 参数 * @throws EntryResolutionException - * @throws ReflectionException * @return mixed 实例 */ public function make(string $abstract, array $parameters = []) diff --git a/src/ZM/Container/WorkerContainer.php b/src/ZM/Container/WorkerContainer.php index 5cb1fe74..4fcad19d 100644 --- a/src/ZM/Container/WorkerContainer.php +++ b/src/ZM/Container/WorkerContainer.php @@ -13,9 +13,12 @@ use ReflectionClass; use ReflectionException; use ReflectionNamedType; use ReflectionParameter; +use ZM\Utils\SingletonTrait; class WorkerContainer implements ContainerInterface { + use SingletonTrait; + /** * @var array */ @@ -210,7 +213,6 @@ class WorkerContainer implements ContainerInterface * @param string $abstract 类或接口名 * @param array $parameters 参数 * @throws EntryResolutionException - * @throws ReflectionException * @return mixed 实例 */ public function make(string $abstract, array $parameters = []) @@ -260,7 +262,6 @@ class WorkerContainer implements ContainerInterface * * @param Closure|string $concrete 类名或对应的闭包 * @throws EntryResolutionException - * @throws ReflectionException * @return mixed */ public function build($concrete) @@ -293,7 +294,12 @@ class WorkerContainer implements ContainerInterface $dependencies = $constructor->getParameters(); // 获取所有依赖的实例 - $instances = $this->resolveDependencies($dependencies); + try { + $instances = $this->resolveDependencies($dependencies); + } catch (EntryResolutionException $e) { + array_pop($this->buildStack); + throw $e; + } array_pop($this->buildStack); @@ -448,7 +454,6 @@ class WorkerContainer implements ContainerInterface * * @param ReflectionParameter[] $dependencies * @throws EntryResolutionException - * @throws ReflectionException */ protected function resolveDependencies(array $dependencies): array { @@ -566,7 +571,6 @@ class WorkerContainer implements ContainerInterface * 解析类 * * @throws EntryResolutionException 如果无法解析类,则抛出异常 - * @throws ReflectionException 实际上不会抛出,请无视 * @return mixed */ protected function resolveClass(ReflectionParameter $parameter) @@ -576,10 +580,16 @@ class WorkerContainer implements ContainerInterface return $this->make($parameter->getClass()->name); } catch (EntryResolutionException $e) { // 如果参数是可选的,则返回默认值 - if ($parameter->isOptional()) { + if ($parameter->isDefaultValueAvailable()) { + array_pop($this->with); return $parameter->getDefaultValue(); } + if ($parameter->isVariadic()) { + array_pop($this->with); + return []; + } + throw $e; } } diff --git a/src/ZM/global_functions.php b/src/ZM/global_functions.php index 460768e8..bfaca2da 100644 --- a/src/ZM/global_functions.php +++ b/src/ZM/global_functions.php @@ -13,6 +13,8 @@ use ZM\API\ZMRobot; use ZM\Config\ZMConfig; use ZM\ConnectionManager\ManagerGM; use ZM\Console\Console; +use ZM\Container\Container; +use ZM\Container\ContainerInterface; use ZM\Context\Context; use ZM\Context\ContextInterface; use ZM\Event\EventManager; @@ -40,6 +42,7 @@ function get_class_path(string $class_name): ?string /** * 检查炸毛框架运行的环境 + * * @internal */ function _zm_env_check() @@ -416,6 +419,7 @@ function server(): Server /** * 获取缓存当前框架pid的临时目录 + * * @internal */ function _zm_pid_dir(): string @@ -433,6 +437,7 @@ function _zm_pid_dir(): string * 随机返回一个 ZMRobot 实例,效果等同于 {@link ZMRobot::getRandom()}。 * * 在单机器人模式下,会直接返回该机器人实例。 + * * @throws RobotNotFoundException */ function bot(): ZMRobot @@ -627,6 +632,7 @@ function zm_internal_errcode($code): string } /** +<<<<<<< HEAD * 将可能为数组的参数转换为字符串 * * 如传入字符串则为原样返回 @@ -638,6 +644,39 @@ function implode_when_necessary($string_or_array): string return is_array($string_or_array) ? implode(', ', $string_or_array) : $string_or_array; } +/** + * 获取容器(请求级)实例 + */ +function container(): ContainerInterface +{ + return Container::getInstance(); +} + +/** + * 解析类实例(使用容器) + * + * @return mixed + */ +function resolve(string $abstract, array $parameters = []) +{ + return Container::getInstance()->make($abstract, $parameters); +} + +/** + * 获取容器实例 + * + * @param null|string $abstract 类或接口名,不传入则返回容器实例 + * @return ContainerInterface|mixed + */ +function app(string $abstract = null, array $parameters = []) +{ + if (is_null($abstract)) { + return container(); + } + + return resolve($abstract, $parameters); +} + /** * 以下为废弃的函数,将于未来移除 */