The Autoloader
Zend_Loader_Autoloader introduces a comprehensive
autoloading solution for Zend Framework. It has been designed with
several goals in mind:
-
Provide a true namespace autoloader. (Previous incarnations
intercepted all userland namespaces.)
-
Allow registering arbitrary callbacks as autoloaders, and manage
them as a stack. (At the time of this writing, this overcomes some
issues with spl_autoload , which does not allow
re-registering a callback that utilizes an instance method.)
-
Allow optimistic matching of namespaces to provide faster class resolution.
Zend_Loader_Autoloader implements a singleton, making it
unversally accessible. This provides the ability to register additional
autoloaders from anywhere in your code as necessary.
Using the Autoloader
The first time an instance of the autoloader is retrieved, it
registers itself with spl_autoload . You retrieve an
instance using the getInstance() method:
$autoloader = Zend_Loader_Autoloader::getInstance();
By default, the autoloader is configured to match the "Zend_" and
"ZendX_" namespaces. If you have your own library code that uses
your own namespace, you may register it with the autoloader using
the registerNamespace() method. For instance, if your
library code is prefixed with "My_", you could do so as follows:
$autoloader->registerNamespace('My_');
Note: Namespace Prefixes
You'll note that the previous example uses "My_" and not "My".
This is because Zend_Loader_Autoloader is intended
as a general purpose autoloader, and does not make the
assumption that a given class prefix namespace includes an
underscore. If your class namespace does
include one, you should include it when registering your
namespace.
You can also register arbitrary autoloader callbacks, optionally
with a specific namespace (or group of namespaces).
Zend_Loader_Autoloader will attempt to match these
first before using its internal autoloading mechanism.
As an example, you may want to utilize one or more eZcomponents
components with your Zend Framework application. To use its
autoloading capabilities, push it onto the autoloader stack using
pushAutoloader():
$autoloader-> pushAutoloader(array('ezcBase', 'autoload'), 'ezc');
This tells the autoloader to use the eZcomponents autoloader for
classes beginning with "ezc".
You can use the unshiftAutoloader() method to add the
autoloader to the beginning of the autoloader chain.
By default, Zend_Loader_Autoloader does no error
suppression when using its internal autoloader, which utilizes
Zend_Loader::loadClass(). Most of the time, this is
exactly what you want. However, there may be cases where you want to
suppress them. You can do this using
suppressNotFoundWarnings():
$autoloader->suppressNotFoundWarnings(true);
Finally, there may be times when you want the autoloader to load any
namespace. For instance, PEAR libraries do not share a common
namespace, making specifying individual namespaces difficult when
many PEAR components are in use. You can use the
setFallbackAutoloader() method to have the autoloader
act as a catch-all:
$autoloader->setFallbackAutoloader(true);
Note: Loading Classes from PHP Namespaces
Starting in version 1.10.0, Zend Framework now allows loading classes from
PHP namespaces. This support follows the same guidelines and
implementation as that found in the » PHP
Framework Interop Group PSR-0 reference implementation.
Under this guideline, the following rules apply:
-
Each namespace separator is converted to a
DIRECTORY_SEPARATOR when loading from the file system.
-
Each "_" character in the CLASS NAME is converted to a
DIRECTORY_SEPARATOR. The "_" character has no special
meaning in the namespace.
-
The fully-qualified namespace and class is suffixed with ".php" when loading
from the file system.
As examples:
-
\Doctrine\Common\IsolatedClassLoader =>
/path/to/project/lib/vendor/Doctrine/Common/IsolatedClassLoader.php
-
\namespace\package\Class_Name =>
/path/to/project/lib/vendor/namespace/package/Class/Name.php
-
\namespace\package_name\Class_Name =>
/path/to/project/lib/vendor/namespace/package_name/Class/Name.php
Selecting a Zend Framework version
Typically, you will use the version of Zend Framework that the autoloader you
instantiate came with. However, when developing a project, it's often useful to track
specific versions, major or minor branches, or just the latest version.
Zend_Loader_Autoloader, as of version 1.10, offers some features
to help manage this task.
Imagine the following scenario:
-
During development, you want to track the latest version of
Zend Framework you have installed, so that you can ensure the application works
when you upgrade between versions.
When pushing to Quality Assurance, however, you need to
have slightly more stability, so you want to use the latest installed revision
of a specific minor version.
Finally, when you push to production, you want to pin to a
specific installed version, to ensure no breakage occurs if or when you add new
versions of Zend Framework to you server.
The autoloader allows you to do this with the method
setZfPath(). This method takes two arguments, a
path to a set of Zend Framework installations, and a
version to use. Once invoked, it prepends a path to the
include_path pointing to the appropriate Zend Framework
installation library.
The directory you specify as your path should have a tree such as
the following:
ZendFramework/
|-- 1.9.2/
| |-- library/
|-- ZendFramework-1.9.1-minimal/
| |-- library/
|-- 1.8.4PL1/
| |-- library/
|-- 1.8.4/
| |-- library/
|-- ZendFramework-1.8.3/
| |-- library/
|-- 1.7.8/
| |-- library/
|-- 1.7.7/
| |-- library/
|-- 1.7.6/
| |-- library/
(where path points to the directory "ZendFramework" in the above
example)
Note that each subdirectory should contain the directory library,
which contains the actual Zend Framework library code. The individual subdirectory names
may be version numbers, or simply be the untarred contents of a standard Zend Framework
distribution tarball/zipfile.
Now, let's address the use cases. In the first use case, in
development, we want to track the latest source install. We can do
that by passing "latest" as the version:
$autoloader->setZfPath($path, 'latest');
In the example from above, this will map to the directory
ZendFramework/1.9.2/library/; you can verify this by checking the
return value of getZfPath().
In the second situation, for quality assurance, let's say we want
to pin to the 1.8 minor release, using the latest install you have for that release. You
can do so as follows:
$autoloader->setZfPath($path, '1.8');
In this case, it will find the directory
ZendFramework/1.8.4PL1/library/.
In the final case, for production, we'll pin to a specific version
-- 1.7.7, since that was what was available when Quality Assurance tested prior to our
release.
$autoloader->setZfPath($path, '1.7.7');
Predictably, it finds the directory ZendFramework/1.7.7/library/.
You can also specify these values in the configuration file you use with
Zend_Application. To do so, you'd specify the following
information:
[production]
autoloaderZfPath = "path/to/ZendFramework"
autoloaderZfVersion = "1.7.7"
[qa]
autoloaderZfVersion = "1.8"
[development]
autoloaderZfVersion = "latest"
Note the different environment sections, and the different version specified in each
environment; these factors will allow Zend_Application to
configure the autoloader appropriately.
WarningPerformance implications
For best performance, either do not use this feature, or specify a specific Zend
Framework version (i.e., not "latest", a major revision such as "1", or a minor
revision such as "1.8"). Otherwise, the autoloader will need to scan the provided
path for directories matching the criteria -- a somewhat expensive operation to
perform on each request.
The Autoloader Interface
Besides being able to specify arbitrary callbacks as autoloaders,
Zend Framework also defines an interface autoloading classes may
imlement, Zend_Loader_Autoloader_Interface:
interface Zend_Loader_Autoloader_Interface
{
public function autoload($class);
}
When using this interface, you can simply pass a class instance to
Zend_Loader_Autoloader's
pushAutoloader()
and unshiftAutoloader() methods:
// Assume Foo_Autoloader implements Zend_Loader_Autoloader_Interface:
$foo = new Foo_Autoloader();
$autoloader->pushAutoloader($foo, 'Foo_');
Autoloader Reference
Below, please find a guide to the methods available in
Zend_Loader_Autoloader.
Zend_Loader_Autoloader Methods
Method |
Return Value |
Parameters |
Description |
getInstance() |
Zend_Loader_Autoloader |
N/A |
Retrieve the Zend_Loader_Autoloader
singleton instance. On first retrieval, it registers
itself with spl_autoload . This method is static.
|
resetInstance() |
void |
N/A |
Resets the state of the
Zend_Loader_Autoloader singleton instance to
it's original state, unregistering all autoloader callbacks and all
registered namespaces.
|
autoload($class) |
string|FALSE |
|
Attempt to resolve a class name to a file and load it.
|
setDefaultAutoloader($callback) |
Zend_Loader_Autoloader |
|
Specify an alternate PHP callback to use for the
default autoloader implementation.
|
getDefaultAutoloader() |
callback |
N/A |
Retrieve the default autoloader implementation; by default, this is
Zend_Loader::loadClass().
|
setAutoloaders(array $autoloaders) |
Zend_Loader_Autoloader |
|
Set a list of concrete autoloaders to use in the
autoloader stack. Each item in the autoloaders array
must be a PHP callback.
|
getAutoloaders() |
Array |
N/A |
Retrieve the internal autoloader stack. |
getNamespaceAutoloaders($namespace) |
Array |
|
Fetch all autoloaders that have registered to load a
specific namespace.
|
registerNamespace($namespace) |
Zend_Loader_Autoloader |
|
Register one or more namespaces with the default
autoloader. If $namespace is a string,
it registers that namespace; if it's an array of
strings, registers each as a namespace.
|
unregisterNamespace($namespace) |
Zend_Loader_Autoloader |
|
Unregister one or more namespaces from the default
autoloader. If $namespace is a string,
it unregisters that namespace; if it's an array of
strings, unregisters each as a namespace.
|
getRegisteredNamespaces() |
Array |
N/A |
Returns an array of all namespaces registered with the default
autoloader.
|
suppressNotFoundWarnings($flag = null)
|
boolean|Zend_Loader_Autoloader |
|
Set or retrieve the value of the flag used to
indicate whether the default autoloader
implementation should suppress "file not found"
warnings. If no arguments or a NULL value is
passed, returns a boolean indicating the status of the flag;
if a boolean is passed, the flag is set to that
value and the autoloader instance is returned (to
allow method chaining).
|
setFallbackAutoloader($flag) |
Zend_Loader_Autoloader |
|
Set the value of the flag used to indicate whether
or not the default autoloader should be used as a
fallback or catch-all autoloader for all namespaces.
|
isFallbackAutoloader() |
Boolean |
N/A |
Retrieve the value of the flag used to indicate whether
or not the default autoloader should be used as a
fallback or catch-all autoloader for all namespaces.
By default, this is FALSE.
|
getClassAutoloaders($class) |
Array |
|
Get the list of namespaced autoloaders that could
potentially match the provided class. If none match,
all global (non-namespaced) autoloaders are returned.
|
unshiftAutoloader($callback, $namespace = '')
|
Zend_Loader_Autoloader |
-
$callback, required.
A valid PHP callback
-
$namespace,
optional. A string representing a class
prefix namespace.
|
Add a concrete autoloader implementation to the
beginning of the internal autoloader stack. If a
namespace is provided, that namespace will be used
to match optimistically; otherwise, the autoloader
will be considered a global autoloader.
|
pushAutoloader($callback, $namespace = '')
|
Zend_Loader_Autoloader |
-
$callback, required.
A valid PHP callback
-
$namespace,
optional. A string representing a class
prefix namespace.
|
Add a concrete autoloader implementation to the
end of the internal autoloader stack. If a
namespace is provided, that namespace will be used
to match optimistically; otherwise, the autoloader
will be considered a global autoloader.
|
removeAutoloader($callback, $namespace = '')
|
Zend_Loader_Autoloader |
-
$callback, required.
A valid PHP callback
-
$namespace,
optional. A string representing a class
prefix namespace, or an array of namespace strings.
|
Remove a concrete autoloader implementation from
the internal autoloader stack. If a namespace or
namespaces are provided, the callback will be
removed from that namespace or namespaces only.
|
|
|