PHP Objects, Patterns and Practice (3rd edition)

(Barry) #1

CHAPTER 5 ■ OBJECT TOOLS


Autoload


In some circumstances, you may wish to organize your classes so that each sits in its own file. There is
overhead to this approach (including a file comes with a cost), but this kind of organization can be very
useful, especially if your system needs to expand to accommodate new classes at runtime (see the
Command pattern in Chapters 11 and 12 for more on this kind of strategy). In such cases, each class file
may bear a fixed relationship to the name of the class it contains, so you might define a ShopProduct class
in a file named ShopProduct.php. Using the PEAR convention, on the other hand, you would name the
file ShopProduct.php, but the class would be named according to its package address:
business_ShopProduct, perhaps.
PHP 5 introduced the autoload() interceptor function to help automate the inclusion of class
files.
autoload() should be implemented by the coder as a function requiring a single argument. When
the PHP engine encounters an attempt to instantiate an unknown class, it invokes the autoload()
function (if defined), passing it the class name as a string. It is up to the implementer to define a strategy
for locating and including the missing class file.
Here’s a simple
autoload() function:


function __autoload( $classname ) {
include_once( "$classname.php" );
}


$product = new ShopProduct( 'The Darkening', 'Harry', 'Hunter', 12.99 );


Assuming that I have not already included a file that defines a class named ShopProduct, the
instantiation of ShopProduct seems bound to fail. The PHP engine sees that I have defined an
__autoload() function and passes it the string "ShopProduct". My implementation simply attempts to
include the file ShopProduct.php. This will only work, of course, if the file is in the current working
directory or in one of my include directories. I have no easy way here of handling packages. This is
another circumstance in which the PEAR naming scheme can pay off.


function __autoload( $classname ) {
$path = strreplace('', DIRECTORY_SEPARATOR, $classname );
require_once( "$path.php" );
}


$y = new business_ShopProduct();


As you can see, the __autoload() function transforms underscores in the supplied $classname to the
DIRECTORY_SEPARATOR character (/ on Unix systems). I attempt to include the class file
(business/shopProduct.php). If the class file exists, and the class it contains has been named correctly,
the object should be instantiated without error. Of course, this does require the programmer to observe
a naming convention that forbids the underscore character in a class name except where it divides up
packages.
What about namespaces? It’s just a matter of testing for the backslash character and adding a
conversion if the character is present:


function __autoload( $classname ) {
if ( preg_match( '/\\/', $classname ) ) {
$path = str_replace('\', DIRECTORY_SEPARATOR, $classname );
} else {
$path = strreplace('', DIRECTORY_SEPARATOR, $classname );
}
require_once( "$path.php" );
}

Free download pdf