I want to get an array from a yaml file inside one of my services, and I am a little confused of how to inject the file to use in my services.yml.
# /path/to/app/src/Bundle/Resources/config/services.yml
parameters:
do_something: Bundle\DoSomething
yaml.parser.class: Symfony\Component\Yaml\Parser
yaml.config_file: "/Resources/config/config.yml" # what do I put here to win!
services:
yaml_parser:
class: %yaml.parser.class%
do_parsing:
class: %do_something%
arguments: [ @yaml_parser, %yaml.config_file% ]
In my service I have
# /path/to/app/src/Bundle/DoSomething.php
<?php
namespace Bundle;
use \Symfony\Component\Yaml\Parser;
class DoSemething
{
protected $parser;
protected $parsed_yaml_file;
public function __construct(Parser $parser, $file_path)
{
$this->parsed_yaml_file = $parser->parse(file_get_contents(__DIR__ . $file_path));
}
public function useParsedFile()
{
foreach($parsed_yaml_file as $k => $v)
{
// ... etc etc
}
}
}
This may be the completely wrong approach, if I should be doing something else please let me know!
First I'll explain why I implemented my solution for you to decide if this case is right for you.
I needed a way to easily load custom .yml files in my bundle (for lots of bundles) so adding a separate line to app/config.yml for every file seemed like a lot of hassle for every setup.
Also I wanted most of the configs to be already loaded by default so end-user wouldn't even need to worry about configuring most of the time, especially not checking that every config file is setup correctly.
If this seems like a similar case for you, read on. If not, just use Kris solution, is a good one too!
Back when I encountered a need for this feature, Symfony2 didnt't provide a simple way to achieve this, so here how I solved it:
First I created a local YamlFileLoader class which was basically a dumbed down Symfony2 one:
<?php
namespace Acme\DemoBundle\Loader;
use Symfony\Component\Yaml\Yaml;
use Symfony\Component\Config\Loader\FileLoader;
/**
* YamlFileLoader loads Yaml routing files.
*/
class YamlFileLoader extends FileLoader
{
/**
* Loads a Yaml file.
*
* @param string $file A Yaml file path
*
* @return array
*
* @throws \InvalidArgumentException When config can't be parsed
*/
public function load($file, $type = null)
{
$path = $this->locator->locate($file);
$config = Yaml::parse($path);
// empty file
if (null === $config) {
$config = array();
}
// not an array
if (!is_array($config)) {
throw new \InvalidArgumentException(sprintf('The file "%s" must contain a YAML array.', $file));
}
return $config;
}
/**
* Returns true if this class supports the given resource.
*
* @param mixed $resource A resource
* @param string $type The resource type
*
* @return Boolean True if this class supports the given resource, false otherwise
*
* @api
*/
public function supports($resource, $type = null)
{
return is_string($resource) && 'yml' === pathinfo($resource, PATHINFO_EXTENSION) && (!$type || 'yaml' === $type);
}
}
Then I updated DIC Extension for my bundle (it's usually generated automatically if you let Symfony2 create full bundle architecture, if not just create a DependencyInjection/<Vendor&BundleName>Extension.php
file in your bundle directory with following content:
<?php
namespace Acme\DemoBundle\DependencyInjection;
use Symfony\Component\DependencyInjection\ContainerBuilder;
use Symfony\Component\Config\FileLocator;
use Symfony\Component\HttpKernel\DependencyInjection\Extension;
use Symfony\Component\DependencyInjection\Loader;
use Acme\DemoBundle\Loader\YamlFileLoader;
/**
* This is the class that loads and manages your bundle configuration
*
* To learn more see {@link http://symfony.com/doc/current/cookbook/bundles/extension.html}
*/
class AcmeDemoExtension extends Extension
{
/**
* {@inheritDoc}
*/
public function load(array $configs, ContainerBuilder $container)
{
$configuration = new Configuration();
$config = $this->processConfiguration($configuration, $configs);
$loader = new Loader\XmlFileLoader($container, new FileLocator(__DIR__.'/../Resources/config'));
$loader->load('services.xml');
// until here everything is default config (for your DIC services)
$ymlLoader = new YamlFileLoader(new FileLocator(__DIR__.'/../Resources/config'));
$container->setParameter('param_name', $ymlLoader->load('yaml_file_name'))); // load yml file contents as an array
}
}
And now you can access/pass your yaml config as simple service parameter (i.e. %param_name%
for services.yml)
I solved it this way:
#/path/to/app/src/Bundle/Resources/config/services.yml
parameters:
example.class: Path\To\Bundle\Service\Class
example.yaml_config_file: "%kernel.root_dir%/../src/Path/To/Bundle/Resources/config/config.yml"
services:
example_service:
class: %example.class%
arguments: [%example.yaml_config_file% ]
# /path/to/app/src/Bundle/Service/Example.php
<?php
namespace Bundle\Service;
use \Symfony\Component\Yaml\Yaml;
class Example
{
private $parsed_yaml_file;
public function __construct($yaml_config_file)
{
$this->parsed_yaml_file = Yaml::parse($yaml_config_file);
}
}
You can use the kernel.root_dir
parameter:
parameters:
yaml.config_file: "%kernel.root_dir%/../src/Path/To/MyBundle/Resources/config/config.yml"
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With