在 Symfony2 中访问与 Bundle 相关的文件
Posted
技术标签:
【中文标题】在 Symfony2 中访问与 Bundle 相关的文件【英文标题】:Accessing Files Relative to Bundle in Symfony2 【发布时间】:2011-11-26 23:32:05 【问题描述】:在 Symfony2 应用的路由配置中,我可以引用这样的文件:
somepage:
prefix: someprefix
resource: "@SomeBundle/Resources/config/config.yml"
有没有办法在控制器或其他 php 代码中访问与包相关的文件?特别是,我正在尝试使用 Symfony\Component\Yaml\Parser 对象来解析文件,并且我不想绝对引用该文件。本质上,我想这样做:
$parser = new Parser();
$config = $parser->parse( file_get_contents("@SomeBundle/Resources/config/config.yml") );
我已经检查了 Symfony\Component\Finder\Finder 类,但我认为这不是我想要的。有任何想法吗?或者也许我完全忽略了这样做的更好方法?
【问题讨论】:
【参考方案1】:事实上,您可以使用一个服务,即内核 ($this->get('kernel')
)。它有一个名为locateResource()
的方法。
例如:
$kernel = $container->getService('kernel');
$path = $kernel->locateResource('@AdmeDemoBundle/path/to/file/Foo.txt');
【讨论】:
正是我想要的! $this->get('kernel')->locateResource("@SomeBundle/Resources/config/config.yml"); // 完美运行 @tomtheman5:一定要捕获它的异常。如果找不到文件或名称无效,则此方法抛出\InvalidArgumentException
,如果名称包含无效/不安全字符,则抛出\RuntimeException
。
愿意为您提供的不仅仅是 +1。
您将如何(如果有的话)在一个(我不认为)会(或应该)访问内核的学说实体中使用此方法?
@Morslamina 查看 fazy 的回答。【参考方案2】:
Thomas Kelley 的回答很好(并且有效!)但如果您使用依赖注入和/或不想将代码直接绑定到内核,则最好使用 FileLocator 类/服务:
$fileLocator = $container->get('file_locator');
$path = $fileLocator->locate('@MyBundle/path/to/file.txt')
$fileLocator
将是\Symfony\Component\HttpKernel\Config\FileLocator
的一个实例。 $path
将是文件的完整绝对路径。
尽管file_locator
服务本身使用内核,但它的依赖项要小得多(更容易替换您自己的实现,使用测试替身等)
将它与依赖注入一起使用:
# services.yml
services:
my_bundle.my_class:
class: MyNamespace\MyClass
arguments:
- @file_locator
# MyClass.php
use Symfony\Component\Config\FileLocatorInterface as FileLocator;
class MyClass
private $fileLocator;
public function __construct(FileLocator $fileLocator)
$this->fileLocator = $fileLocator;
public function myMethod()
$path = $this->fileLocator->locate('@MyBundle/path/to/file.txt')
【讨论】:
好点,但是 FileLocator 被注入了 KernelInterface,所以基本上,如果你注入 FileLocator 而不是 Kernel,你不会做的更好:) 我明白你的意思,我想到了这一点。但是,问题不是“加载/执行了什么代码?”,而是“MyClass
依赖什么代码?”。当前的FileLocator
实现使用KernelInterface
,但如果将来发生变化MyClass
不需要知道它。此外,现在更清楚MyClass
真正需要什么(并且减少了将其与其他内核功能结合起来的诱惑)。说了这么多,构造函数应该可能需要Symfony\Component\Config\FileLocatorInterface
而不是Symfony\Component\HttpKernel\Config\FileLocator
。然后你就可以自己写了。
这是更好的答案【参考方案3】:
您可以使用$container->getParameter('kernel.root_dir')
获取应用程序的app
文件夹,并浏览您的目录找到您想要的文件。
【讨论】:
Bundle 可以在任何目录中。常用示例:src/Acme/Bundle/MyBundle
、src/Acme/MyBundle
、vendor/acme/my-bundle/src
等。【参考方案4】:
如果您想在位于src/.../SomeBundle/...
的文件中执行此操作,您可以使用__DIR__
获取当前文件的完整路径。然后将您的 Resources/...
路径附加到类似
$foo = __DIR__.'/Resources/config/config.yml';
【讨论】:
@ruudy “只有拥有付费计划的注册用户才能获得对规则描述的完全访问权限。此页面显示了通过订阅可以获得的示例。” 我没有付款,我可以看到完整的描述和如何解决它的解释。也许你只需要注册。 现在我已经注册了,我可以看到页面了。首先,它说“不应该”而不是“不得”。其次,恕我直言,这仅在您计划向公众发布代码或计划稍后覆盖资源路径时才重要。在我的闭源项目中,这不会发生,所以这对我来说并不重要。这取决于您将要使用它的上下文,如果这一点对您很重要。不过感谢您的提示。 如果您遵循建议,您可以模拟路径,或者出于测试目的使用它。我不是英语本地人,最好不要尽可能使用这个 php 常量,更不用说像 Symfony2 这样的框架了。以上是关于在 Symfony2 中访问与 Bundle 相关的文件的主要内容,如果未能解决你的问题,请参考以下文章
Payum Bundle:如何在 symfony2 中更改捕获操作的视图
Symfony2 KnpPaginator bundle 从多个实体获取数据并在一个网格/分页中呈现
Symfony2:列出虚拟文件夹(Netbeans)中的所有视图/路由文件
Symfony2 Sonata Media Bundle 自定义图像裁剪