Php 从编译器过程中检索捆绑包类实例
我不确定是否能在这里找到任何解决方案,正如已经被问到的那样,但给出了一个我无法实现的(有效的)解决方案,因为我正在开发symfony(一个月) 形势 在编译器过程(或包扩展)中,我需要获取加载应用程序每个包的资源的路径(包括第三方,在内核中注册的所有包) 目前,我在可访问ContainerBuilder的捆绑包扩展中使用以下内容:Php 从编译器过程中检索捆绑包类实例,php,symfony,Php,Symfony,我不确定是否能在这里找到任何解决方案,正如已经被问到的那样,但给出了一个我无法实现的(有效的)解决方案,因为我正在开发symfony(一个月) 形势 在编译器过程(或包扩展)中,我需要获取加载应用程序每个包的资源的路径(包括第三方,在内核中注册的所有包) 目前,我在可访问ContainerBuilder的捆绑包扩展中使用以下内容: foreach ($container->getParameter('kernel.bundles') as $bundle) { // Create
foreach ($container->getParameter('kernel.bundles') as $bundle) {
// Create a reflection from the FQCN of the bundle class
$reflection = new \ReflectionClass($bundle);
// Localise the file containing the class
$path = dirname($reflection->getFilename());
// Do stuffs that load files such as $path/Resources/config/serializer.yml
}
每个bundle类都有一个getPath()
方法,在自定义目录结构的情况下,该方法可以返回自定义路径
因此,使用反射文件可能会导致忽略一些配置文件,而不是正确加载它们
错误的备选方案
创建捆绑包的实例并调用getPath()
方法,可以是:
$reflection = new \ReflectionClass($bundle);
$getPathReflection = new \ReflectionMethod($bundle, 'getPath');
$path = $getPathReflection->invoke(new $bundle());
但是如果其中一个bundle类具有一个(或多个)构造函数参数呢?这将导致致命错误 问题 因此,我无法手动创建实例,因为我不知道它们需要实例化什么 我的第一个想法是,我可以获得
kernel
服务,然后循环$kernel->getBundles()
并调用getPath()
方法
但是$container->get('kernel')
的结果是:
[Symfony\Component\DependencyInjection\Exception\RuntimeException]您已经请求了一个合成服务(“内核”)。驾驶员信息中心不知道如何构建此服务 有没有一种方法可以在不向FrameworkBundle类添加参数的情况下,为编译器过程/bundle扩展中的每个bundle类调用此方法 编辑 第一种可能的选择:
$getPathReflection = new \ReflectionMethod($bundle, 'getPath');
$reflectionInstance = $reflection->newInstanceWithoutConstructor();
$path = $getPathReflection->invoke($reflectionInstance) ?: dirname($reflection->getFilename());
缺点:
仅在PHP 5.4中可用,因此测试无法通过\ReflectionClass::newInstanceWithoutConstructor()
- 如果
值取决于构造函数参数,这将导致Bundle#getPath()
,从而使用反射路径(即null
)?:dirname($reflection->getFilename())