Newsgroup: it.comp.www.php
Titolo: organizzazione in classi per pagina che crea un file

Dunque dovrei fare una pagina php che crea un file .html che contiene i
dati (per riga) degli  utenti di un sito.
Tali dati vengono pescati da una tabella users-
Ho cercato  di usare le classi organizzando la cosa in questa maniera:
[CODE]
class User {
 
	  private $user_name;
	  private $pwd; 
	  ...altri dati che ometto per semplificare
 
	  public function __construct($dati) {
			$this->user_name =$dati['USERNAME'];
			$this->pwd = $dati['PASSWORD'];
	  }
	  public function get_username() {
			return $this-> user_name;
	  }
	  public function get_pwd() {
			return $this-> pwd;
	  }
	  ...metodi relativi agli altri dati
 
 }
 class DataManager {
	  private static function _getConnection() { 
		static $mDB;
		$mDB = mysql_connect('localhost', 'root', '')
		  or die("Failure connecting to the database!");
		$Link = mysql_select_db('my_db') or die('Failure selecting the
database!');
		return $mDB;
	  }
 
	  public static function getUserData() {
			$objs = array();
			$sql = "SELECT * FROM users";
			$hDB2=DataManager::_getConnection();
			$res = mysql_query($sql,$hDB2);
			while($row = mysql_fetch_assoc($res)) {
				$objs[] = new User($row);
			}
 
			return $objs;
	  }
}	
questa è la pagina:
<?
$html="<table>";
$dati = DataManager::getUserData();
foreach($dati as $obj) {
 
$html.="<tr><td>".$obj->get_username()."</td><td>".$obj->get_pwd()."</td></tr>";
} 
$html.="<table>";
$fp=fopen("mio_file.html", "w");
fwrite($fp, $html);
?>
[/CODE]
come vi sembra??
grazie
-- 
questo articolo e` stato inviato via web dal servizio gratuito 
http://www.newsland.it/news
 segnala gli abusi ad 
ab...@newsland.it

 
-- 
www.iuz-lab.info

 sono piu' in lista..
scusa ma io devo avere tutta la lista nella mia pagina.
non ho capito come faresti questo metodo e come lo useresti nella pagina
comunque grazie


 comunque grazie
ok forse ci sono.
quel metodo viene chiamato dalla mia pagina e pian piano costruisce l'html
della pagina da creare.
ma quindi la select deve essere chiamata tantisime volte? (se ho capito
quello che intendi)
e poi in qualche modo dovrei tenere traccia dell'ultimo id_utente chiamato
per passare al successivo
č cosě?


dicedo 'la select viene chiamata tantissime volte' intendevo dire che quel
metodo viene invocato finchè gli utenti non terminano e ogni volta tira
fuori un record


 grazie
Pare buono, se non che hai i dati di connessione hardcoded dentro la  
classe DataManager.
O perchi da un file di configurazione o (ancora meglio) passi la  
connessione come parametro.
$dati = DataManager::getUserData (new MysqlConnection());
Ovviamente questo è meno flessibile, perchè aggiungi un parametro ad una  
funzione che potrebbe averne altri.
$Connection = new MysqlConnection();
$DataManager = new DataManager ($Connection);
$dati = $DataManager->getUserData ();
Il punto non è risparmiare qualche riga di codice, quanto ottenere una  
struttura sobria, comprensibile e flessibile.
Uno dei vantaggi della classe user, ad esempio, è il fatto di non  
contenere meccanismi di caricamento dati di sorta. Questo permette di  
utilizzare la logica della classe con dati presi da qualsiasi luogo.
Un esempio (troppo) semplicistico: $user = new user ($_POST);
Comunque mi piace.
Tac
-- 
La netiquette prevede sign di al massimo quattro righe.
Purtroppo la mia sign in quattro righe non ci stà.

 ha scritto nel messaggio 
news:dtsbhk$r6c$1...@news.newsland.it...

Ciao Io cercherò di essere un pò più critico ma spero anche costruttivo :-)
1) Nella classe DataManager secondo me stai abusando dell'utilizzo dei 
metodi statici (tieni conto che non si usano solo per non fare un bel new)
anche se la loro appliccazione in linguaggio tipo php ancora non mi è 
chiarissima.
2)Sempre relativo alla classe DataManger è troppo rigida come dice anche 
TAC, esempio: se devi selezionare un'altro db che fai ? devi modificare il 
codice ...
3) Eviterei anche anche quel getUserData nella classe dataManager (Già il 
nome è troppo generico , tiene conto che una classe deve avere uno specifico 
"ruolo" ed i suoi confini devono essere bene marcati)
inoltre nel caso ti servano documenti,news,articoli,report ,statistiche dove 
li metti tutti la ?
si creerebbe un casino poco controllabile...
Devi avere le idee più chiare nel senso fatti queste domande
cosa mi serve ?
come lo devo usare ?
etc. etc.
e sopratutto quando progetti una classe tieni bene a mente che fa una cosa e 
basta ma ancora cosa più importante basati sulla sua interfaccia
non su come implementi.
Poi vabè forse sono stato troppo pignolo bisogna un pò vedere a cosa punti

Non conosci ancora 'Joe Natta'? Ti esorto calorosamente a visitare il
suo sito a: 
www.joenatta.com
 !
Ciao, io sono Alessandro Saitta di 37 anni (da compiere il 25 Maggio
2006) abitante a Follonica(GR) ITALIA in via Cassarello,
131. Sono un esibizionista al quale non piace stare tra la gente (così
evito ogni sorta di problema, quali litigi. incidenti,
furti, ecc.), in particolar modo  nelle comunità dove tutto viene
obbligatoriamente condiviso (spese, doveri, ecc.) e si
vuole far affermare l'uguaglianza e la solidarietà tra gli individui.
Non mi piacciono le norme, le regole, il dialogo,
l'educazione, il perbenismo, la cultura, che sono  valori
imprescindibili nelle comunità, quindi l'unico modo per appagare
questo mio egocentrismo, sono riuscito a trovarlo diventando uno
spammer (dato che in Rete posso farmi pubblicità anche senza
uscire di casa e standomene tranquillo per i cazzi miei).  Però io non
faccio pubblicità per denaro, dato che il denaro nella
vita serve solo ai burattini e neppure ho qualcosa da dire giacché
ritengo che tutti i grandi temi della nostra società
(politica, scienza, tecnologia, sport, spettacolo, informazione,
medicina, legge, ecc.) siano solo cose superflue ed inutili
alla vita (chi dice che esse siano cose serie, può essere solo un
pappagallo idiota od un burattinaio). Se una persona ha le
'palle' oltre ad un po' d'intelligenza riesce a vivere bene anche da
solo, senza rompersi il cazzo a trovare compromessi per
andare d'accordo con gli altri.
Io voglio solo che il mio nome sia letto dappertutto e questo è
l'unico scopo della mia vita da spammer. Soddisfazione la
ottengo anche dal riuscire ad essere famoso evitando di sforzarmi nel
pensare, dire o fare qualcosa di particolare e/o
impegnativo, come invece è obbligata a fare la massa.
P.S. Negli ultimi tempi, nei pomeriggi dal lunedì al Venerdì, mi
trovi anche presso l'ufficio 'RAS assicurazioni' di via
Cassarello 88/90 dove faccio compagnia alla mia amica Serena nelle sue
dure giornate lavorative (ma io non ci lavoro... Non 
pensate male :).

 punti
Forse parlare di interfaccie per ora è un po' troppo, si.


ringrazio entrambi.
la classe DataManger è troppo rigida, è vero (e tra l'altro TAC mi aveva
già spiegato questa cosa)
la questione dei metodi statici me la devo vedere  meglio ma forse in
questo caso non ho sbagliato.
la critica n° 3 di yag non la ho capita; doverei crearmi una classe
separata che ha un metodo analogo a getUserData ? che è un 'table
gateway'??
un'ultima cosa: per quanto riguarda ls soluzione proposta da iuz e il
fatto che 'caricare tutti gli utenti e poi ritornare tutto il blocco e'
dispendioso e in caso di tanti utenti rischi di superare il limite di
memoria.. ' che mi dite???
comunque è la terza volta che provo delle classi in php(con qualche
piccola esperienza in java). non mi semrba di essere andato malissimo.
preferisco procedere così dal basso che iniziare con le interfacce e con
altre cose troppo complicate. al massimo riprogettare tutto
successivamente alla luce di nuove consocenza, è importante partire ora
grazie ancora


 successivamente alla luce di nuove consocenza, è importante partire ora
Direi anch'io.


 applicata in modo errato.
[..]
considerando che lo script di diana_est e' stato per sua ammissione
esemplificato e che raggiunge circa +400KB per ogni 1000 utenti io
inizierei a riflettere su una alternativa meno dispendiosa..
dal punto di vista dell'uso della memoria l'approccio usato da diana_est
arriva ad utilizzare un valore massimo della memoria che corrisponde a
qualcosa di simile ad i+x*n*2 dove i e' un valore fisso, x e' lo spazio
medio dedicato ai dati di un utente ed n e' il numero degli utenti..
strutturando in modo diverso si sarebbe potuto raggiungere qualcosa di
simile ad i+x*2.. che IMHO e' preferibile..
ho semplificato ed approssimato le formule sino a renderle risibili.. ma non
mi pareva il caso di dilungare..
-- 
www.iuz-lab.info

 mi pareva il caso di dilungare..
intanto ringrazio tutti di nuovo.
ma iuz tu quindi suggeriresti di creare un metodo che restituisce un solo
utente e eseguire quel metodo (e quindi la select) un numero di volte pari
a quello degli utenti?? e in qualche maniera quindi memorizzare l'ultimo
utente tirato fuori per passare al successivo.
vi chiedo un'ultima cosa: nella mia classe non ho messo un metodo che
chiude la connessione perchè facendo delle prove non mi sembrava ci
fossero problemi. penso cmq sia sbagliato.
in questo caso come e dove deve essere tale metodo?
grazie




Per carità. Ma nel momento in cui volesse mostrare 1000 utenti sulla  
pagina il problema probabilmente sarebbe altrove.
Inoltre non vedo perchè aggiungere un livello di complicazione tale  
adesso, si può fare refactoring dopo.


 Tac
che problemi ci potrebbero essere??
si risolverebbero come ha detto Iuz o in quale altra maniera?
ma la mia interpretazione di quel che ha detto iuz è corretta?('creare un
metodo che restituisce un solo utente e eseguire quel metodo (e quindi la
select) un numero di volte pari a quello degli utenti')
grazie


 in questo caso come e dove deve essere tale metodo?
Nella stessa classe che contiene l'apertura della connessione, qualunque  
essa sia.


 utente tirato fuori per passare al successivo.
[..]
no non hai capito cio' che intendevo..
il codice sotto non e' completamente testato e naturalmente e' decisamente
migliorabile ma credo che ti fara' capire quello che intendevo dire..
<?php
error_reporting(E_ALL);
class User {
 private $userInfo;
 public function __construct($userInfo) {
  if(is_array($userInfo) && isset($userInfo['USERNAME']) &&
isset($userInfo['PASSWORD']))
   $this->userInfo = $userInfo;
  else
   throw new UserInvalidInfo("Invalid user info.");
 }
 public function getUsername () {
  return $this->userInfo['USERNAME'];
 }
 public function getPassword () {
  return $this->userInfo['PASSWORD'];
 }
}
class MysqlLink {
 private $dbl;
 function __construct ($host, $user, $pass, $db) { 
  $this->dbl = @mysql_connect($host, $user, $pass, true);
  if(!$this->dbl)
   throw new MysqlLinkConnectionFailure("Bad host or user or pass.");
  if(!mysql_select_db($db))
   throw new MysqlLinkDatabaseNotFound("Unable to select database.");
  }
  public function getLink () {
   return $this->dbl;
  }
}
class UserDataManager {
 private $result;
 public function __construct ($dbl, $table) {
  $this->result = mysql_query("SELECT * FROM `" .
mysql_real_escape_string($table) . "` WHERE 1", $dbl->getLink());
  if(!$this->result)
   throw new UserDataManagerQueryFailure(mysql_errno() . ': ' .
mysql_error());
 }
 public function getNextUser() {
  $currentUser = mysql_fetch_assoc($this->result);
  return $currentUser ? new User($currentUser) : false;
 }
}
class MysqlLinkConnectionFailure extends Exception {}
class MysqlLinkDatabaseNotFound extends Exception {}
class UserDataManagerQueryFailure extends Exception {}
class UserInvalidInfo extends Exception {}
$fp = fopen('mio_file.html', 'w');
fwrite($fp, '<table>');
$users = new UserDataManager(new MysqlLink('localhost', 'root', '',
'my_db'), 'users');
while($user = $users->getNextUser()) {
 fwrite($fp,
"<tr><td>{$user->getUsername()}</td><td>{$user->getPassword()}</td></tr>");
}
fwrite($fp, '</table>');
?>
-- 
www.iuz-lab.info

 select) un numero di volte pari a quello degli utenti')
Quello che intendeva iuz lo sa solo lui.
La soluzione che ha dato è buona, ovviamente dipende da come implementi  
(se fai, ad esempio, una query per ogni record, diventano un casino di  
query e altro che problemi di memoria - ovviamente ci sono metodi migliori  
di fare la stessa cosa).
Iuz non ha detto certo una cosa sbagliata, il punto è che la flessibilità  
del sistema, in un certo senso, ne perde. Ad esempio un approccio simile  
al suo potrebbe essere questo:
$UserManager = new UserManager();
$UserManager->find();
echo '<table>';
while ( $user = $UserManager->fetch() )
{
	echo '<tr><td>$user->name</td></tr>';
}
$UserManager->close();
echo '</table>';
Và benissimo, ma cominciano ad esserci un po' troppi metodi in questa  
pagina, che usano logica che appartiene di per se alla classe UserManager.  
Vuol dire che nel momento in cui cambi uno dei metodi, devi fare il giro  
delle pagine e cambiare tutte le pagine (che sono meno testabili delle  
classi in sè).
Non vorrei sovraccaricare troppo il discorso.
Ma piuttosto che farsi seghe con i problemi di memoria, nel momento in cui  
cominciano ad esserci troppi utenti farei piuttosto qualcosa di questo  
tipo:
$UserManager = new UserManager();
$users = $UserManager->getRange (20,40);
echo '<table>';
foreach ($users as $user)
{
	....
}
echo '</table>';
echo 'vai a pagina 2[link]';
Motivo per cui, a me, piace piu' l'approccio che hai scelto, secondo me  
per ora và piu' che bene. Prima di implementare un certo tipo di soluzioni  
(caricare 1000 utenti tutti in una volta), aspetterei di sentirne la  
necessità (a meno che tu non abbia la certezza assoluta che succederà).


 echo 'vai a pagina 2[link]';
beh chi mi ha dato da fare la pagina vuole tutti gli utenti sulla stessa
pagina .html per cui i problemi di usabilità saranno suoi (effettivamente
gli utenti potrebbero essere 1000)
la soluzione di iuz me la guardo dopo perchè è lunghetta-
quella che proponi tu qui sopra potrei farla ma svolgendola tutta in
un'unica pagina. 
il problema se ho capito è non creare un array enorme.
potrei fare un ciclo e chiamare il metodo getRange piu volte ognivolta
scaricando l'array.
dopo mi rileggo tutto, ora ho unpo' di confusione.


 grazie
non capisco poi quanto sia rilevante la questione della memoria
ammettiamo che ci siano molti utenti e lasciamo stare l'usabilità. la mia
prima soluzione è cosi pericolosa per la memoria?
nel senso: visto che sono agli inizi non vorrei considerare problemi che
magari sono tipici di programmatori esperti.


 
fermo restando che vuoi solo riportare nome utente e password con una
configurazione di default di php gli utenti che saresti in grado di
trattare sono circa 20000 con user e pass di lunghezza media di 8
caratteri..
quindi il problema e' relativamente trascurabile..
se inizi ad aggiungere anche altri dati quali email, date etc.. il numero di
utenti trattabili scende molto velocemente..
per me questa e' una limitazione da considerare sin dall'inizio.. ma e' solo
il mio punto di vista..
-- 
www.iuz-lab.info

 il mio punto di vista..
iuz ok io il problema lo considero (per ora potrebbero essere 1000 ma con
piu' campi). appena ho tempo mi guardo tutto, ora non ce la faccio.
speravo fosse una questione da esperti ma evidentemente...


 grazie
ho provato la soluzione di iuz.
se ho capito bene si avrebbe un risparmio perchè non si creerebbe
quell'enorme array di oggetti User
infatti tramite la funzione
public function getNextUser() {
			$currentUser = mysql_fetch_assoc($this->result);
			return $currentUser ? new User($currentUser) : false;
} 
scorro su un record alla volta e restituisco un oggetto User alla volta.
sto dicendo baggianate?
ora mi converrà usare questa soluzione o una soluzione analoga solo in
caso di molti Utenti con molti dati.
spero di essere arrivato ad un punto fermo appprovato da tutti :-)
TAC io l'ho capita così; se tu vedi una soluzione per mantenere la
flessibilità e nello stesso tempo gestire tanti utenti dimmela che mi fai
un gran favore (anche qualcunaltro)
comunque vi ringrazio tantissmo tutti


 un gran favore (anche qualcunaltro)
Na. E comunque stiamo parlando di dettagli. Direi che và piu' che bene  
così.


 Tac
ok grazie.
il mio problema è che non capisco ancora quali siano i dettagli e (ad
esempio) alla cosa della memoria non ci avevo pensato minimamente (apparte
che forse è anomala la richiesta del cliente)
grazie ancora
