phpBB Italia chiude!
phpBB Italia ringrazia tutti gli utenti che hanno dato fiducia al nostro progetto per ben 9 anni, e che, grazie al grande lavoro fatto da tutto lo Staff (rigorosamente a titolo gratuito), hanno portato il portale a diventare il principale punto di riferimento italiano alla piattaforma phpBB.

Purtroppo, causa motivi personali, non ho più modo di gestirlo e portarlo avanti. Il forum viene ora posto in uno stato di sola lettura, nonché un archivio storico per permettere a chiunque di fruire di tutte le discussioni trattate.

Il nuovo portale di assistenza per l'Italia di phpBB diventa phpBB-Store.it, cui ringrazio per aver deciso di portare avanti questo grande progetto.

Grazie ancora,
Carlo - Amministratore di phpBB Italia

Domanda teorica

Area di discussione relativa al linguaggio di programmazione web più conosciuto. Il forum è dedicato anche a MySQL, la piattaforma di database più utilizzata con il PHP.
Rispondi
BMercer
Utente
Utente
Messaggi: 205
Iscritto il: 02/09/2009, 12:28
Versione: 3.0.6
Server: UNIX/Linux

Domanda teorica

Messaggio da BMercer » 28/07/2010, 1:06

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

Codice: Seleziona tutto

class user extends database
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 :)

Avatar utente
Carlo
Amministratore
Amministratore
Messaggi: 9957
Iscritto il: 19/04/2009, 10:24
Sesso: Maschio
Versione: 3.2.0
Server: UNIX/Linux
PHP: 7.1.0
Database: MySQL(i) 10.0.27-MariaDB-cll-lve
Località: Puglia
Contatta:

Re: Domanda teorica

Messaggio da Carlo » 28/07/2010, 21:34

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.
MODs | Stili | Traduzioni MOD
Ogni MP contenente una richiesta di supporto verrà ignorato.

BMercer
Utente
Utente
Messaggi: 205
Iscritto il: 02/09/2009, 12:28
Versione: 3.0.6
Server: UNIX/Linux

Re: Domanda teorica

Messaggio da BMercer » 28/07/2010, 22:37

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.

BMercer
Utente
Utente
Messaggi: 205
Iscritto il: 02/09/2009, 12:28
Versione: 3.0.6
Server: UNIX/Linux

Re: Domanda teorica

Messaggio da BMercer » 29/07/2010, 19:01

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ì:

Codice: Seleziona tutto

$db = new database;
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?

Avatar utente
Carlo
Amministratore
Amministratore
Messaggi: 9957
Iscritto il: 19/04/2009, 10:24
Sesso: Maschio
Versione: 3.2.0
Server: UNIX/Linux
PHP: 7.1.0
Database: MySQL(i) 10.0.27-MariaDB-cll-lve
Località: Puglia
Contatta:

Re: Domanda teorica

Messaggio da Carlo » 29/07/2010, 21:47

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ù. :/
MODs | Stili | Traduzioni MOD
Ogni MP contenente una richiesta di supporto verrà ignorato.

BMercer
Utente
Utente
Messaggi: 205
Iscritto il: 02/09/2009, 12:28
Versione: 3.0.6
Server: UNIX/Linux

Re: Domanda teorica

Messaggio da BMercer » 30/07/2010, 0:47

Va bè, òascia stare le ultime due righe non sono importanti.
Secondo te potrebbe funzionare come sistema?

Avatar utente
Carlo
Amministratore
Amministratore
Messaggi: 9957
Iscritto il: 19/04/2009, 10:24
Sesso: Maschio
Versione: 3.2.0
Server: UNIX/Linux
PHP: 7.1.0
Database: MySQL(i) 10.0.27-MariaDB-cll-lve
Località: Puglia
Contatta:

Re: Domanda teorica

Messaggio da Carlo » 30/07/2010, 8:43

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:

Codice: Seleziona tutto

$db = new database;
$user = new user;
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.
MODs | Stili | Traduzioni MOD
Ogni MP contenente una richiesta di supporto verrà ignorato.

BMercer
Utente
Utente
Messaggi: 205
Iscritto il: 02/09/2009, 12:28
Versione: 3.0.6
Server: UNIX/Linux

Re: Domanda teorica

Messaggio da BMercer » 30/07/2010, 14:48

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?

Avatar utente
Carlo
Amministratore
Amministratore
Messaggi: 9957
Iscritto il: 19/04/2009, 10:24
Sesso: Maschio
Versione: 3.2.0
Server: UNIX/Linux
PHP: 7.1.0
Database: MySQL(i) 10.0.27-MariaDB-cll-lve
Località: Puglia
Contatta:

Re: Domanda teorica

Messaggio da Carlo » 30/07/2010, 16:47

Sì. Devi semplicemente aggiungere in ogni funzione della classe "user", prima che richiami le funzioni dell'oggetto "database", questo:

Codice: Seleziona tutto

global $db;
che ti permetterà di usufruire al suo interno delle funzioni della classe "database".
MODs | Stili | Traduzioni MOD
Ogni MP contenente una richiesta di supporto verrà ignorato.

BMercer
Utente
Utente
Messaggi: 205
Iscritto il: 02/09/2009, 12:28
Versione: 3.0.6
Server: UNIX/Linux

Re: Domanda teorica

Messaggio da BMercer » 30/07/2010, 17:01

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

Codice: Seleziona tutto

$this->db->query():
Grazie mille come sempre.

Rispondi

Torna a “PHP - MySQL”

Chi c’è in linea

Visitano il forum: Nessuno e 3 ospiti