Scriptorama.nl

Header image showing a keyboard, mouse, laptop and books on design patterns

Autoload in PHP

Wanneer je in PHP4 een instantie van een class wilt maken die nog niet gedefinieert is krijg je onmiddelijk een fatal error. In PHP5 hoeft dat niet meer het geval te zijn. Een van de features van PHP5 is de functie __autoload(). Deze functie wordt aangeroepen wanneer je een instantie maakt van een nog niet gedefineerde class. Ik zal laten zien hoe je het moet gebruiken en wat de voordelen zijn.

Laat ik eerst illustreren hoe __autoload precies werkt.

PHP:
  1. <?php
  2. function __autoload($class_name) {
  3.   require_once($class_name . '.php');
  4. }
  5.  
  6. /* Probeer een object van een nog niet bestaande
  7. * class te instantieren */
  8. $feestdag = new Pasen();
  9. ?>

Bij het uitvoeren van dit script probeert het een instantie te maken van de class 'Pasen' maar deze class is nog nergens gedefineert. In dat geval zal PHP5 zoeken naar de functie __autoload(). Zoals je ziet kun je deze functie zelf definieren en op deze wijze kun je zelf aangeven waar het script moet zoeken naar de definitie van deze klasse. De implementatie is geheel aan jezelf.

Zoals in de PHP handleiding staat:

One of the biggest annoyances is having to write a long list of needed includes at the beginning of each script (one for each class).

Een groot voordeel is dat je niet meer handmatig al die include's hoeft te doen, dat kan __autoload voor je doen. Deze functie is heel handig als je de PEAR naming conventies gebruikt voor je classes.

The PEAR class hierarchy is also reflected in the class name, each level of the hierarchy separated with a single underscore.

Oftewel, om de class Log_XML_File te laden zal PEAR kijken in het pad Log/XML/ naar het bestand File.php. Hieronder volgt een handige functie om alle classes die deze naamgeving aanhoud te laden:

PHP:
  1. <?php
  2. function __autoload($class_name) {
  3.   $path  = str_replace('_', DIRECTORY_SEPARATOR, $class_name);
  4.   $path .= '.php';
  5.   require_once($path);
  6. }
  7. ?>

De constante DIRECTORY_SEPARATOR, extra-gratis geleverd door PHP zelf, definieert hoe paden uit elkaar geworden houden. Zoals je wellicht wel weet is C:\Program Files\PHP een typisch Windows pad, terwijl /usr/bin/ een typisch *NIX pad is. DIRECTORY_SEPARATOR bevat de waarde ( \ voor Windows of / voor *NIX) die voor het huidige platform van toepassing is.

Let op: Autoload zal maar 1 keer aangeroepen worden bij, ook al maak je twee instanties van de zelfde class.

Je kunt natuurlijk ook de fout in gaan met de __autoload() functie. Het is bijvoorbeeld een slecht idee om een autoloader te schrijven die allerlei directories doorzoekt naar de opgegeven class. Dit zorgt alleen maar voor onnodige overhead. Heb je toch al je classes in verschillende directories staan, bekijk dan juist de Zend Framework of PEAR (komen veelal overeen) structuur eens.

Reageer ook!

Maarten Manders publiceerde een tijdje terug een aardige __autoload() truc: http://www.sitepoint.com/blogs/2005/11/23/whats-your-plan-for-autoload/.

Leave a comment
Line and paragraph breaks automatic, e-mail address never displayed, HTML allowed: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>