【问题标题】:YAML and symfony2YAML 和 symfony2
【发布时间】:2015-09-19 08:05:21
【问题描述】:

我注意到在 symfony2 的 config.yml 文件中,导入功能的使用如下

imports:
- { resource: security.yml }
- { resource: services.yml }

我在自己的包中使用了一些 YAML 文件来初始化一些只读实体。然而,它们都被塞进了这个单一的 YAML 文件中。我正在使用Symfony\Component\Yaml\Parser; 组件来读取这个文件。

但是,如果我尝试复制import 的这一好功能,解析器只会正常读取它,它不会解释导入或资源关键字。

imports:
- { resource: test.yml }

也就是说 var_dump 只是没有解释的节点树。测试未加载。

如何使用与 config.yml 文件中相同的功能?

【问题讨论】:

    标签: php symfony yaml


    【解决方案1】:

    正如 Anthon 所建议的,我使用一些 symfony 组件创建了自己的实现,这是为感兴趣的人准备的类(这是一个基本实现,随心所欲)

    use Symfony\Component\Yaml\Parser;
    use Symfony\Component\Filesystem\Filesystem;
    
    class MyYmlParser {
    
    protected $parser;
    protected $finder;
    protected $currentDir;
    protected $ymlPath;
    protected $data;
    
    public function __construct($rootDir) {
        $this->rootDir = $rootDir;
        $this->parser = new Parser();
        $this->fs = new Filesystem;
    }
    
    public function setYmlPath($ymlPath) {
        $this->ymlPath = $ymlPath;
        $this->currentDir = dirname($this->ymlPath) . "/";
        return $this;
    }
    
    public function getYmlPath() {
        return $this->ymlPath;
    }
    
    private function parseFile($path) {
        if ($this->fs->exists($path)):
            return $this->parser->parse(file_get_contents($path));
        else:
            throw new \Exception("$path Do not exsist");
        endif;
    }
    
    private function buildPathFromImport($fileName) {
        return $this->currentDir . $fileName;
    }
    
    public function parse($ymlPath) {
        $this->setYmlPath($ymlPath);
        $this->data = $this->parseFile($this->ymlPath);
        if (isset($this->data["imports"])):
            foreach ($this->data["imports"] as $array):
                $importData = $this->parseFile($this->buildPathFromImport($array["resource"]));
                $this->data = array_merge($this->data, $importData);
            endforeach;
            unset($this->data['imports']);
        endif;
        #dump($this->data); exit();
        return $this->data;
    }
    }
    

    用法很简单:

    //Follow symfony syntax for imports that is:
     imports:
      - { resource: test.yml }
      - { resource: nested/dir/test2.yml }
    
    $myYmlParser = new MyYmlParser();
    $parsedData = $myYmlParser->parse($path); //the path to your yml file
    //thats it, you got an array with the data form other files and the original file.
    
     //dont forget to add it to your services for the rootDir
     AmceBundle.ymlParser:
        class: OP\AcmeBundle\Services\MyYmlParser
        arguments: ["%kernel.root_dir%"]
    

    【讨论】:

      【解决方案2】:

      YAML 解析器在所有情况下都会正常读取它。仅对于config.yml,处理表示的实例的程序“扩展”映射键import 的值,方法是从作为关联值的列表中获取并用与resource 关联的值替换节点。

      这不是YAML 的特性,而是解析器传递给程序的数据的解释。如果您的程序不递归地应用此功能,您应该修补程序以执行此操作。

      【讨论】:

      • 是否有一些已经制作好的包实现了上述功能?否则,我觉得我需要扩展解析器并创建此功能。
      • @delmalki 扩展解析器或后处理。您应该能够在 symfony 源代码中找到代码,只需将其更普遍地应用于所有 YAML 文件(并且可能递归地应用到所有导入都被扩展)。看起来你已经这样做了)
      猜你喜欢
      • 2012-05-08
      • 2012-06-04
      • 1970-01-01
      • 2015-03-08
      • 2014-04-20
      • 2023-03-28
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多