Namespaces.txt 5.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133
  1. = How to Use PHP 5.3 Namespaces =
  2. 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 5.3 applications in a clean way.
  3. == Namespace Declaration And Inheritance ==
  4. To define a namespace for a model class, you just need to specify it in a `namespace` attribute of the `<table>` element for a single table, or in the `<database>` element to set the same namespace to all the tables.
  5. Here is an example schema using namespaces:
  6. {{{
  7. #!xml
  8. <?xml version="1.0" encoding="ISO-8859-1" standalone="no"?>
  9. <database name="bookstore" defaultIdMethod="native" namespace="Bookstore">
  10. <table name="book">
  11. <column name="id" required="true" primaryKey="true" autoIncrement="true" type="INTEGER" />
  12. <column name="title" type="VARCHAR" required="true" primaryString="true" />
  13. <column name="isbn" required="true" type="VARCHAR" size="24" phpName="ISBN" />
  14. <column name="price" required="false" type="FLOAT" />
  15. <column name="publisher_id" required="false" type="INTEGER" description="Foreign Key Publisher" />
  16. <column name="author_id" required="false" type="INTEGER" description="Foreign Key Author" />
  17. <foreign-key foreignTable="publisher" onDelete="setnull">
  18. <reference local="publisher_id" foreign="id" />
  19. </foreign-key>
  20. <foreign-key foreignTable="author" onDelete="setnull" onUpdate="cascade">
  21. <reference local="author_id" foreign="id" />
  22. </foreign-key>
  23. </table>
  24. <table name="author">
  25. <column name="id" required="true" primaryKey="true" autoIncrement="true" type="INTEGER"/>
  26. <column name="first_name" required="true" type="VARCHAR" size="128" />
  27. <column name="last_name" required="true" type="VARCHAR" size="128" />
  28. <column name="email" type="VARCHAR" size="128" />
  29. </table>
  30. <table name="publisher" namespace="Book">
  31. <column name="id" required="true" primaryKey="true" autoIncrement="true" type="INTEGER" />
  32. <column name="name" required="true" type="VARCHAR" size="128" default="Penguin" />
  33. </table>
  34. <table name="user" namespace="\Admin">
  35. <column name="id" required="true" primaryKey="true" autoIncrement="true" type="INTEGER"/>
  36. <column name="login" required="true" type="VARCHAR" size="128" />
  37. <column name="email" type="VARCHAR" size="128" />
  38. </table>
  39. </database>
  40. }}}
  41. 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`.
  42. The `publisher` table defines a `namespace` attribute on ots own, which ''extends'' the database namespace. That means that the generated class will be `\Bookstore\Book\Publisher`.
  43. 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`.
  44. '''Tip''': You can use subnamespaces (i.e. namespaces containing backslashes) in the `namespace` attribute.
  45. == Using Namespaced Models ==
  46. 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.
  47. {{{
  48. #!php
  49. <?php
  50. // use an alias
  51. use Bookstore\Book;
  52. $book = new Book();
  53. // or use fully qualified name
  54. $book = new \Bookstore\Book();
  55. }}}
  56. Relation names forged by Propel don't take the namespace into account. That means that related getter and setters make no mention of it:
  57. {{{
  58. #!php
  59. <?php
  60. $author = new \Bookstore\Author();
  61. $book = new \Bookstore\Book();
  62. $book->setAuthor($author);
  63. $book->save();
  64. }}}
  65. The namespace is used for the ActiveRecord class, but also for the Query and Peer classes. Just remember that when you use relation names ina query, the namespace should not appear:
  66. {{{
  67. #!php
  68. <?php
  69. $author = \Bookstore\AuthorQuery::create()
  70. ->useBookQuery()
  71. ->filterByPrice(array('max' => 10))
  72. ->endUse()
  73. ->findOne();
  74. }}}
  75. Related tables can have different namespaces, it doesn't interfere with the functionality provided by the object model:
  76. {{{
  77. #!php
  78. <?php
  79. $book = \Bookstore\BookQuery::create()
  80. ->findOne();
  81. echo get_class($book->getPublisher());
  82. // \Bookstore\Book\Publisher
  83. }}}
  84. '''Tip''': Using namespaces make generated model code incompatible with versions of PHP less than 5.3. Beware that you will not be able to use your model classes in an older PHP application.
  85. == Using Namespaces As A Directory Structure ==
  86. In a schema, you can define a `package` attribute on a `<database>` or a `<table>` tag to generate model classes in a subdirectory (see [wiki:Documentation/1.5/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:
  87. {{{
  88. #!xml
  89. <database name="bookstore" defaultIdMethod="native"
  90. namespace="Foo/Bar" package="Foo.Bar">
  91. }}}
  92. To avoid such repetitions, just set the `propel.namespace.autoPackage` setting to `true` in your `build.properties`:
  93. {{{
  94. #!ini
  95. propel.namespace.autoPackage = true
  96. }}}
  97. 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:
  98. {{{
  99. #!xml
  100. <database name="bookstore" defaultIdMethod="native" namespace="Foo/Bar">
  101. }}}