PDA

Visualizza la versione completa : Liberare la memoria in PHP, chiusura connessioni, che altro fare?


robynosse
16-03-2016, 14:25
Ciao a tutti,

vorrei liberare la memoria dopo l'esecuzione di una pagina PHP

la prima cosa che faccio, dopo il rendering della pagina è:



Db::close();
echo $html;//contiene l'intera pagina HTML


la classe Db è la seguente:


<?php
class Db implements IConfigDb {
private static $instancia=NULL;
private static $host=self::HOST;
private static $nombre=self::NOMBRE;
private static $pw=self::PW;
private static $dbNome=self::DB;

private function __construct(){}

private function __clone(){}

static function close(){
var_dump(self::$instancia);
var_dump(mysqli_close(self::$instancia));
//mysqli_close(self::$instancia);
}

static function getDBC(){
if(self::$instancia==NULL){
try{
self::$instancia=new mysqli(self::$host, self::$nombre, self::$pw, self::$dbNome);
}catch(Exception $e){
self::$instancia=NULL;
}
}
return self::$instancia;
}
}


Il primo var_dump del metodo statico close(), var_dump(self::$instancia), produce questo risultato:


object(mysqli)[104]
public 'affected_rows' => null
public 'client_info' => null
public 'client_version' => null
public 'connect_errno' => null
public 'connect_error' => null
public 'errno' => null
public 'error' => null
public 'error_list' => null
public 'field_count' => null
public 'host_info' => null
public 'info' => null
public 'insert_id' => null
public 'server_info' => null
public 'server_version' => null
public 'stat' => null
public 'sqlstate' => null
public 'protocol_version' => null
public 'thread_id' => null
public 'warning_count' => null

Il secondo var_dump, var_dump(mysqli_close(self::$instancia)) produce questo risultato:

boolean true

Il risultato, qualsisi pagina utilizzi, è sempre lo stesso, vorrei capire perché tutti i valori sono null, sto sbagliando qualche cosa?

Inoltre, che altre operazioni mi consigliate di effettuare per liberare la menoria il più possibile?

Grazie,
Roberto

Al_katraz984
17-03-2016, 11:25
Perchè usi pattern singleton? e perchè usi msqli?

k.b
17-03-2016, 13:00
Allora, un po' di cose da dire:

- per fare una classe con tutti metodi e proprieta' statiche devi avere una buona ragione (e accade raramente), e questo non e' il caso
- mysqli e' un'interfaccia via-di-mezzo che non ha molta ragione di essere, visto che PDO e' superiore in ogni aspetto: ergo usa PDO
- il fatto che ti dia tutti NULL e' strano, anche sbagliando i dati di accesso almeno la versione del client dovrebbe mostrartela
- la memoria viene liberata automaticamente al termine dell'esecuzione dello script, al limite la tua preoccupazione dev'essere quanta memora usi nello script, ma a liberarla ci pensa PHP da solo

Marcolino's
17-03-2016, 15:30
Già perché Singleton?
Ma anzi perché farlo per aprire una connessione ad un database? ( Sì lo so un tempo era caldamente appoggiata, ci sono script al riguardo persino su HTML.IT ) oggi non lo è più, crea più casini di quanti ne risolva.
Ti consiglio di leggerti questo http://it.phptherightway.com/pages/Design-Patterns.html
Poi sul fatto che sia tutto null, credo c'entri il come sono stati istanziati i valori all'interno della classe, ma non ho tempo di fare prove ora :)

robynosse
19-03-2016, 14:07
Uso mysqli perché il progetto l'ho inziato in una macchina con una versione di php molto vecchia e PDO non si poteva utilizzare.
Uso Singleton per instanziare una sola volta la connessione.
Ho una classe astratta , chiamata 'ModelloPrototipo' che utilizza i metodi statici della classe Db, nella classe ModelloPrototipo sono definiti tutti i metodi che mi permettono di effettuare le operazioni sul DB senza dover scrivere una linea di SQL(le sentenze vengono generate dinamicamente)
Per ogni tabella del db ho una classe Modello_nomeTabella extends ModelloPrototipo dove definisco i metodi specifici a seconda delle esigente specifiche delle operazioni da effettuare.

In definitiva il metodo close() della mia classe, è perfettamente inutile?

robynosse
19-03-2016, 14:16
- per fare una classe con tutti metodi e proprieta' statiche devi avere una buona ragione (e accade raramente), e questo non e' il caso

Come mai dici che non è il caso di creare questi metodi statici?
...non è meglio avere una sola instanza per la connessione al DB piuttosto che crearne varie, 1 per ogni sentenza che si deve effettuare sul DB?
Se non fosse un metodo statico getDBC() dovrei instanziare ogni volta un oggetto per ogni sentenza, mentre così faccio riferimento sempre alla stessa prorietà statica:
private static $instancia

robynosse
19-03-2016, 14:17
msg duplicato

k.b
19-03-2016, 14:32
Come mai dici che non è il caso di creare questi metodi statici?
...non è meglio avere una sola instanza per la connessione al DB piuttosto che crearne varie, 1 per ogni sentenza che si deve effettuare sul DB?
Se non fosse un metodo statico getDBC() dovrei instanziare ogni volta un oggetto per ogni sentenza, mentre così faccio riferimento sempre alla stessa prorietà statica:
private static $instancia

Non e' necessario usare un singleton per riutilizzare una connessione, basta fare piu' query usando lo stesso oggetto $db.

Poi per un singleton e' necessario solo UN metodo statico: quello che restituisce un'istanza della classe, il resto dei metodi e delle proprieta' non ha senso che siano statici (se usi solo metodi e proprieta' statiche di fatto non usi nemmeno un'istanza della classe, ma usi la classe come una libreria di funzioni e variabili globali con un prefisso).

robynosse
19-03-2016, 14:59
Poi per un singleton e' necessario solo UN metodo statico: quello che restituisce un'istanza della classe, il resto dei metodi e delle proprieta' non ha senso che siano statici

Ma come faccio ad usare proprità NON statiche all'interno di un metodo statico?
...non potrei scrivere questo:

self::$instancia=new mysqli(self::$host, self::$nombre, self::$pw, self::$dbNome);

all'interno della classe ModelloPrototipo ho questi 3 metodi:

public function __construct() {
self::$instancia = Db::getDBC();
}

static function getDBC() {
return self::$instancia;
}
protected function ejecutaQuery($sql) {
try {
return self::$instancia->query($sql);
} catch (Exception $e) {
die('Connección error [' . self::$instancia->error . ']');
}
}


Potrei eliminare la classe Db ma l'ho fatto proprio per separare la "logica" di connessione al db da quello che erano i metodi per gestire le operazioni sul db stesso.

I metodi all'interno della classe ModelloPrototipo mi permettono di effettuare delle operazioni del genere all'interno dei controller:


$modello=$this->getModello("nome_tabella");
$modello->aggiorna($arrayDati,$arrayCondizioni);
.
.
.
.
$modello->nuovo($arrayDatiNuovoRecord)

Al_katraz984
22-03-2016, 18:42
Ciao la soluzione al tuo problema si chiama Aggregation che si semplifica in questo modo:



class PDO {
}

class Controller {
private $pdo;

public function __construct( PDO $db ) {
$this->pdo = $db;
}
}

$pdo = new PDO( ... );
// aggrego le due classi
$controller = new Controller( $pdo );


:ciauz:

Loading