Pagina 1 di 1
Domanda teorica
Inviato: 28/07/2010, 1:06
da BMercer
Ok, allora mettiamo di avere una classe per il database che contiene soltando la funzione di costruct di destruct, di query personalizzata, di fetch dei risultati e di liberamento di risultati con free_result.
Il tutto va alquanto bene, dentro la funzione di destruct creiamo la connessione che poi gestiamo con le altre funzioni.
Ma arriva il momento in cui quella classe deve essere espansa per permettere la gestione degli utenti (a cui dedichiamo una tabella nel database) solo con le funzioni. E' ovvio che ci servono le nostre funzioni all'interno della classe del database quindi scriviamo
ora però abbiamo bisogno di una funzione di costruct anche qui che ci permetta di gestire un utente alla volta.
Creaimo una funzione che ricavi tutte le informazioni dell'utente dal database con una select e che le stampi chiamata get_info().
Perfetto, quindi apriamo una nuova pagina e scriviamo:
Codice: Seleziona tutto
include('database.php'); // dove c'è la classe database
include('users.php'); // dove c'è la classe per gli utenti
$db = new database('localhost', 'username', 'password', 'database');
$u = new user(1); // nel costruct passiamo come variabile sempre l'id dell'utente
$u = get_info();
unset($u);
unset($db);
Però sorge un problema. Sembra, anzi è quasi sicuro che sorgano dei conflitti con i due costruct, poichè sembra che il primo costruct della classe database venga ignorato, infatti quello creava il link (come descritto ufficialmente da php.net che dice che sarebbe buona cosa associare la connessione ad un link che poi viene usato come secondo parametro per esempio nelle query mysql_query($sql, $link)) e l'errore mi dice che non è settato alcun link.
Mettiamo il caso che il costruct per la classe user è di obbligo cosa mi consigliate di fare?
Mettendo invece il caso che la funzione costruct della classe user possa venir eliminata, secondo voi potrebbe funzionare come sistema di gestione utenti? Ve ne sono di migliori?
Per favore rispondete ad entrambe le mie ultime 2 domande.
Grazie

Re: Domanda teorica
Inviato: 28/07/2010, 21:34
da Carlo
Credo che il conflitto sia qui:
Codice: Seleziona tutto
$db = new database('localhost', 'username', 'password', 'database');
$u = new user(1); // nel costruct passiamo come variabile sempre l'id dell'utente
Prima crei l'oggetto
$db per la classe
database, e poi crei un nuovo oggetto per la classe
user che a sua volta contiene le funzioni della classe
database? A quale scopo? Hai solo delle "doppie" funzioni.
Per utilizzare le funzioni della classe
database all'interno di
user basta che utilizzi l'oggetto
$db.
Poi un'altra cosa: mi puoi riportare la funzione della classe
database per connetterti al database, e poi la funzione
get_info, che presumo sia della classe
user?
BMercer ha scritto:Mettiamo il caso che il costruct per la classe user è di obbligo cosa mi consigliate di fare?
Mettendo invece il caso che la funzione costruct della classe user possa venir eliminata, secondo voi potrebbe funzionare come sistema di gestione utenti? Ve ne sono di migliori?
Per queste due domande puoi spiegarti meglio? Non mi sono ben chiare.
Re: Domanda teorica
Inviato: 28/07/2010, 22:37
da BMercer
La mia intenzione era separare bene le classi del database, quella principale chiamata database, poi quella per gestire i topic chiamata topic, quella per gestire i post, quella per gestire i forum, quella per gestire gli utenti.
Tutte quante figlie della classe database che come detto contiene le funzioni per connessione (con __costruct), per l'eseguezione delle query, per il fetch dei risultati e per la liberazione mediante mysql_free_result() delle query giganti. Tutte funzioni che in determinati perti del mio cms vorrei non fossero disponibili, quindi in quelle parti utilizzo solo le subclassi figlie in modo che al limite il massimo che si può fare è eseguire comandi preimpostati che quindi limitano di gran lunga i rischi. Alla fine ho deciso di togliere il costruct della classe figlia e mi aveva dato un altro errore che ora come ora non ricordo, non relativo alle parentele comunque. Ti farò sapere domani.
Re: Domanda teorica
Inviato: 29/07/2010, 19:01
da BMercer
Allora ho provato così:
Ho creato la classe del database come già detto con le funzioni che verranno utilizzate dalle classi figlie.
Ho creato dentro la classe del database il costruct e decostruct che rispettivamente apre e chiude la connessione senza il passaggio di alcun parametro, quindi semplicemente così:
Poi ho creato le subclassi utenti, forum, topic, post e ho scoperto con mio grande stupore e felicità che senza istanziare la classe database (che quindi a questo punto credo trasformerò in astratta o cose simili, o no?) ma istanziando solo una subclasse, ad esempio così:
Codice: Seleziona tutto
$u = new users;
$u->create_new($username, $password, $email, $avatar, ecc...);
unset($u);
viene richiamato il costruct della classe database.
Quindi le 3 linee sopra automaticamente aprono la connession non appena è istanziata, eseguono la funzione per creare un nuovo utente e disconnettono dal database. E' una cosa che a mio parere oltre che essere molto funzionale è anche molto sicura. Ti basta istanziare una classe alla volta e ogni volta che istanzi una subclasse si connette al database.
Esempio totale:
Classe database
Codice: Seleziona tutto
class database
{
private $link;
protected function __costruct()
{
$link = mysql_connect(parametri...);
$this->link = link;
mysql_db_select(nome database);
}
protected function __destruct()
{
mysql_close($this->link);
}
// lista funzioni
protected function query($sql)
{
mysql_query($sql, $this->link);
}
ecccc....
}
Classe utenti
Codice: Seleziona tutto
class user extends database
{
public function create_new($username, $password)
{
$this->query('
INSERT INTO utenti blablablbal
');
}
}
Ora facendo così:
Codice: Seleziona tutto
$u = new user; // qui viene richiamata la funzione __ costruct
$u->create_new($_POST['username'], $_POST['password']); // qui esegue la funzione che devi eseguire
unset($u); // richiama la funzione __destruct
Poichè creare 2 subclassi diverse senza chiuderne una provoca un errore di collisione ti verrà sempre in mente di attuare le modifiche al database e poi chiudere la connessione dietro di te.
Non so, non riesco a vedere le falle di questo ragionamento o non ci sono?
Re: Domanda teorica
Inviato: 29/07/2010, 21:47
da Carlo
BMercer ha scritto:Poichè creare 2 subclassi diverse senza chiuderne una provoca un errore di collisione ti verrà sempre in mente di attuare le modifiche al database e poi chiudere la connessione dietro di te.
Non so, non riesco a vedere le falle di questo ragionamento o non ci sono?
Non ti seguo più.

Re: Domanda teorica
Inviato: 30/07/2010, 0:47
da BMercer
Va bè, òascia stare le ultime due righe non sono importanti.
Secondo te potrebbe funzionare come sistema?
Re: Domanda teorica
Inviato: 30/07/2010, 8:43
da Carlo
Però io dico, a che serve "estendere" (per così dire) la classe "database" nella nuova classe "user"?
Una volta che hai creato gli oggetti per entrambe le classi:
all'interno della classe classe "user", poi puoi utilizzare, nelle funzioni, la variabile globale
$db per accedere alle funzioni della classe "database".
E quindi se vuoi estrarre dei dati dal database, fai così:
mysql_query($sql, $db->link);
Ultima cosa. Io non "distruggo" mai gli oggetti a fine script. E' possibile, caso mai, per connettersi o chiudere una connessione al database, creare una funzione apposita.
Re: Domanda teorica
Inviato: 30/07/2010, 14:48
da BMercer
Mi potresti illuminare un pò di più riguardo al porre la classe db come globale? Credo che sia anche il sistema che usa phpbb o no?
Re: Domanda teorica
Inviato: 30/07/2010, 16:47
da Carlo
Sì. Devi semplicemente aggiungere in ogni funzione della classe "user", prima che richiami le funzioni dell'oggetto "database", questo:
che ti permetterà di usufruire al suo interno delle funzioni della classe "database".
Re: Domanda teorica
Inviato: 30/07/2010, 17:01
da BMercer
Ho letto in giro che la keyword global è il diavolo. C'è chi dice che è poco sicuro, c'è chi dice che se la inserisci si crea un buco nero ecc.
Alla fine ho risolto con un sistema molto pratico e nativo solo da php5 : il class chaining.
Ovvero dentro il costruttore della classe user inserisco l'istanza della classe così:
Codice: Seleziona tutto
class user
{
private $db;
public function __construct()
{
$this->db = new database;
}
}
e poi all'interno posso utilizzare le funzioni di tale classe con
Grazie mille come sempre.