How to Use Namespaces

    The generated model classes can use a namespace. It eases the management of large database models, and makes the Propel model classes integrate with PHP applications in a clean way.

    Namespace Declaration And Inheritance

    To define a namespace for a model class, you just need to specify it in the namespace attribute of a <table> element for a single table, or in the <database> element to set the same namespace for all the tables.

    Here is an example schema using namespaces:

    <?xml version="1.0" encoding="ISO-8859-1" standalone="no"?>
    <database name="bookstore" defaultIdMethod="native" namespace="Bookstore">
    
      <table name="book">
        <!-- ... -->
      </table>
    
      <table name="author">
        <!-- ... -->
      </table>
    
      <table name="publisher" namespace="Book">
        <!-- ... -->
      </table>
    
      <table name="user" namespace="\Admin">
        <!-- ... -->
      </table>
    
    </database>
    

    The <database> element defines a namespace attribute. The book and author tables inherit their namespace from the database, therefore the generated classes for these tables will be \Bookstore\Book and \Bookstore\Author.

    The publisher table defines a namespace attribute on its own, which extends the database namespace. That means that the generated class will be \Bookstore\Book\Publisher.

    As for the user table, it defines an absolute namespace (starting with a backslash), which overrides the database namespace. The generated class for the user table will be Admin\User.

    Tip You can use subnamespaces (i.e. namespaces containing backslashes) in the namespace attribute.

    Using Namespaced Models

    Namespaced models benefit from the Propel runtime autoloading just like the other model classes. You just need to alias them, or to use their fully qualified name.

    <?php
    // use an alias
    use Bookstore\Book;
    $book = new Book();
    
    // or use fully qualified name
    $book = new \Bookstore\Book();
    

    Relation names forged by Propel don’t take the namespace into account. That means that related getter and setters make no mention of it:

    <?php
    $author = new \Bookstore\Author();
    $book = new \Bookstore\Book();
    $book->setAuthor($author);
    $book->save();
    

    The namespace is used for the ActiveRecord class, but also for the Query classes. Just remember that when you use relation names in a query, the namespace should not appear:

    <?php
    $author = \Bookstore\AuthorQuery::create()
      ->useBookQuery()
        ->filterByPrice(array('max' => 10))
      ->endUse()
      ->findOne();
    

    Related tables can have different namespaces, it doesn’t interfere with the functionality provided by the object model:

    <?php
    $book = \Bookstore\BookQuery::create()
      ->findOne();
    echo get_class($book->getPublisher());
    // \Bookstore\Book\Publisher
    

    Using Namespaces As A Directory Structure

    In a schema, you can define a package attribute on a <database> or a <table> tag to generate model classes in a subdirectory (see Multi-Component). If you use namespaces to autoload your classes based on a SplClassAutoloader (see http://groups.google.com/group/php-standards), then you may find yourself repeating the namespace data in the package attribute:

    <database name="bookstore" defaultIdMethod="native"
      namespace="Foo\Bar" package="Foo.Bar">
    

    To avoid such repetitions, just set the schema’s autoPackage setting to true in your configuration file:

    propel:
        generator:
            schema:
                autoPackage: true
    <?php
    
    return [
        'propel' => [
            'generator' => [
                'schema' => [
                    'autoPackage' => true
                ]
            ]
        ]
    ];
    {
        "propel": {
            "generator": {
                "schema": {
                    "autoPackage": true
                }
            }
        }
    }
    [propel]
    
    generator.schema.autoPackage = true
    <?xml version="1.0" encoding="ISO-8859-1" standalone="no"?>
    <config>
        <propel>
            <generator>
              <schema>
                <autoPackage>true</autoPackage>
              </schema>
            </generator>
        </propel>
    </config>
    Now Propel will automatically create a `package` attribute, and therefore distribute model classes in subdirectories, based on the `namespace` attribute, and you can omit the manual `package` attribute in the schema: ```xml ```