class-loading.rst 9.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242
  1. Class Loading
  2. =============
  3. Class loading is an essential part of any PHP application that
  4. makes heavy use of classes and interfaces. Unfortunately, a lot of
  5. people and projects spend a lot of time and effort on custom and
  6. specialized class loading strategies. It can quickly become a pain
  7. to understand what is going on when using multiple libraries and/or
  8. frameworks, each with its own way to do class loading. Class
  9. loading should be simple and it is an ideal candidate for
  10. convention over configuration.
  11. Overview
  12. --------
  13. The Doctrine Common ClassLoader implements a simple and efficient
  14. approach to class loading that is easy to understand and use. The
  15. implementation is based on the widely used and accepted convention
  16. of mapping namespace and class names to a directory structure. This
  17. approach is used for example by Symfony2, the Zend Framework and of
  18. course, Doctrine.
  19. For example, the following class:
  20. .. code-block:: php
  21. <?php
  22. namespace MyProject\Shipping;
  23. class ShippingStrategy { ... }
  24. resides in the following directory structure:
  25. ::
  26. src/
  27. /MyProject
  28. /Shipping
  29. ShippingStrategy.php
  30. Note that the name of "src" or the structure above or beside this
  31. directory is completely arbitrary. "src" could be named "classes"
  32. or "lib" or whatever. The only convention to adhere to is to map
  33. namespaces to directories and classes to files named after the
  34. class name.
  35. Usage
  36. -----
  37. To use a Doctrine Common ClassLoader, you first need to load the
  38. class file containing the ClassLoader. This is the only class file
  39. that actually needs to be loaded explicitly via ``require``. All
  40. other classes will be loaded on demand by the configured class
  41. loaders.
  42. .. code-block:: php
  43. <?php
  44. use Doctrine\Common\ClassLoader;
  45. require '/path/to/Doctrine/Common/ClassLoader.php';
  46. $classLoader = new ClassLoader('MyProject', '/path/to/src');
  47. A ``ClassLoader`` takes two constructor parameters, both optional.
  48. In the normal case both arguments are supplied. The first argument
  49. specifies the namespace prefix this class loader should be
  50. responsible for and the second parameter is the path to the root
  51. directory where the classes can be found according to the
  52. convention mentioned previously.
  53. The class loader in the example above would thus be responsible for
  54. all classes under the 'MyProject' namespace and it would look for
  55. the class files starting at the directory '/path/to/src'.
  56. Also note that the prefix supplied in the first argument need not
  57. be a root namespace but can be an arbitrarily nested namespace as
  58. well. This allows you to even have the sources of subnamespaces
  59. split across different directories. For example, all projects under
  60. the Doctrine umbrella reside in the Doctrine namespace, yet the
  61. sources for each project usually do not reside under a common root
  62. directory. The following is an example of configuring three class
  63. loaders, one for each used Doctrine project:
  64. .. code-block:: php
  65. <?php
  66. use Doctrine\Common\ClassLoader;
  67. require '/path/to/Doctrine/Common/ClassLoader.php';
  68. $commonLoader = new ClassLoader('Doctrine\Common', '/path/to/common/lib');
  69. $dbalLoader = new ClassLoader('Doctrine\DBAL', '/path/to/dbal/lib');
  70. $ormLoader = new ClassLoader('Doctrine\ORM', '/path/to/orm/lib');
  71. $commonLoader->register();
  72. $dbalLoader->register();
  73. $ormLoader->register();
  74. Do not be afraid of using multiple class loaders. Due to the
  75. efficient class loading design you will not incur much overhead
  76. from using many class loaders. Take a look at the implementation of
  77. ``ClassLoader#loadClass`` to see how simple and efficient the class
  78. loading is. The iteration over the installed class loaders happens
  79. in C (with the exception of using ``ClassLoader::classExists``).
  80. A ClassLoader can be used in the following other variations,
  81. however, these are rarely used/needed:
  82. - If only the second argument is not supplied, the class loader
  83. will be responsible for the namespace prefix given in the first
  84. argument and it will rely on the PHP include_path.
  85. - If only the first argument is not supplied, the class loader
  86. will be responsible for *all* classes and it will try to look up
  87. *all* classes starting at the directory given as the second
  88. argument.
  89. - If both arguments are not supplied, the class loader will be
  90. responsible for *all* classes and it will rely on the PHP
  91. include_path.
  92. File Extension
  93. --------------
  94. By default, a ClassLoader uses the ``.php`` file extension for all
  95. class files. You can change this behavior, for example to use a
  96. ClassLoader to load classes from a library that uses the
  97. ".class.php" convention (but it must nevertheless adhere to the
  98. directory structure convention!):
  99. .. code-block:: php
  100. <?php
  101. $customLoader = new ClassLoader('CustomLib', '/path/to/custom/lib');
  102. $customLoader->setFileExtension('.class.php');
  103. $customLoader->register();
  104. Namespace Separator
  105. -------------------
  106. By default, a ClassLoader uses the ``\`` namespace separator. You
  107. can change this behavior, for example to use a ClassLoader to load
  108. legacy Zend Framework classes that still use the underscore "_"
  109. separator:
  110. .. code-block:: php
  111. <?php
  112. $zend1Loader = new ClassLoader('Zend', '/path/to/zend/lib');
  113. $zend1Loader->setNamespaceSeparator('_');
  114. $zend1Loader->register();
  115. Failing Silently and class_exists
  116. ----------------------------------
  117. A lot of class/autoloaders these days try to fail silently when a
  118. class file is not found. For the most part this is necessary in
  119. order to support using ``class_exists('ClassName', true)`` which is
  120. supposed to return a boolean value but triggers autoloading. This
  121. is a bad thing as it basically forces class loaders to fail
  122. silently, which in turn requires costly file_exists or fopen calls
  123. for each class being loaded, even though in at least 99% of the
  124. cases this is not necessary (compare the number of
  125. class_exists(..., true) invocations to the total number of classes
  126. being loaded in a request).
  127. The Doctrine Common ClassLoader does not fail silently, by design.
  128. It therefore does not need any costly checks for file existence. A
  129. ClassLoader is always responsible for all classes with a certain
  130. namespace prefix and if a class is requested to be loaded and can
  131. not be found this is considered to be a fatal error. This also
  132. means that using class_exists(..., true) to check for class
  133. existence when using a Doctrine Common ClassLoader is not possible
  134. but this is not a bad thing. What class\_exists(..., true) actually
  135. means is two things: 1) Check whether the class is already
  136. defined/exists (i.e. class_exists(..., false)) and if not 2) check
  137. whether a class file can be loaded for that class. In the Doctrine
  138. Common ClassLoader the two responsibilities of loading a class and
  139. checking for its existence are separated, which can be observed by
  140. the existence of the two methods ``loadClass`` and
  141. ``canLoadClass``. Thereby ``loadClass`` does not invoke
  142. ``canLoadClass`` internally, by design. However, you are free to
  143. use it yourself to check whether a class can be loaded and the
  144. following code snippet is thus equivalent to class\_exists(...,
  145. true):
  146. .. code-block:: php
  147. <?php
  148. // Equivalent to if (
  149. ('Foo', true)) if there is only 1 class loader to check
  150. if (class_exists('Foo', false) || $classLoader->canLoadClass('Foo')) {
  151. // ...
  152. }
  153. The only problem with this is that it is inconvenient as you need
  154. to have a reference to the class loaders around (and there are
  155. often multiple class loaders in use). Therefore, a simpler
  156. alternative exists for the cases in which you really want to ask
  157. all installed class loaders whether they can load the class:
  158. ``ClassLoader::classExists($className)``:
  159. .. code-block:: php
  160. <?php
  161. // Equivalent to if (class_exists('Foo', true))
  162. if (ClassLoader::classExists('Foo')) {
  163. // ...
  164. }
  165. This static method can basically be used as a drop-in replacement
  166. for class_exists(..., true). It iterates over all installed class
  167. loaders and asks each of them via ``canLoadClass``, returning early
  168. (with TRUE) as soon as one class loader returns TRUE from
  169. ``canLoadClass``. If this sounds like it can potentially be rather
  170. costly then because that is true but it is exactly the same thing
  171. that class_exists(..., true) does under the hood, it triggers a
  172. complete interaction of all class/auto loaders. Checking for class
  173. existence via invoking autoloading was never a cheap thing to do
  174. but now it is more obvious and more importantly, this check is no
  175. longer interleaved with regular class loading, which avoids having
  176. to check each and every class for existence prior to loading it.
  177. The vast majority of classes to be loaded are *not* optional and a
  178. failure to load such a class is, and should be, a fatal error. The
  179. ClassLoader design reflects this.
  180. If you have code that requires the usage of class\_exists(...,
  181. true) or ClassLoader::classExists during normal runtime of the
  182. application (i.e. on each request) try to refactor your design to
  183. avoid it.
  184. Summary
  185. -------
  186. No matter which class loader you prefer to use (Doctrine classes do
  187. not care about how they are loaded), we kindly encourage you to
  188. adhere to the simple convention of mapping namespaces and class
  189. names to a directory structure.
  190. Class loading should be simple, automated and uniform. Time is
  191. better invested in actual application development than in designing
  192. special directory structures, autoloaders and clever caching
  193. strategies for class loading.