a SENSIOLABS Product
Symfony

Dependency Injection
Reinventing how you manage
PHP classes

Appendix B - The XML Format

RELEASE INFORMATION

You are currently browsing the documentation for the trunk version.

This appendix describes the XML format used to describe parameters and services.

Format

The XML files are always validated by an XSD file before being parsed by the component.

The bare minimum and valid XML file reads as follows:

<?xml version="1.0" ?>
 
<container xmlns="http://symfony-project.org/2.0/container">
</container>

The parameters and services are described under a main <container> tag. Notice the usage of the xmlns attribute to avoid the prefixing of all elements in the file.

The official namespace is http://symfony-project.org/2.0/container.

Under the <container> tag, you can any of the three valid tags:

You can only have at most one tag of each type. Each one is described in the following sections.

Placeholders

Most keys and values can use placeholders. A placeholder is a string enclosed in % signs, which is replaced dynamically at runtime by the corresponding parameter value.

Precedence Rules

When loading an XML resource, services definitions overrides the current defined ones.

But for parameters, they are overridden by the current ones. It allows the parameters passed to the container constructor to have precedence over the loaded ones.

$container = new sfServiceContainerBuilder(array('foo' => 'bar'));
$loader = new sfServiceContainerLoaderFileXml($container);
$loader->load('services.xml');

In the above example, even if the loaded resource defines a foo parameter, the value will still be 'bar' as defined in the builder constructor.

Parameters

Each parameter must be defined using a <parameter> tag:

<parameters>
  <parameter>a string</parameter>
</parameters>

By default, the parameter will have a key generated by PHP (as any PHP array). The previous XML is equivalent to the following PHP array:

array('a string')

If you want to create a hash, you can define your own key by using the key attribute:

<parameters>
  <parameter key="foo">a string</parameter>
</parameters>

Which is equivalent to the the following PHP code:

array('foo' => 'a string')

You can also define arrays by changing the type attribute to collection:

<parameters>
  <parameter key="values" type="collection">
    <parameter>foo</parameter>
    <parameter>bar</parameter>
  </parameter>
</parameters>

You can of course nest arrays as you want.

When parsing the XML parameters, the component also casts values automatically:

You can force a special value to be interpreted as a string by using the string type:

<parameters>
  <parameter key="foo">true</parameter>
  <parameter key="bar" type="string">true</parameter>
</parameters>

For the previous example, the converted PHP array will be similar to the following one:

array('foo' => true, 'bar' => 'true')

Parameter values can contain placeholders:

<parameters>
  <parameter key="foo">true</parameter>
  <parameter key="bar">%foo%</parameter>
  <parameter key="baz">The placeholders can be %foo% embedded in a string</parameter>
</parameters>

The previous XML snippet is equivalent to the following PHP code:

array('foo' => true, 'bar' => true, 'baz' => 'The placeholders can be true embedded in a string')

You can escape a % by doubling it:

<parameters>
  <parameter key="foo">The string has no placeholder... %%foo</parameter>
</parameters>

A parameter can also be a reference to a service:

<parameters>
  <parameter key="foo" type="service" id="bar" />
</parameters>

Services

A service is defined by <service> tags:

<services>
  <service id="foo" class="FooClass" />
</services>

The id and class attributes are the minimum required to define a service.

Attributes

A <service> tag supports the following attributes:

Tags

Under the main <service> tag, several other optional tags can be used to further configure a service:

Here is an example that uses most possibilities:

<service id="bar" class="FooClass" shared="true" constructor="getInstance">
  <file>%path%/foo.php</file>
  <argument>foo</argument>
  <argument type="service" id="foo" />
  <argument type="collection">
    <argument>true</argument>
    <argument>false</argument>
  </argument>
  <configurator function="configure" />
  <call method="setBar" />
  <call method="setBar">
    <argument>foo</argument>
    <argument type="service" id="foo" />
    <argument type="collection">
      <argument>true</argument>
      <argument>false</argument>
    </argument>
  </call>
</service>

Anonymous Services

You can also define anonymous services. It is useful when you need to create a service just to be able to pass it to another service constructor, configurator or method call. It you don't need to be able to access it outside of its scope, no need to define a unique id for it, and clutter the main name space.

Defining an anonymous service is as simple as defining an argument of service type, without defining an id, but by providing a <service> definition as an argument:

<services>
  <service id="foo" class="FooClass">
    <argument type="service">
      <service class="BarClass" />
    </argument>
  </service>
</services>

Notice that neither the argument, nor the service attribute has an id defined.

Aliases

You can define an alias for an existing service by using the alias attribute when defining the service:

<services>
  <service id="alias_for_foo" alias="foo" />
</services>

The alias_for_foo service is now an alias of the foo service. Notice that the <service> tag must be empty.

Imports

Before the XML file is parsed, the component first reads the import resources defined under the <imports> tag:

<imports>
  <import resource="services.xml" />
</imports>

If you import many resources, they are interpreted in the same order as they are defined. As one resource can override previous defined parameters and services, the order is significant.

If the resource is a relative path, the resource is first looked for in the same directory as the current XML file. If it is not found, the paths passed to the loader constructor second argument will be looked for one after the other.

By default, the same loader as the current one will be used, but you can also use any other loader class by defining a class attribute:

<imports>
  <import resource="services.xml" />
  <import resource="../ini/parameters.ini" class="sfServiceContainerLoaderFileIni" />
</imports>

The same paths as the original loaders will be passed to the new one.

As parameters are seen as simple key/value pairs by the component, when a value is overridden, the value is replaced with the new value.

For instance, if you have the following two XML files:

file1.xml
<parameter key="complex" type="collection">
  <parameter>true</parameter>
  <parameter>false</parameter>
</parameter>
 
file2.xml
<parameter key="complex">foo</parameter>

When loading file1.xml and file2.xml in this order, the value of complex will be "foo".

powered by symfony - "symfony" is a trademark of Fabien Potencier, all rights reserved - The components "animals" are © 2009 Sensio Labs

The Sensio Labs Network

Since 1998, Sensio Labs has been promoting the Open-Source software movement by providing quality web application development, training, consulting.
Sensio Labs also supports several large Open-Source projects.