Visualizzazione risultati 1 fino 17 di 17

Discussione: [ MySqli ] GetUserById!!!

  1. #1
    Guest

    Predefinito [ MySqli ] GetUserById!!!

    Eccomi tornato con una nuova puntata di: Attenti al Mysqli!
    A parte gli scherzi ragazzi, come al solito, risolvo un problema e me ne spunta un altro, probabilmente è la dinamica di mysqli che mi sfugge. In breve sto cercando di creare una classe che mi permetta di ricavare le informazioni di un utente, semplicemente indicando l'id. Esempio, vorrei scrivere:

    Codice PHP:
    $user = new User;
    $user->getUserById($id_che_scelgo);
    // Ed ora vorrei poter usare tutti i record dell utente
    // Nel database ho tre campi, name, surname, email
    // Vorrei ora estrarre il nome dell'utente con ID '1' e fare tipo:

    echo "Ciao " . $user->name;
    Per la classe ho pensato qualcosa tipo:

    Codice PHP:
    class Users {

    // Metodi
    public function getUserById($user_id) {
    $query = "SELECT * FROM table_users WHERE id = " . $user_id;
    $results = mysqli_query($query);
    $row = mysqli_fetch_array($results);
    $this->user_id = $user_id; // create a property
    $this->name = $row['name']; // create a property
    $this->surname = $row['surname']; // create a property
    return true;
    }

    }
    L'ho trovata su internet, ma non so come utilizzare le proprietà ò.ò
    Help guys!

  2. #2
    L'avatar di javascripter
    javascripter non è connesso Moderatore
    Data registrazione
    14-02-2010
    Messaggi
    1,114

    Predefinito

    Il codice della classe che hai postato è esattamente l'implementazione dell'esempio:
    Codice PHP:
    $user = new User;
    $user->getUserById($id_che_scelgo);
    // Ed ora vorrei poter usare tutti i record dell utente
    // Nel database ho tre campi, name, surname, email
    // Vorrei ora estrarre il nome dell'utente con ID '1' e fare tipo:

    echo "Ciao " . $user->name;
    Cosa non ti è chiaro?
    Ultima modifica di javascripter : 15-09-2013 alle ore 18.03.58

  3. #3
    Guest

    Predefinito

    Gia provato, ma non mi stampa nulla...

    Codice PHP:
    <?php
    include_once("config/config.inc.php");
    $db = new Database; // Avvio la connessione al Database
    $user = new Users; // Avvio la classe users
    ?>
    <!doctype html>
    <html>
    <head>
    <meta charset="utf-8">
    <title><?php echo Info::Sitename . " - " . Info::Version; ?></title>
    </head>

    <body>
    <h1><?php echo Info::Sitename . " - " . Info::Version; ?></h1>
    <h2>Benvenuto su <?php echo Info::Sitename; ?>, attraverso il menù potrai effettuare molte operazioni, accedi o registrati per visualizzare il tuo pannello gestionale.</h2>
    <h3>Menu di navigazione</h3>
    <ul>
    <li><a href="pages/login.php">Accedi</a></li>
    <li><a href="pages/register.php">Registrati</a></li>
    <li><a href="pages/contactus.php">Contattaci</a></li>
    <br>
    <?php

    echo var_dump($user->getUserById(1)); // volevo vedere..il contenuto ( che mi da bool(true)... mah
    echo "Ciao " . $user->name;

    ?>
    </ul>
    </body>
    </html>
    <?php
    $db
    ->close();
    ?>
    Ecco la classe:

    Codice PHP:
    class Users {

    // Metodi
    public function getUserById($user_id) {
    $query = "SELECT * FROM table_users WHERE id = " . $user_id;
    $results = mysqli_query($query);
    $row = mysqli_fetch_array($results);
    $this->user_id = $user_id; // create a property
    $this->name = $row['name']; // create a property
    $this->surname = $row['surname']; // create a property
    return true;
    }
    Questa si trova però in un altra pagina chiamata config.inc.php..

  4. #4
    L'avatar di javascripter
    javascripter non è connesso Moderatore
    Data registrazione
    14-02-2010
    Messaggi
    1,114

    Predefinito

    Allora, il metodo getUserById resituisce true (che è un valore booleano) ecco perché var_dump ti da quel risultato.
    Per effettuare una query devi avere il riferimento alla database (nel tuo caso $db).

    Puoi passare ogni volta alla classe il link al database oppure estrarlo dalle variabili globali.
    Per esempio:
    Codice PHP:
    class User {
    protected
    $db;

    public function
    __construct() {
    $this->db = $GLOBALS["db"];
    }

    /* oppure
    public function __construct(mysqli $db) {
    $this->db = $db;
    }
    */

    public function getById($id) {
    $query = "SELECT * FROM table_users WHERE id = " . (int) $id;
    $results = $this->db->query($query);
    $ret = false;

    if(
    $results) {
    $ret = $results->fetch_object();
    }

    return
    $ret;
    }
    }

    $db = new Database;
    $user = new User; /* oppure new User($db) */

    var_dump( $user->getById(1) );

  5. #5
    Guest

    Unhappy Scusa l'ignoranza!

    Mh non ho capito molto bene, in pratica. Il mio scopo è quello di ottenere Nome e Cognome di un utente, utilizzando la classe user e la relativa funzione getUserById.

    Nel mio sito, utilizzo due pagine, la prima contiene i file di configurazione con la connessione al database, l'altra invece è la index.php e contiene i la pagina precedente attraverso un include_once.

    config.inc.php
    Codice PHP:
    // Constanti per la configurazione del sito.
    class Info {

    const
    Author = "Ernesto Campese",
    Version = "1.0.0",
    Sitename = "",
    Status = "Alpha Version",
    Url = "";

    }

    // Classe per la connessione al database mysql
    class Database extends mysqli {

    // Proprietà del Database: Dati di accesso!
    const HOST = "localhost";
    const
    USER = "ernestocampese.altervista.org";
    const
    PASS = "$$$$$$$";
    const
    DB = "my_ernestocampese";

    // Metodo per la connessione al database
    public function __construct() {
    $mysqli;
    // Richiamo il costruttore della classe mysqli
    $mysqli = parent::__construct(self::HOST, self::USER, self::PASS, self::DB);
    // Effettuo un controllo sulla connessione
    if ($mysqli->connect_errno) {
    die(
    "Connessione Fallita: " . $mysqli->connect_error);
    }
    return
    $mysqli;
    }

    }

    class
    User {

    // Funzione per ottener ei dati
    public function getUserById($user_id) {
    //????
    }
    }
    index.php
    Codice PHP:
    <?php
    include_once("config/config.inc.php");
    $db = new Database; // Avvio la connessione al Database
    $user = new User;
    ?>

    <!doctype html>
    <html>
    <head>
    <meta charset="utf-8">
    <title><?php echo Info::Sitename . " - " . Info::Version; ?></title>
    </head>

    <body>

    <?php

    $user_id
    = 1;
    echo
    $user->getUserById($user_id);
    echo
    $user->name;
    echo
    $user->surname;

    ?>

    </body>
    </html>

    <?php
    $db
    ->close();
    ?>
    Conosco poco la programmazione ad oggetti, mi ci sto avvicinando passo dopo passo, moooolto lentamente, ecco perchè alcune risposte non le capisco, sono ancora un po ignorante al riguardo.

  6. #6
    L'avatar di javascripter
    javascripter non è connesso Moderatore
    Data registrazione
    14-02-2010
    Messaggi
    1,114

    Predefinito

    Nel codice d'esempio che ho postato prima c'è esattamente l'implementazione di quel metodo (l'ho chiamato getById, poiché ripetere user è una sorta di pleonastico).

    Il problema principale è condividere la connessione al database con la classe User.
    Dato che nel tuo codice hai dichiarato la variabile $db = new Database (che è globale, si trova nel blocco principale), puoi accederci con $GLOBALS["db"].
    Altrimenti, devi passarla ogni volta alla classe User (nel metodo __construct).
    Ultima modifica di javascripter : 16-09-2013 alle ore 14.01.04

  7. #7
    Guest

    Predefinito

    Capisco, ora provo il tuo codice, ma vorrei sapere una cosa. Non esiste un altro metodo per evitare l'uso della variabile globale? Un altro modo per fare quello che vorrei fare io? Magari in modo piu semplice?

    -> EDIT <-

    o magari, non posso dare alla classe user, la connessione $mysqli della classe Database? Questa per intenderci: ( dato che stanno nella stessa pagina )

    Codice PHP:
    // Classe per la connessione al database mysql
    class Database extends mysqli {

    // Proprietà del Database: Dati di accesso!
    const HOST = "localhost";
    const
    USER = "ernestocampese.altervista.org";
    const
    PASS = "$$$$$$$";
    const
    DB = "my_ernestocampese";

    // Metodo per la connessione al database
    public function __construct() {
    $mysqli;
    // Richiamo il costruttore della classe mysqli
    $mysqli = parent::__construct(self::HOST, self::USER, self::PASS, self::DB);
    // Effettuo un controllo sulla connessione
    if ($mysqli->connect_errno) {
    die(
    "Connessione Fallita: " . $mysqli->connect_error);
    }
    return
    $mysqli;
    }

    }
    Ultima modifica di ernestocampese : 16-09-2013 alle ore 14.49.42

  8. #8
    L'avatar di javascripter
    javascripter non è connesso Moderatore
    Data registrazione
    14-02-2010
    Messaggi
    1,114

    Predefinito

    Mi sembrava già di avere elencato i due possibili modi...
    Devi necessariamente passare il link del database per eseguire le query nella classe User.

    Per quanto mi riguarda, vedo solo due possibili percorsi:
    1. Usi la variabile globale
    2. Passi il link ad ogni invocazione della classe User (con __construct)


    Avevo scritto il codice per entrambi i modi (la parte commentata tra /* */ è l'alternativa).
    Questo è valido se vuoi mantenere indipendenti le classi Database e User.

    Una soluzione differente potrebbe essere questa, dove la classe Database serve solo a stabilire la connessione:
    Codice PHP:
    class Database {
    protected
    $db;

    public function
    __construct() {
    $this->db = new mysqli("localhost", "user", "", "my_user");
    }
    }

    class
    User extends Database {
    public function
    getById($id) {
    $query = "SELECT * FROM table_users WHERE id = " . (int) $id;
    $results = $this->db->query($query);
    $ret = false;

    if(
    $results) {
    $ret = $results->fetch_object();
    }

    return
    $ret;
    }
    }

    //$db = new Database;
    $user = new User;

    var_dump( $user->getById(1) );
    Ma in questo modo, User va interferire con la parte relativa alla connessione al database.

  9. #9
    Guest

    Predefinito

    Ho scelto la prima parte di codice che mi hai postato, va tutto alla perfezione, ora voglio capire però.

    Quando tu fai l'uso della variabile globale chiamata db, da dove la prendi? Nel senso che, nella funzione tu dici:

    Codice PHP:
    public function __construct() {
    $this->db = $GLOBALS["db"];
    }
    Ora questa variabile globale corrisponde a? A quella che ho aperto nella pagina index.php?

    Inoltre, è buona cosa usare le variabili globali? Sono come le sessioni? vengono salvate nel browser? Ok ora sto per fondermi... :P

    Ultima cosa, ho notato che per estrarre ad esempio il nome, devo fare tutto questo giro di variabili:

    Codice PHP:
    $user = new User; /* oppure new User($db) */
    $dati = $user->getById(1);
    echo
    "<br>" . $dati->name;
    Non c'è nessun altro modo?
    Ultima modifica di ernestocampese : 16-09-2013 alle ore 21.52.58

  10. #10
    L'avatar di javascripter
    javascripter non è connesso Moderatore
    Data registrazione
    14-02-2010
    Messaggi
    1,114

    Predefinito

    Per quanto riguarda le variabili globali, dovresti approfondire la "visibilità" delle variabili ( http://php.net/manual/en/language.variables.scope.php ).
    Non è buona pratica, ma ci sono pochi casi in cui esse sono la scelta più appropriata e diretta (cioè senza inutili giri).
    Non vengono salvate nel browser (d'altronde nemmeno le sessioni lo sono).

    Per quanto riguarda la seconda domanda, cosa intendi per giri di variabili?
    Forse vuoi selezionare l'utente con id specifico direttamente dal costruttore?
    E.s:
    Codice PHP:
    $user = new User(1);
    echo
    $user->name;

  11. #11
    Guest

    Predefinito

    Ecco si intendevo questo, quindi basta rendere la funzione getbyid, quella costruttore?

    Codice PHP:
    class User {

    /* Proprietà della classe */

    // Proprietà che contiene la connessione al database
    protected $db;

    /* Metodi della classe */

    // Metodo costruttore che richiama la variabile globale della connessione
    public function __construct($id) {
    $this->db = $GLOBALS["db"];

    $query = "SELECT * FROM table_users WHERE id = " . (int) $id;
    $results = $this->db->query($query);
    $ret = false;

    if(
    $results) {
    $ret = $results->fetch_object();
    }

    return
    $ret;
    }
    }
    Ho anche provato ma non mi stampa nulla!
    Ultima modifica di ernestocampese : 16-09-2013 alle ore 22.28.08

  12. #12
    L'avatar di javascripter
    javascripter non è connesso Moderatore
    Data registrazione
    14-02-2010
    Messaggi
    1,114

    Predefinito

    Hai controllato la query?
    Prova ad eseguire il var_dump (per vedere che tipo restituisce).
    Ultima modifica di javascripter : 17-09-2013 alle ore 09.16.44

  13. #13
    Guest

    Predefinito

    Ho provato il dump della variabile:

    Codice PHP:
    $user = new User(1);
    echo
    var_dump($user->name);
    Mi restituisce: NULL

  14. #14
    L'avatar di javascripter
    javascripter non è connesso Moderatore
    Data registrazione
    14-02-2010
    Messaggi
    1,114

    Predefinito

    Intendevo di $user.
    Se var_dump($user) resituisce false, sarà colpa della query.
    Controlla se ci sono errori ( $this->db->error ) nell'esecuzione.

    Ah, la variabile $db è dichiarata ovviamente no (prima di $user)?
    Ultima modifica di javascripter : 17-09-2013 alle ore 16.23.25

  15. #15
    Guest

    Predefinito

    ecco il risultato di:

    Codice PHP:
    <?php

    $user
    = new User(1);
    echo
    var_dump($user);
    ?>
    Codice:
    object(User)#2 (1) { ["db:protected"]=> object(Database)#1 (0) { } }
    E comunque si, DB è aperta prima, ecco infatti il codice completo:

    Codice PHP:
    <?php
    include_once("config/config.inc.php");
    $db = new Database; // Avvio la connessione al Database
    ?>
    <!doctype html>
    <html>
    <head>
    <meta charset="utf-8">
    <title><?php echo Info::Sitename . " - " . Info::Version; ?></title>
    </head>

    <body>
    <h1><?php echo Info::Sitename . " - " . Info::Version; ?></h1>
    <h2>Benvenuto su <?php echo Info::Sitename; ?>, attraverso il menù potrai effettuare molte operazioni, accedi o registrati per visualizzare il tuo pannello gestionale.</h2>
    <h3>Menu di navigazione</h3>
    <ul>
    <li><a href="visual/login.php">Accedi</a></li>
    <li><a href="visual/register.php">Registrati</a></li>
    <li><a href="visual/contactus.php">Contattaci</a></li>
    <br>
    </ul>
    <center><img src="graphic/logos/Let it be.png" width="567" height="283" alt=""/></center>
    <?php

    $user
    = new User(1);
    echo
    var_dump($user);
    ?>
    </body>
    </html>
    <?php
    $db
    ->close();
    ?>

  16. #16
    L'avatar di javascripter
    javascripter non è connesso Moderatore
    Data registrazione
    14-02-2010
    Messaggi
    1,114

    Predefinito

    Ora che ci penso, in php il metodo __construct restituisce sempre e solo $this (cioè il suo contesto/scope).
    Pertanto, bisogna implementare qualcosa di diverso.

    Una soluzione particolarmente bella è usare l'accoppiata dei metodi speciali __get e __isset:
    Codice PHP:
    class User {

    /* Proprietà della classe */

    // Proprietà che contiene la connessione al database
    protected $db,
    $fetch = array();

    const
    USER_TABLE = "user_table", // configura queste costanti
    DB_VAR = "db";

    /* Metodi della classe */

    // consente l'override di $user->nome_variabile
    // per poter restituire un valore 'personalizzato'
    public function __get($key) {
    $r = NULL;

    if(
    array_key_exists($key, $this->fetch))
    $r = $this->fetch[$key];

    return
    $r;
    }

    // per capire se $this->nome_variabile
    // è una proprietà valida o meno della classe
    public function __isset($key) {
    return isset(
    $this->fetch[$key]);
    }

    // Metodo costruttore che richiama la variabile globale della connessione
    public function __construct($id) {
    $this->db = $GLOBALS[self::DB_VAR];
    $query = "SELECT * FROM " . self::USER_TABLE . " WHERE id = " . (int) $id;
    $results = $this->db->query($query);
    $this->fetch = $results ? $results->fetch_assoc() : array();
    }
    }
    Avresti potuto fare anche un loop sui dati estratti e impostare dinamicamente le proprietà della classe:
    Codice PHP:
    foreach( $results->fetch_assoc() as $key => $value) {
    $this->$key = $value;
    }
    ma è una soluzione meno corretta poiché non si dichiara la visibilità (public, private, protected).
    Ultima modifica di javascripter : 17-09-2013 alle ore 23.19.06

  17. #17
    Guest

    Predefinito

    Grazie mille, ora provo :)

Regole di scrittura

  • Non puoi creare nuove discussioni
  • Non puoi rispondere ai messaggi
  • Non puoi inserire allegati.
  • Non puoi modificare i tuoi messaggi
  •