downloads | documentation | faq | getting help | mailing lists | licenses | wiki | reporting bugs | php.net sites | links | conferences | my php.net

search for in the

spl_autoload_unregister> <spl_autoload_functions
[edit] Last updated: Fri, 25 May 2012

view this page in

spl_autoload_register

(PHP 5 >= 5.1.2)

spl_autoload_registerEnregistre une fonction comme __autoload()

Description

bool spl_autoload_register ([ callable $autoload_function [, bool $throw = true [, bool $prepend = false ]]] )

spl_autoload_register() enregistre une fonction dans la pile __autoload() fournie. Si la pile n'est pas encore active, elle est activée.

Si votre code dispose déjà d'une fonction __autoload(), alors cette fonction doit explicitement enregistrer la pile __autoload. Ceci est du au fait que spl_autoload_register() remplace le cache du moteur pour la fonction __autoload() par soit spl_autoload(), soit spl_autoload_call().

Si vous devez utiliser plusieurs fonctions d'autochargement, la fonction spl_autoload_register() est faîte pour cela. Elle crée une file d'attente de fonctions d'autochargement, et les exécute les unes après les autres, dans l'ordre qu'elles ont été définies. A contrario, la fonction __autoload() ne peut être définie qu'une seule fois.

Liste de paramètres

autoload_function

La fonction __autoload() à enregistrer. Si aucun paramètre n'est fourni, alors, l'implémentation par défaut de la fonction spl_autoload() sera enregistrée.

throw

Ce paramètre spécifie si spl_autoload_register() doit lancer des exceptions lorsque le paramètre autoload_function n'a pu être enregistré.

prepend

Si ce paramètre vaut TRUE, spl_autoload_register() ajoutera la fonction au début de la pile de l'autoloader au lieu de l'ajouter à la fin de la pile.

Valeurs de retour

Cette fonction retourne TRUE en cas de succès ou FALSE si une erreur survient.

Historique

Version Description
5.3.0 Ajout du support des espaces de noms.
5.3.0 Le paramètre prepend a été ajouté.

Exemples

Exemple #1 Exemple avec spl_autoload_register() comme remplacement d'une fonction __autoload()

<?php

// function __autoload($class) {
//     include 'classes/' . $class . '.class.php';
// }

function my_autoloader($class) {
    include 
'classes/' $class '.class.php';
}

spl_autoload_register('my_autoloader');

// Ou, en utilisant une fonction anonyme à partir de PHP 5.3.0
spl_autoload_register(function ($class) {
    include 
'classes/' $class '.class.php';
});

?>

Exemple #2 Exemple avec spl_autoload_register() où la classe n'est pas chargée

<?php

namespace Foobar;

class 
Foo {
    static public function 
test($name) {
        print 
'[['$name .']]';
    }
}

spl_autoload_register(__NAMESPACE__ .'\Foo::test'); // Depuis PHP 5.3.0

new InexistentClass;

?>

L'exemple ci-dessus va afficher quelque chose de similaire à :

[[Foobar\InexistentClass]]
Fatal error: Class 'Foobar\InexistentClass' not found in ...

Voir aussi



spl_autoload_unregister> <spl_autoload_functions
[edit] Last updated: Fri, 25 May 2012
 
add a note add a note User Contributed Notes spl_autoload_register
Anonymous 03-Feb-2012 05:52
Note that when specifying the third parameter (prepend), the function will fail badly in PHP 5.2
(delphists) at (apollo) dot (lv) 01-Feb-2011 02:57
When using spl_autoload_register() with class methods, it might seem that it can use only public methods, though it can use private/protected methods as well, if registered from inside the class:
<?php

   
class ClassAutoloader {
        public function
__construct() {
           
spl_autoload_register(array($this, 'loader'));
        }
        private function
loader($className) {
            echo
'Trying to load ', $className, ' via ', __METHOD__, "()\n";
            include
$className . '.php';
        }
    }

   
$autoloader = new ClassAutoloader();

   
$obj = new Class1();
   
$obj = new Class2();

?>

Output:
--------
Trying to load Class1 via ClassAutoloader::loader()
Class1::__construct()
Trying to load Class2 via ClassAutoloader::loader()
Class2::__construct()
anthon at piwik dot org 04-Jul-2010 11:02
Think twice about throwing an exception from a registered autoloader.

If you have multiple autoloaders registered, and one (or more) throws an exception before a later autoloader loads the class, stacked exceptions are thrown (and must be caught) even though the class was loaded successfully.
sebastian dot krebs at kingcrunch dot de 24-Mar-2010 11:54
It seems, that  spl_autoload tests, if the class exists, after calling every registered loader. So it breaks the chain, if the class exists and will not call the other loaders

<?php
function a ($c) {
  echo
"a\n";
  class
Bla {} // Usually "include 'path/to/file.php';"
}
function
b ($c) {
  echo
"b\n";
}
spl_autoload_register('a');
spl_autoload_register('b');

$c = new Bla();
?>
Anonymous 16-Mar-2010 09:30
Be careful using this function on case sensitive file systems.

<?php
spl_autoload_extensions
('.php');
spl_autoload_register();
?>

I develop on OS X and everything was working fine. But when releasing to my linux server, none of my class files were loading. I had to lowercase all my filenames, because calling a class "DatabaseObject" would try including "databaseobject.php", instead of "DatabaseObject.php"

I think i'll go back to using the slower __autoload() function, just so i can keep my class files readable
rayro at gmx dot de 04-Jan-2010 04:14
It is never a good idea and a unconscienable concept to create the classes in the autoload function via eval.
It should be a nice feature with these Exception, but i think anyone is able to handle it without this method although. Atm i dont realize for what this is good for...

As i might note, class_exists() will ever define the classes u only want to check for existance, and will therefor ever return true:
<?php
function EvalIsEvil($class) {
  eval(
'class '.$className.'{}');
}
spl_autoload_register('EvalIsEvil');
if (
class_exists($s="IsMyModuleHere")) {
 
// this is no module, but get there with eval()...
 
return new $s();
}
?>
a dot schaffhirt at sedna-soft dot de 27-Jul-2009 09:05
Good news for PHP 5.3 users with namespaced classes:

When you create a subfolder structure matching the namespaces of the containing classes, you will never even have to define an autoloader.

<?php
    spl_autoload_extensions
(".php"); // comma-separated list
   
spl_autoload_register();
?>

It is recommended to use only one extension for all classes. PHP (more exactly spl_autoload) does the rest for you and is even quicker than a semantically equal self-defined autoload function like this one:

<?php
   
function my_autoload ($pClassName) {
        include(
__DIR__ . "/" . $pClassName . ".php");
    }
   
spl_autoload_register("my_autoload");
?>

I compared them with the following setting: There are 10 folders, each having 10 subfolders, each having 10 subfolders, each containing 10 classes.

To load and instantiate these 1000 classes (parameterless no-action constructor), the user-definded autoload function approach took 50ms longer in average than the spl_autoload function in a series of 10 command-line calls for each approach.

I made this benchmark to ensure that I don't recommend something that could be called "nice, but slow" later.

Best regards,
djames at dealerspan dot com 15-May-2009 11:39
This behaves more like a QUEUE than a STACK, since the registry is accessed in FIFO order. The autoloaders are attempted in the order they are defined.
mailinglist dot php at hydras-world dot com 26-Jun-2008 06:07
The automatic generation of classes can be further improved to cater for files that don't actually contain the class they were supposed to contain:

<?php

// code to set include_path...

class AutoloadException extends Exception { }

class
AutoloadClass {

    public static function
autoload($sClassName) {

        @include_once(
$sClassName . '.class.php');

       
// does the class requested actually exist now?
       
if (class_exists($sClassName)) {
           
// yes, we're done
           
return;
        }
       
       
// no, create a new one!
       
eval("class $sClassName {
            function __construct() {
                throw new AutoloadException('Class $sClassName not found');
            }

            static function __callstatic(\$m, \$args) {
                throw new AutoloadException('Class $sClassName not found');
            }
        }"
);
    }
}

spl_autoload_register(array('AutoloadClass', 'autoload'));

?>

You might be able to expand the example above to automatically generate interfaces too...

Enjoy!

DominicC
stanlemon at mac dot com 28-Sep-2007 12:20
Editorial note: The appropriate PHP bug that requests behavior this function emulates is http://bugs.php.net/bug.php?id=42823 . This function does NOT work if there has been an array($obj, 'nonStaticMethod') registered in the autoload stack--while the autoload will be removed, it will be re-registered incorrectly.

The spl_autoload_register() method registers functions in its stack in the order that spl_autoload_register() was called, and subsequently if you want an autoload function to override previous autoload functions you will either need to unregister the previous ones or change the order of the autoload stack.

For example, say in your default implementation of an autoload function you throw an exception if the class cannot be found, or perhaps a fatal error.  Later on in your code you add a second implementation of an autoload function which will load a library that the previous method would fail on.  This will not call the second autoloader method first, but rather will continue to error out on the first method.

As previously mentioned, you can unregister the existing autoloader that errors out, or you can create a mechanism for unregistering and re-registering the autoloaders in the order you want.

Here is a sample/example of how you might consider re-registering autoloaders so that the newest autoloader is called first, and the oldest last:

<?php

// Editorial notes: Small bug and compatibility fixes
// added to the function

function spl_autoload_preregister( $autoload ) {
   
// No functions currently in the stack.
   
if ( ($funcs = spl_autoload_functions()) === false ) {
       
spl_autoload_register($autoload);
    } else {
       
// Unregister existing autoloaders...
       
$compat =
           
version_compare(PHP_VERSION, '5.1.2', '<=') &&
           
version_compare(PHP_VERSION, '5.1.0', '>=');
        foreach (
$funcs as $func) {
            if (
is_array($func)) {
               
// :TRICKY: There are some compatibility issues and some
                // places where we need to error out
               
$reflector = new ReflectionMethod($func[0], $func[1]);
                if (!
$reflector->isStatic()) {
                    throw new
Exception('
                        This function is not compatible
                        with non-static object methods due to PHP Bug #44144.
                    '
);
                }
               
// Suprisingly, spl_autoload_register supports the
                // Class::staticMethod callback format, although call_user_func doesn't
               
if ($compat) $func = implode('::', $func);
            }
           
spl_autoload_unregister($func);
        }
       
       
// Register the new one, thus putting it at the front of the stack...
       
spl_autoload_register($autoload);
       
       
// Now, go back and re-register all of our old ones.
       
foreach ($funcs as $func) {
           
spl_autoload_register($func);
        }
    }
}

?>

Note: I have not tested this for overhead, so I am not 100% sure what the performance implication of the above example are.
harvey dot NO_SPAM dot robin at gmail dot com 10-Feb-2007 06:54
This function is smart enough not to add the same loader twice.  This seems to work for all of the different loader formats.  Example:

<?php
class ALoader
{
  static function
load($class) { return true; }
}

function
anotherLoader($class) {
  return
true;
}

$F = new ALoader;

spl_autoload_register(array('ALoader', 'load'));
spl_autoload_register(array('ALoader', 'load'));
spl_autoload_register(array($F, 'load'));
spl_autoload_register('anotherLoader');
spl_autoload_register('anotherLoader');
var_dump(spl_autoload_functions());

/*
 * Results on PHP5.2 CLI, linux.
 * array(2) {
 *  [0]=>
 *  array(2) {
 *    [0]=>
 *    string(7) "ALoader"
 *    [1]=>
 *    string(4) "load"
 *  }
 *  [1]=>
 *  string(13) "anotherLoader"
 * }
 */
?>
florent at mediagonale dot com 14-Nov-2006 02:19
If your autoload function is a class method, you can call spl_autoload_register with an array specifying the class and the method to run.

* You can use a static method :
<?php

class MyClass {
  public static function
autoload($className) {
   
// ...
 
}
}

spl_autoload_register(array('MyClass', 'autoload'));
?>

* Or you can use an instance :
<?php
class MyClass {
  public function
autoload($className) {
   
// ...
 
}
}

$instance = new MyClass();
spl_autoload_register(array($instance, 'autoload'));
?>

 
show source | credits | sitemap | contact | advertising | mirror sites