2010-04-13 18 views
7

Ho letto di dinamicamente il caricamento dei file di classe in caso di necessità in una funzione come questa:Sostituzione per la funzione __autoload di PHP?

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

$obj = new DB(); 

che caricherà automaticamente DB.class.php quando si effettua una nuova istanza di quella classe, ma ho anche letto un paio di articoli che è brutto usare questo dato che è una funzione globale e qualsiasi libreria che porti nel tuo progetto che ha una funzione __autoload() lo rovinerà.

Quindi qualcuno sa di una soluzione? Forse un altro modo per ottenere lo stesso effetto di __autoload()? Finché non trovo una soluzione adatta, continuerò a utilizzare __autoload() in quanto non inizia a diventare un problema finché non si introducono librerie e simili.

Grazie.

risposta

10

Ho usato il seguente codice per utilizzare spl_autoload_register in un modo che si degrada se isn 't presente, e anche gestire le librerie che utilizzano __autoload, che è necessario includere.

//check to see if there is an existing __autoload function from another library 
if(!function_exists('__autoload')) { 
    if(function_exists('spl_autoload_register')) { 
     //we have SPL, so register the autoload function 
     spl_autoload_register('my_autoload_function');  
    } else { 
     //if there isn't, we don't need to worry about using the stack, 
     //we can just register our own autoloader 
     function __autoload($class_name) { 
      my_autoload_function($class_name); 
     } 
    } 

} else { 
    //ok, so there is an existing __autoload function, we need to use a stack 
    //if SPL is installed, we can use spl_autoload_register, 
    //if there isn't, then we can't do anything about it, and 
    //will have to die 
    if(function_exists('spl_autoload_register')) { 
     //we have SPL, so register both the 
     //original __autoload from the external app, 
     //because the original will get overwritten by the stack, 
     //plus our own 
     spl_autoload_register('__autoload'); 
     spl_autoload_register('my_autoload_function');  
    } else { 
     exit; 
    } 

} 

Quindi, che il codice verifica la presenza di una funzione __autoload esistente, e aggiungerlo alla pila così come il vostro (perché spl_autoload_register disabiliterà il normale comportamento __autoload).

+0

Una buona soluzione, anche se farei la minima modifica usando solo spl_autoload, irrilevante del caricamento automatico esistente, basta caricare la funzione __autoload se esiste, quindi caricare la tua funzione. – Aatch

+0

Sì, puoi farlo anche se, se ti capisco bene, stai semplicemente cambiando se le affermazioni in realtà lo riguardano. – Kazar

3

Utilizzare spl_autoload_register anziché __autoload. Questo ti permetterà di aggiungere la tua funzione autoload nello stack.

+0

penso 'spl_autoload_register' clobbers qualsiasi esistente' __autoload' funzione, quindi se una libreria lo utilizza, si sta cancellando la funzione della biblioteca. Detto questo, se due librerie definiscono entrambe una funzione '__autoload' sei un po 'fottuto comunque! –

+0

Se il codice ha una funzione __autoload esistente, questa funzione deve essere esplicitamente registrata nello stack __autoload. Questo perché spl_autoload_register() sostituirà efficacemente la cache del motore per la funzione __autoload con spl_autoload() o spl_autoload_call(). Questo è preso dalla pagina di manuale – Ololo

0

È possibile utilizzare Zend_Loader. (Supponendo che Zend Framework sia disponibile per voi ...)

6

È possibile utilizzare spl_autoload_register(), aggiungendo qualsiasi magia __autoload() esistente allo stack.

function my_autoload($class) {  
    include($class . '.al.php'); 
} 
spl_autoload_register('my_autoload'); 

if(function_exists('__autoload')) { 
    spl_autoload_register('__autoload'); 
}                       

$f = new Foo; 
4

Il modo corretto sarebbe utilizzare spl_autoload_register. Per salvare una funzione __autoload che qualche 3rd-party introdotto si può mettere quella funzione il caricatore automatico-stack così:

if (function_exists('__autoload')) { 
    spl_autoload_register('__autoload'); 
} 
0

Il meglio che puoi fare è definire il tuo oggetto responsabile del caricamento automatico per qualsiasi sottosistema che stai programmando.

Ad esempio:

class BasketAutoloader 
{ 
    static public function register() 
    { 
    spl_autoload_register(array(new self, 'autoload')); 
    } 

    public function autoload($class) 
    { 
    require dirname(__FILE__).'/'.$class.'.php'; 
    } 
} 
Problemi correlati