Visualizzazione dei risultati da 1 a 10 su 10

Discussione: [PHP5] __autoload

  1. #1

    [PHP5] __autoload

    Ciao.
    Mi piacerebbe conoscere il vs parere su
    __autoload

    [list=1][*]la usate[*]la trovate utile[*]che convenzione usate per i nomi delle classi[*]che organizzazione date alle varie classi [*]come gestite gli errori [/list=1]

    Without faith, nothing is possible. With it, nothing is impossible
    http://ilwebdifabio.it

  2. #2
    1. si
    2. si
    3. solitamente le classi si salvano in un file con il nome della classe e l'estensione ".class.php". Esempio: class Pippo{} , la salvi in un file Pippo.class.php. In realtà a mio avviso sarebbe meglio scrivere le classi in questo modo: class.Pippo.php per il semplice fatto che se hai altri file nella stessa cartella (pasticcioso ma possibile), con un sort by name hai le classi raggruppate prima per prefisso, poi per nome, cosa non vera col classico sistema.
    4. l'organizzazione è solitamente per cartelle, partendo da una classica dir classes e varie sotto cartelle per i namespace/ pacchetti
    5. nota dolente ... mi spiego meglio ...


    Io stesso pensavo di aver risolto invece col PHP non si smette mai di imparare. In primis, il controllo in __autoload tipo
    codice:
    if(!class_exists($className)){
        // do stuff per gestire errori o altro
    }
    è completamente inutile, come lo è il require_once.

    __autoload viene chiamata proprio come ultima speranza, ergo se è chiamata la classe non esiste, ci sta poco da fare.

    Un controllo rapido potrebbe essere un ...
    codice:
    if(file_exists($classDir.'/'.$className.'.class.php')){
        // do stuff, carica la classe
    } else {
        // genera un eccezione o ferma tutto perchè non hai un file
    }
    Per le eccezioni ci sono vari metodi ma non tutti sono così fantastici.
    Io stesso proponevo di creare runtime la classe per estendere le eccezioni ma di fatto ci sono casi dove l'eval diventa il male e per queste delicate operazioni più che mai è bene non usarlo.

    Una funzione facile facile quindi potrebbe essere questa
    codice:
    function autoloader($className){
    	static	$classDir	= 'classes/',
    		$classPrefix	= '',
    		$classSuffix	= '.class.php';
    	$classFile		= $classDir.$classPrefix.$className.$classSuffix;
    	$result			= true;
    	if(file_exists($classFile))
    		require	$classFile;
    	else {
    		$result		= false;
    		trigger_error("Unable to load class {$className}. File {$classFile} does not exist.", E_USER_ERROR);
    	}
    	return	$result;
    }
    
    spl_autoload_register("autoloader");
    che grazie alla spl permette di avere più gestori ... sempre che questo abbia un senso nell'uso di tutti i giorni.

    Chiamala pure __autoload e togli la spl se non ti piace.

    Per concludere, questa funzione ci obbliga a salvare ogni classe in un file a parte.
    Questa è una pratica comune in Java, meno famosa o ben vista in Python ed altri linguaggi, dove puoi creare più di una classe nello stesso file e/o namespace.

    Il bello di questa funzione magica è che secondo me semplifica moltissimo la gestione dei requires ovunque tu sia nel tuo applicativo.

    Unica cosa magari è dare un path assoluto o a partire dalla root alla statica $classDir.

    Questa è la mia opinione a riguardo
    Formaldehyde a new Ajax PHP Zero Config Error Debugger

    WebReflection @WebReflection

  3. #3
    Ti ringrazio del rassicurante riassunto
    in rete si trova veramente di tutto con pareri
    contrari sopratutto sulla gestione degli errori.
    (sono già stato bacchettato per una mia implementazione
    che usava eval )

    Non mi resta che iniziare il mio prossimo progetto
    usando sta comoda funzione

    Grazie ancora dei chiarimenti.


    Without faith, nothing is possible. With it, nothing is impossible
    http://ilwebdifabio.it

  4. #4
    Frontend samurai L'avatar di fcaldera
    Registrato dal
    Feb 2003
    Messaggi
    12,924
    andr3a, ti ringrazio per l'approfondimento: in genere studio attentamente ogni dettaglio dei tuoi interventi ed è per questo che mi è sorta una curiosità: da un punto di vista pratico dove hai usato

    trigger_error()

    avresti potuto usare anche

    throw new Exception()


    ? Ovvero che differenza c'è tra i due costrutti in questo caso specifico (oltre al fatto di poter usare il secondo costrutto blocchi try...catch)?

    Grazie


    Fab.

    (P.s. pensi di andare al phpday?)
    Vuoi aiutare la riforestazione responsabile?

    Iscriviti a Ecologi e inizia a rimuovere la tua impronta ecologica (30 alberi extra usando il referral)

  5. #5
    Diciamo che puoi generare eccezioni se vuoi, ma che senza creare runtime la classe è meno utile.

    O meglio ... diciamo che non ho mai visto un'applicativo che per ogni istanza scrive un try catch, mentre ne ho visti a bizzeffe, frameworks compresi, che implementano un error_handler che, anche per generare logs o altro, è secondo me la via più comoda / facile.

    La funzione è facile facile, usatela o modificatela come meglio credete ma spero di aver spiegato meglio il mio punto di vista riguardo il trigger

    P.S. lavoro a Londra da poco e per altri 2 mesi son senza ferie ... niente phpDay quest'anno
    Formaldehyde a new Ajax PHP Zero Config Error Debugger

    WebReflection @WebReflection

  6. #6
    Originariamente inviato da fcaldera
    andr3a, ti ringrazio per l'approfondimento: in genere studio attentamente ogni dettaglio dei tuoi interventi ed è per questo che mi è sorta una curiosità: da un punto di vista pratico dove hai usato

    trigger_error()

    avresti potuto usare anche

    throw new Exception()


    ? Ovvero che differenza c'è tra i due costrutti in questo caso specifico (oltre al fatto di poter usare il secondo costrutto blocchi try...catch)?

    Grazie


    Fab.

    (P.s. pensi di andare al phpday?)

    Dai un occhio a questo thread.





    Ps.
    Come diceva andr3a è sconsigliato usare le exception con
    __autoload.

    @andr3a

    Scusa un attimo ma perchè utilizzi static nella funzione ?

    e il return true o false ha senso solamente se utilizzi
    spl_autoload_register (cioè perde la sua efficacia se rinomini
    la funzione __autoload) sbaglio ?



    Without faith, nothing is possible. With it, nothing is impossible
    http://ilwebdifabio.it

  7. #7
    Originariamente inviato da whisher
    Scusa un attimo ma perchè utilizzi static nella funzione ?
    perche' evito di creare ed assegnare ogni volta 3 variabili che avranno sempre lo stesso valore

    Originariamente inviato da whisher
    e il return true o false ha senso solamente se utilizzi
    spl_autoload_register (cioè perde la sua efficacia se rinomini
    la funzione __autoload) sbaglio ?
    non sbagli ... quella funzione l'ho scritta al volo mentre rispondevo al primo post ed include entrambi i casi ... ma diciamo che puoi riadattarla meglio cosi'

    codice:
    // __autoload
    function __autoload($className){
    	static	$classDir	= 'classes/',
    		$classPrefix	= '',
    		$classSuffix	= '.class.php';
    	$classFile		= $classDir.$classPrefix.$className.$classSuffix;
    	if(file_exists($classFile))
    		require	$classFile;
    	else {
    		trigger_error("Unable to load class {$className}. File {$classFile} does not exist.", E_USER_ERROR);
    	}
    }
    
    
    
    // autoloader con spl
    function yourPrefixAutoloader($className){
    	static	$classDir	= 'classes/',
    		$classPrefix	= '',
    		$classSuffix	= '.class.php';
    	$classFile		= $classDir.$classPrefix.$className.$classSuffix;
    	$result			= file_exists($classFile);
    	if($result)
    		require	$classFile;
    	return	$result;
    }
    
    spl_autoload_register('yourPrefixAutoloader');
    nel secondo caso sara' di fatto la spl a preoccuparsi dell'eccezione. nel primo la generi tu.

    Per concludere, la spl permette di gestire i files per cartelle, ergo l'organizzazione dei files puo' essere migliore.

    codice:
    function yourBasePrefixAutoloader($className){
    	static	$classDir	= 'classes/',
    		$classPrefix	= '',
    		$classSuffix	= '.class.php';
    	$classFile		= $classDir.$classPrefix.$className.$classSuffix;
    	$result			= file_exists($classFile);
    	if($result)
    		require	$classFile;
    	return	$result;
    }
    
    spl_autoload_register('yourBasePrefixAutoloader');
    
    function yourDeepPrefixAutoloader($className){
    	static	$classDir	= 'classes/components/',
    		$classPrefix	= '',
    		$classSuffix	= '.class.php';
    	$classFile		= $classDir.$classPrefix.$className.$classSuffix;
    	$result			= file_exists($classFile);
    	if($result)
    		require	$classFile;
    	return	$result;
    }
    
    spl_autoload_register('yourDeepPrefixAutoloader');
    ... ma bisogna stare attenti a gerarchie e nomi classi ... se due classi hanno lo stesso nome si rischia solo di far casini ...
    Formaldehyde a new Ajax PHP Zero Config Error Debugger

    WebReflection @WebReflection

  8. #8

    ultima perla

    ... o ultimo pirla ? :master:

    appena addata in devpro

    codice:
    function spl_autoload_create($classDir, $classSuffix = '.class.php', $classPrefix = ''){
    	// (C) Andrea Giammarchi - www.devpro.it - Mit Style License
    	spl_autoload_register(create_function('$className',
    		'$className="'.str_replace(
    			'\\\\',
    			'/',
    			sprintf(
    				'%s/%s{$className}%s',
    				$classDir,
    				$classPrefix,
    				$classSuffix
    			)
    		).'";'.
    		'if($result=file_exists($className))'.
    			'require $className;'.
    		'return $result;'
    	));
    }
    Formaldehyde a new Ajax PHP Zero Config Error Debugger

    WebReflection @WebReflection

  9. #9
    Without faith, nothing is possible. With it, nothing is impossible
    http://ilwebdifabio.it

  10. #10
    Una implementazione che ho trovato su
    konstrukt

    Codice PHP:
    function search_include_path($filename) {
        if (
    is_file($filename)) {
          return 
    $filename;
        }
        foreach (
    explode(PATH_SEPARATORini_get("include_path")) as $path) {
            if (
    strlen($path) > && $path{strlen($path)-1} != DIRECTORY_SEPARATOR) {
                
    $path .= DIRECTORY_SEPARATOR;
            }
            
    $f realpath($path.$filename);
            if (
    $f && is_file($f)) {
                return 
    $f;
            }
        }
        return 
    FALSE;

    Codice PHP:
    function k_autoload($class_name) {
      
    $filename str_replace('_''/'strtolower($class_name)).'.php';
      if (
    search_include_path($filename)) {
        require_once(
    $filename);
      }
    }
    spl_autoload_register('k_autoload'); 

    Without faith, nothing is possible. With it, nothing is impossible
    http://ilwebdifabio.it

Permessi di invio

  • Non puoi inserire discussioni
  • Non puoi inserire repliche
  • Non puoi inserire allegati
  • Non puoi modificare i tuoi messaggi
  •  
Powered by vBulletin® Version 4.2.1
Copyright © 2025 vBulletin Solutions, Inc. All rights reserved.