Imparare oop

luigi777

Utente Attivo
14 Feb 2008
1.086
1
38
43
Massa, Italy
Salve, volevo sapere se è giusto fare cosi la programmazione ad oggetti:
PHP:
<?php
class User {
   
public function register_user($name, $password, $email) 
{		global $db;	
		$db_name = $db->real_escape_string($name);
		$db_password = $db->real_escape_string($password);
		$db_email = $db->real_escape_string($email);
        $md5_password = md5($db_password);
		
		$result = $db->query("SELECT * from users WHERE email = '$email'");
        $no_rows = $result->num_rows;
		
		if ($no_rows == 0) 
		{
        $result = $db->query("INSERT INTO users(name, password, email) values ('$db_name','$md5_password','$db_email')") or die($db->error);
        return $result;
		}
		else
		{
		return FALSE;
		}
		
    }

   public function check_login($email, $password) 
	{
		global $db;
		$db_password = $db->real_escape_string($password);
		$db_email = $db->real_escape_string($email);
    
		$md5_password = md5($db_password);
        
        $result = $db->query("SELECT * from users WHERE email = '$db_email'  and password = '$md5_password'");
        $user_data = $result->fetch_array();
        $no_rows = $result->num_rows;
		
        if ($no_rows == 1) 
		{
     
            $_SESSION['login'] = true;
            $_SESSION['uid'] = $user_data['uid'];
            return TRUE;
        }
        else
		{
		    return FALSE;
		}
    }

    public function get_fullname($uid) 
	{
		global $db;
		$db_uid = $db->real_escape_string($uid);
		
        $result = $db->query("SELECT * FROM users WHERE uid = $db_uid");
        $user_data = $result->fetch_array();
        echo $user_data['name'];
    }
  

    public function get_session() 
	{
            return isset($_SESSION['login']) ? $_SESSION['login'] : false; 
    }

    public function user_logout() {
        $_SESSION['login'] = FALSE;
        session_destroy();
    }
	
	public function get_email($uid)
	{
	global $db;
	$db_uid = $db->real_escape_string($uid);
	$result = $db->query("SELECT * FROM users WHERE uid = $db_uid");
	$user_data =  $result->fetch_array();
	echo $user_data['email'];
	}

}

?>

l'esempio lo preso da qui:
http://www.9lessons.info/2011/02/php-object-oriented-programming.html

ma lo convertito a modo io.. con la classe mysqli a oggetti..

mi date conferma se è cosi programmare a oggetti?

grazie mille e buona giornata.
 
Lo definirei più un elenco di funzioni più che programmazione ad oggetti.


Comunque per il database ti consiglio di crearti una classe a parte che ti faciliti le cose e utilizzando un pattern singleton per non ricorrere ai global

ti mostro un esempio
PHP:
class db{

    //etc......

    //istanza corrente della classe
    private static $instance;
    
   //da chiamare cosi db::getDb() per ricevere l'istanza corrente della classe
    public static function getDb(){
        //se non hai istanziato la classe la istanzia
        if(!self::$instance instanceof db) self::$instance = new db();
        //ritorna con la nuova istanza o quella precedente quindi avrai sempre la principale
        return self::$instance;
    }
}
 
Ultima modifica:
sai se c'è una guida decente che dice come programmare in oop..

perché anche il sistema di registrazione oop di mrwebmaster fa la stessa cosa che vi ho linkato il sito sopra.

non ci sto capendo più nulla-

info guide?

grazie mille.
 
ciao, ho fatto solo che non so come risolvere il problema della global $db.
mi dici come fare e mi protesti fare un esempio?
grazie mille.

come posso fare per la global $db senza scriverla mille volte?

non ho capito l'ultimo messaggio dove hai postato il codice.

mi fai un esempio pratico?

grazie mille di nuovo e buona serata.

ecco il codice:

PHP:
<?php
class Login
{

		public function VerifyLogin()
		{
			global $db;
			$username = $_POST['username'];
			$password = $_POST['password'];
			
			$sql = "CALL LOGIN('".$username."','".$password."');";
			$res = $db->query($sql) or die($db->error);
 
			if($row = $res->fetch_array())
			{
				$_SESSION['auth'] = 1;
				$_SESSION['auth_level'] = $row['auth_level']; 

				$_SESSION['user_id'] = $row['id'];
				header("Location: welcome.php");
			
				die;
			}
			else
			{
				header("Location: ?alert=1");
				
				die;
			}
		}
 
		public function IsAuth()
		{
			if(!isset($_SESSION['auth']))
			{
				header("Location: login.php");
				die;
			}
		}
	
	public function ShowUsername()
		{
			global $db;
			$sql = "SELECT * FROM users WHERE id='".$_SESSION["user_id"]."'";
			$res = $db->query($sql) or die($db->error);
			$row = $res->fetch_array();
			return $row['username'];
		}
 }
 
?>
 
Ti mostro un esempio della classe che intendevo
PHP:
class db{

    //istanza corrente della classe
     private static $instance;
    //istanza di mysqli
     public $mysqli;

    //funzione iniziale che imposta la configurazione per mysqli
    public function __construct($v){
      $this->mysqli = new mysqli($v['host'],$v['user'],$v['pass'],$v['db']) or die('Errore nella connessione: '.$this->mysqli->connect_error);
    }

  //aggiungi delle funzioni personalizzate per semplificare il lavoro, ad esempio per ottenere direttamente un fetch o il numero dei record trovati...
    public function query($query){ 
        $return = $this->mysqli->query($query) or die('Errore nella query '.$this->mysqli->error); 
         return $return;
    }
    public function fetch_diretto($query){ return $this->query($query)->fetch_array(); }
    public function num_rows($query){ return $this->query($query)->num_rows; }
    
   //da chiamare cosi db::getDb() per ricevere l'istanza corrente della classe
    public static function getDb($conf=array()){
        //se non hai istanziato la classe la istanzia
        if(!self::$instance instanceof db) self::$instance = new db($conf);
        //ritorna con la nuova istanza o quella precedente quindi avrai sempre la principale
        return self::$instance;
    }
}

Sennò potresti anche fare tutte le funzioni statiche e richiamarle ovunque vuoi, ad esempio
PHP:
class db{

    //istanza di mysqli
     public static $mysqli;

    //funzione iniziale che imposta la configurazione per mysqli
    public static function connect($v){
      self::$mysqli = new mysqli($v['host'],$v['user'],$v['pass'],$v['db']) or die('Errore nella connessione: '.self::$mysqli->connect_error);
    }

  //aggiungi delle funzioni personalizzate per semplificare il lavoro, ad esempio per ottenere direttamente un fetch o il numero dei record trovati...
    public static function query($query){ 
        $return = self::$mysqli->query($query) or die('Errore nella query '.self::$mysqli->error); 
         return $return;
    }
    public static function fetch_diretto($query){ return self::query($query)->fetch_array(); }
    public static function num_rows($query){ return self::query($query)->num_rows; }
}  

db::connect($array_conf);
//la connessione al db è richiesta ovviamente una sola volta
$sql = db::query($query);
$fetch = $sql->fetch_object();

Ti consiglio la seconda opzione se hai diverse classi invece la prima se devi gestire principalmente da procedurale
 
e come faccio ad implementare nella mia classe login e le altre classi che ho fatto.. dovrei riscriverle tutte da capo.

prima cosa e che uso anche le mysql store procedures.

ora come faccio? non si può mettere public $db?
grazie mi ispiri come fare?

buona serata.
 
e come faccio ad implementare nella mia classe login e le altre classi che ho fatto.. dovrei riscriverle tutte da capo.

prima cosa e che uso anche le mysql store procedures.

ora come faccio? non si può mettere public $db?
grazie mi ispiri come fare?

buona serata.

Invece di gestire tramite la variabile $db gestisci con la sola istanza della classe oppure tramite le funzioni statiche, puoi lasciare cosi oppure cambiarlo, non c'è una procedura obbligata da fare.

ps: cosa intendi per mettere public $db? in tal caso sarebbe una proprietà della classe, da accederci come $this->db, ma ti ripeto che fai prima mettendo le funzioni statiche.
 
dici che va bene anche global $db come dici nell'ultima frase che dici non c'è una procedura da essere usata?

grazie e buona serata.
 
dici che va bene anche global $db come dici nell'ultima frase che dici non c'è una procedura da essere usata?

grazie e buona serata.
Si va bene, ma a quel punto è inutile fare una classe, cioè fai prima facendo un elenco di funzioni con i global.
 
ciao, girando sul web ho trovato questo:
http://www.obiv.it/video-giornale/7-programmazione-oggetti-php-mysqli-class.html

e ho copiato lo script:
PHP:
<?php
session_start();

ini_set('display_errors',1);


class Mysqlimproved {
	// contiene la query
	private $query;
	// connessione e risorsa mysqli
	private $mysqli;
	// risultato con i dati estratti
	private $result;
	
	public function __construct(){
		// Parametri di connessione
		 
		$host = "localhost";
		$user = "root";
		$password = "";
		$database = "database_gigi";
		$charset = 'utf8';
		
		// connessione in construct per non chiamare il metodo
		$this->connect($host, $user, $password, $database, $charset);
	}
	
	public function __destruct(){
		$this->disconnect();
	}

// Metodo per la connessione
	public function connect($host, $user, $password, $database, $charset, $port = null, $socket = null){
		// creare la connessione
		$this->mysqli = new mysqli($host, $user, $password, $database, $port, $socket);
		
		if(mysqli_connect_error()){
			exit('Impossibile connettersi al DataBase'.$mysqli_connect_error);
		} else {
			$this->mysqli->set_charset($charset);
		}
		
		return true;
	}	
// Per Disconnetterci
	public function disconnect(){
		$this->mysqli->close();
		return true;
	}
	
// Per prepaparare la query
	public function prepare($query){
		$this->query = $query;
		return true;
	}
	
// Per eseguire la query
	public function query(){
		if(isset($this->query)){
			$this->result = $this->mysqli->query($this->query);
			if(!$this->result) {
				exit("Errore nell'interrogazione del DataBase: ".$this->mysqli->error);
				return false;
			}
		}	
	}

// Per fettchare , estrare i dati in un Array o Oggetto
	public function fetch($type = 'object'){
		switch($type){
			case 'array':
				$row = $this->result->fetch_array();
				break;
			case 'object':
				$row = $this->result->fetch_object();
				break;
		}
		$this->result->close();
		
		return $row;
	}

// Per ri pulire i dati
	public function escape($data){
		return $this->mysqli->real_escape_string($data);
	}
}


?>

però e la solita storia...

ma come mai devo mettere lo stesso global $db? alle mie funzioni?

esempio:
PHP:
<?php
class Login
{		
		
		public function VerifyLogin()
		{	
			global $db;
			$username = $_POST['username'];
			$password = $_POST['password'];
			
			$sql = "CALL LOGIN('".$username."','".$password."');";
			$res = $db->prepare($sql);
			//$res = $db->query($sql) or die($db->error);
			$db->query();
			if($row = $db->fetch('array'))
			{
				$_SESSION['auth'] = 1;
				$_SESSION['auth_level'] = $row['auth_level']; //la differenza sta qui

				$_SESSION['user_id'] = $row['id'];
				//header("Location: welcome.php");
			
				die;
			}
			else
			{
				header("Location: ?alert=1");
				
				die;
			}
		}

ho messo nel config l'instanza:
$db = new Mysqlimproved;

ma la devo richiamre di nuovo con global.. anche se uso quelle funzione della classe fatta da obiv.

come mai?

io non sto capendo più nulla.

ti ringrazio e buona notte.
 
Beh prima di tutto devi saper distinguere una variabile da una proprietà, $db sarà una nuova istanza della classe di mysqli ma è esterno, è una variabile esterna non una proprietà della stessa classe, e quindi essendo un metodo anche una funzione ha bisogno di ricavare la variabile per poterla utilizzare, e in php il richiamo si fa con global.

Comunque ripeto e ribadisco, per mysqli crea una classe con i metodi STATICI cosi non hai più problemi e puoi richiamarli dove vuoi gestendo sempre la solita istanza di mysqli.

Se non puoi rifare la struttura o ti torna meglio cosi, lasciaci pure global, non è un crimine :p, ma non ho capito perché allora non hai fatto un elenco di funzioni invece di una classe.
 
ciao,

vorrei capire questa frase che hai detto:


Comunque ripeto e ribadisco, per mysqli crea una classe con i metodi STATICI cosi non hai più problemi e puoi richiamarli dove vuoi gestendo sempre la solita istanza di mysqli.

quali sono i metodi statici quelli che hanno private function?

sai sto imparando ora ad fare le classi tramite tutorial fatti cosi e cosi.

mi fai un'esempio?
grazie mille.
 
ciao, ho quasi risolto con questo piccolo codice:
PHP:
class MysqliConnect {

     private static $connection;

     function SQL() {
          if(empty(self::$connection)) {
               self::$connection = new mysqli('localhost', 'root', '', 'database_gigi');
          }
          return self::$connection;
     }
} // MysqliConnect end

l'unico come faccio fare l'error per far che se ho dei errori nella classi mi da gli errori?

io nella logina la chiamo cosi:
PHP:
public function VerifyLogin()
		{	
			
			$username = $_POST['username'];
			$password = $_POST['password'];
			$sql = "CALL SLOGIN('".$username."','".$password."');";
			$res =  MysqliConnect::SQL()->query($sql) or die(MysqliConnect::SQL()->error);  // qui come faccio dirgli di mettere mysqli_error?

			if($row = $res->fetch_array())
			{
				$_SESSION['auth'] = 1;
				$_SESSION['auth_level'] = $row['auth_level']; 

				$_SESSION['user_id'] = $row['id'];
				header("Location: welcome.php");
			
				die;
			}
			else
			{
				header("Location: ?alert=1");
				
				die;
			}
		}
 
quasi risolto: ho esteso la classe e ho messo cosi:

MysqliConnect::SQL()->query($sql) or die(MysqliConnect::SQL()->error);

dimmi se va bene?
grazie mille.
 
In pratica hai fatto un mezzo singleton, comunque anche la funzione SQL() deve essere statica, un metodo statico cioè con 'static' è accessibile ovunque proprio come stavi facendo te

es.
PHP:
Classe::Metodo();
echo Classe::$var;
echo Classe::costante;
oppure (con l'equivalente di $this statico) nella classe self:: al posto del nome della classe

Comunque in questo caso gli errori li dovevi gestire dalla funzione, cioè
PHP:
static function SQL() { 
          if(empty(self::$connection)) { 
               self::$connection = new mysqli('localhost', 'root', '', 'database_gigi') or die(self::$connection->connect_error); 
          } 
          return self::$connection; 
     }
 
Ultima modifica:

Discussioni simili