Newsgroup: it.comp.www.php
Titolo: autoload con metodi

Salve a tutti,
mi chiedevo se fosse possibile fare l'autoload di una classe se in effetti 
uno dei suoi metodi viene utilizzato e non se viene istanziata la classe:
<?php
function __autoload($class_name) {
    require_once $class_name . '.php';
}
$obj  = new MyClass1(); //Non ancora caricata
$obj->Saluta(); //Qui carica
?>
e' fattibile?
ciao e grazie
Dade 

 $obj->Saluta(); //Qui carica
No. Quando istanzi la classe PHP ha bisogno di sapere come e` fatta, per 
allocarla in memoria.
Ma sarei curioso di sapere perche` ti serve una cosa del genere... :)
Bye.

 wrote in message 
news:5k80l1F...@mid.individual.net...

hihihi ora te lo spiego :P
ho circa una decina di classi, e alcune hanno bisogno di certi parametri 
passati al costruttore... siccome non mi piaceva ogni volta in ogni script 
riportare un'intestazione con tanto di configurazione etc, ho creato un 
common.php dove faccio tutti gli include, istanzio tutte le classi con i 
vari costruttori etc, pero' in realta' in common non uso alcun metodo. 
Questo pero' penso che mi appesantisca il server in quanto in ogni script 
carico tutte le classi per poi usare i metodi di 2 o 3 solamente... lo so 
che il sistema migliore, o meglio piu' "leggero" sarebbe quello di 
istanziare gli oggetti nei vari script pero' questo significa una lunga 
lista di include che vorrei evitare! 

 significa una lunga lista di include che vorrei evitare!
Beh, perche` fare gli include? L'autoload e` li` apposta per caricare un 
file solo quando serve.
Metti una classe per file (o vatti dei namespace virtuali e metti n classi 
in ogni file), e, quando ti servono, le istanzi chiamando il costruttore 
con i parametri corretti.
Gia` il fatto che chiami il costruttore con dei parametri ti rende 
necessario caricare la classe, altrimenti dove memorizza i parametri che 
gli passi, e soprattutto come chiama il costruttore? :)
In alternativa, se vuoi anche passare automaticamente dei parametri alla 
classe, dentro l'autoloader fai quello che fai nel tuo common: in base al 
nome della classe richiesta le passi i parametri sul costruttore.
Occhio alla sintassi, in questo caso. Non l'ho mai fatto, non so se la 
classe "esista" e sia gia` istanziata prima del termine dell'autoload.
Bye.

 Bye.
ti riporto qualche riga del common cosi' riesco a spiegarmi meglio :)
--- start common.php ---
<?PHP
	if (is_file(dirname(__FILE__)."/../config.php")){
		require(dirname(__FILE__)."/../config.php");
	} else {
		//esegui installazione
		die();
	}
	define("CLASS_DIR", dirname(__FILE__)."/");
	define("ROOT_WEB",$config["ROOT_WEB"]);
...
	if(!defined(SMARTY_DIR)){
		define('SMARTY_DIR',dirname(__FILE__).'/Smarty/');
		require_once(SMARTY_DIR.'mySmarty.lib.php');
	}
...
	include_once(dirname(__FILE__)."/db.lib.php");
	include_once(dirname(__FILE__)."/Auth.lib.php");
	include_once(dirname(__FILE__)."/Filters.lib.php");
	if(!is_object($db))		$db=new 
db();	if(!is_object($auth))
		$auth=new Auth();	if(!is_object($filters))
		$filters=new Filter();...
	$db->query("SELECT * FROM int_version");
	$version=$db->fetch_result();
?>
--- fine common.php ---
E poi faccio l'include del common.php in ogni pagina php del mio progetto, 
cosi' da avere sempre disponibili le funzioni del db (es: 
$db->query(...); ), authenticazione (ogni pagina php richiama la 
$auth->check_authentication(); che controlla se l'utente che richiama la 
pagina e' autorizzato) etc...
Dici che e' proprio brutto come sistema? A me sembra molto comodo, ma lo 
spreco di risorse e' grande... soprattutto col crescere del progetto e degli 
utenti...
ciao e grazie!
 

fetch_result()
Auth e Filters non so cosa facciano, nel tuo caso, quindi non mi 
esprimo. :)
Suddividi ulteriormente (senza esagerare) i compiti e fai fare a ogni 
classe il suo compito specifico, senza voler raggruppare troppa roba nella 
stessa classe.
Bye.

 Bye.
ma penso che terro' ogni classe in un file... eventualmente faccio un file 
intermedio per configurare le classi che lo necessitano e faccio un require 
di quel file... dai cosi' e' meno brutto :)
Ciao e grazie ancora!
 

 require di quel file... dai cosi' e' meno brutto :)
Mi puoi fare un esempio di quali sono questi parametri richiesti dalle 
classi all'inizializzazione? Magari si trova una soluzione piu` efficiente.
Bye.

 Bye.
Grazie 1000
Dade 

 passarlo alle classi
Allora ci starebbe bene un singleton di configurazione.
Nei costruttori avrai qualcosa tipo
class DB {
 public function __construct()
 {
  $config = Config::getInstance();
  $this->_db = mysql_connect($config["db"]["user"],
                              $config["db"]["passwd"]
                              ...);
 }
}
Nelle pagine usi
$db = new DB();
$res = $db->query("...");
Si caricheranno automaticamente sia la classe DB che la Config, ma 
soprattutto puoi strutturare la Config come vuoi: per leggere da 
parametri preimpostati nella classe, da DB (occhio ai riferimenti 
circolari, non usare la classe DB ;) ), da file, da LDAP, da web, da 
ftp, da quello che vuoi.
Rispetto alla tua soluzione hai una riga in piu` nella pagina, ma nelle 
funzioni e nelle classi ce l'avresti comunque, solo del tipo "global 
$db;" invece di "$db = new DB();", e avresti meno problemi nel caso la 
sovrascrivessi per sbaglio in qualsiasi punto del tuo programma (un 
errore difficilissimo da individuare. Basta un
if ($db = null)
al posto di 
if ($db == null)
e sei fregato con la variabile globale azzerata.
Bye.