Newsgroup: it.comp.www.php
Titolo: anche io nel magico mondo OOP

ciao
ho provato a buttare giu' una "classicina" di mia produzione per testare 
i primi rudimenti oop....questa classe server a creare una textarea o 
una casella di testo scegliendo i parametri relativi.
secondo voi cosa potrei migliorare?..inteso come stile di programmazione
grazie!
class box{
var $modello="";
var $nome="";
var $valore="";
var $lungmax="";
var $dimensione="";
var $colonne="";
var $righe="";
	function __construct($model=""){
	 $this->modello=$model;
	}
	function crea(){
		 switch($this->modello){
		 case "textarea":
		 echo"<textarea name=\"$this->nome\" cols=\"$this->colonne\" 
rows=\"$this->righe\"></textarea>";
		 break;
		 case "text":
		 echo"<input type=\"$this->modello\" name=\"$this->nome\" 
size=\"$this->dimensione\" maxlenght=\"$this->lungmax\" 
value=\"$this->valore\">";
		 break;
		 case "":
		 echo "non hai indicato nessun tipo di casella";
		 break;
		 }
	}
}

setLungmax(20)->print();
Livello 3: interfacce
Puoi "costringere" le tue classi a implementare alcuni metodi:
Interface formElementInterface
{
 public function print();
}
class formInput extends formElement implements formInputInterface
{
 ...
}
In questo modo, se ti dimentichi di dichiarare print() o se la dichiari 
nel modo sbagliato, ti torna un errore.
Io le uso molto poco, anzi, per nulla.
Per adesso non mi viene in mente altro, ma mi pare di averti dato un po' 
di spunti. :)
Non spaventarti, prendi le cose con calma. Passare alla OOP e` un bel 
salto, ma quando ci sei non puoi piu` farne a meno. ;)
Bye.

 [cut]
Grazie a nome di tutti i lurkatori folli :)
però è vero che il salto è duro.. io ad esempio mi sto facendo una 
piccola applicazioncina web con dentro un po' di ajax, un po' di snmp, 
abbastanza ldap, una discreta dose di mysql ma ancora non ho capito 
cosa guadagnerei facendo classi per ogni "blocco" piuttosto che 
semplicemente includere i files dedicati al "blocco"..
Ora mi insulti, giàssò :)

 semplicemente includere i files dedicati al "blocco"..
Probabilmente nulla se ci lavori da solo.

 Ora mi insulti, giàssò :)
Se proprio insisti... ;)
La programmazione a oggetti non e` la panacea di tutti i mali. Spesso e` 
utile, ma ci sono molti casi in cui e` piu` utile una programmazione 
strutturata classica, o una funzionale. In alcuni casi e` ancora 
preferibile la programmazione "vecchia", senza nemmeno le funzioni e le 
precedure.
In generale, piu` un progetto cresce (e piu` persone ci lavorano), piu` 
diventa utile la programmazione a oggetti, proprio per isolare le 
funzionalita` del software, e quindi isolare meglio gli errori.
In PHP uno dei vantaggi piu` evidenti fin da subito e` che, con 
l'autoloader di PHP5, non ti serve piu` avere una sfilza di include 
all'inizio di ogni file, perche` se li carica da solo quando istanzi una 
classe o quando ne utilizzi metodi statici.
Se hai dubbi o richieste specifiche, prova a descrivere cosa stai facendo 
e (nei limiti del possibile) si vede come si potrebbe strutturare il 
progetto usando le classi. Qui c'e` gente anche molto piu` esperta di me 
nella OOP. :)
Bye.

 nella OOP. :)
Molto volentieri, è un discorso che è un po' che mi ronza in testa e 
che avevo voglia di affrontare..
Nei ritagli di tempo sto mettendo su, come dicevo, un'applicazioncina 
web "modulare", nel senso che nella pagina mostrata sono presenti 
diversi blocchi che fanno cose diverse.
Esempi:
- lista utenti del dominio, dati presi via ldap dal server, gestione 
immagini per gli utenti, tutto condito con buona dose di ajax
- stato stampanti, a seconda dell'utente loggato il sistema riconosce 
le stampanti "usate" e ne ricava lo stato via snmp mostrandolo
- documenti utili, a seconda del gruppo di appartenenza dell'utente
- blocco appunti
- reminder
ecc ecc
Ecco, ora come ora i vari "blocchi" sono files php inclusi nella pagina 
principale.
Che vantaggio avrei nel chiamare le classi invece che includere i files 
esterni?
in fondo in ogni file c'è "il blocco", solo scritto non a oggetti :)
quindi il vantaggio di dire "modifico questa parte e tutto il resto 
funziona" è relativo, perchè già com'è ora non c'è legame fra i blocchi 
e quello che riguarda un blocco è tutto nel file
Quindi?
sono stato spiegato? (cit.)
:)
Grazie, sempre un piacere leggerti..

 
Non è semplice stilare una lista di vantaggi, ma ci provo!
Raccogli tutti i metodi e funzioni relativi ad un oggetto in un'unica 
classe e questo ti consente di modificarla con una certa sicurezza 
rispetto il resto dell'applicazione
Hai una gestione organizzata di oggetti in memoria, della serie se metti 
in sessione l'oggetto utente, avrai in sessione una sola variabile che 
raccoglie tutte le info sull'utente stesso e per il debug ti basta 
controllare tutto l'oggetto rispetto che ricordarti il nome di tutte le 
var che hai dichiarato (ok, anche con un array ottieni la stessa cosa, 
ma è più semplice)
Utilizzando nome classe e metodi "verbose" hai già un codice commentato 
e, se vuoi sapere dove è definito tale metodo sai già dove cercarlo, 
cosa che non ottieni con una serie di function definite in file di 
include separati.
Proviamo a buttare giù un esempio: devi gestire la ricerca di un utente 
e poi stamparne i dati.
In modo procedurale fai:
$utente = CercaUtenteDaNome('pippo');
echo stampaInformazioniUtente($utente);
Con la classe
$user = new Utente('pippo');
echo $user->printInfo();
Se nel modo procedurale alla funzione CercaUtenteDaNome torna un array 
fatto da cognome, nome etc alla fine hai quasi creato un oggetto.
Senza contare i vantaggi che hai nel lavoro di gruppo...
	Francesco

 Senza contare i vantaggi che hai nel lavoro di gruppo...
ho capito perfettamente e ti GIURO che non "tifo" per il prodecurale
(cerca di capire il senso, lol), però vedi, non trovo queste
differenze mostruose fra le 2 programmazioni..
Probabilmente per sbloccarmi dovrei vedere un'applicazioncina di media
complessità scritta nei 2 modi..
Se hai un po' di tempo da buttare: come organizzeresti (per restare in
ambito esempio) una pagina web contenente diversi blocchi?
In procedurale, lasciando perdere il discorso grafica/template,
disegno la pagina principale e poi posso:
- includere tutti i files dei blocchi all'inizio, e nelle posizioni
giuste richiamare una funzione tipo DisplayBloccoNomeblocco(parametri)
- includere direttamente nella posizione giusta il file esterno del
blocco che si occupa della generazione dell'output
in OOP come dovrei fare?
magari guadagno qualcosa, come diceva alessandro, con l'autoloading,
ma per mostrare i blocchi non è uguale?
mi sto perdendo :)
Grazie ragazzi

 
Provo a concretizzare, anche se non sono molto capace :-(
require_once('../main.inc.php');
$obj_AUTH = MyAuth::singleton();
$obj_AUTH->start();
if (!$obj_AUTH->getAuth(4)) {
	MyAuth::loginMessage($obj_AUTH->status);
} else {
	MySetting::start();
	$template = new MyHTML_Template_ITX(null, null, null);
	$template->fillBoxUserInfo($obj_AUTH->getUserInfo());
	$template->setVariable('blocco_1',Utility::batchExportValori());
	$template->show();
}
Risultato finale: il template per default mi genere un footer con date, 
ora e tempo di esecuzione script, nell'header immetto i dati prelevati 
dall'oggetto utente, con il metodo getUserInfo, il blocco centrale è 
composto dall'output del metodo statico della classe utility
	Francesco

 ambito esempio) una pagina web contenente diversi blocchi?
Non pensare solo alla composizione della grafica del sito. Quella e` solo 
una piccola parte, e dovrebbe sfruttare altri oggetti piu` piccoli che 
fanno il lavoro sporco.
Per esempio, nel tuo caso potresti avere, per la parte "visibile" la 
classe PrinterBlock, la classe NotesBlock, la classe ReminderBlock che si 
occupano solo di creare l'HTML interrogando altre classi
Questa classi potrebbero essere Printer, Notes e Reminder, con delle 
funzioni tipo Printer::get_stats($printername), Notes::get_by_user($user), 
Reminder::get_by_user($user)
A loro volta queste classi usano la classe User, che potrebbe avere come 
funzioni User::get_level(), User::can_have_notes(), 
User::can_have_reminders(), ecc.
Sto buttando giu` idee a caso, eh, prendile solo come traccia! :)
A questo punto hai la tua index.php:
<html>...<body>
<div id="blocks">
 <div class="block">
  <?php
    $printerblock = new PrinterBlock();
    $printerblock->print_block();
  ?>
 </div>
 <div class="block">
  <?php
    $notesblock = new NotesBlock();
    $notesblock->print_block();
  ?>
 </div>
</div>
</body></html>
Puoi anche generalizzare, se hai i blocchi configurabili:
<html><body>
<div id="blocks">
 <?php
   $blockconfig = new BlockConfig();
   $blocks = $blockconfig->get_active_blocks_for_user($user);
   foreach ($blocks as $block) {
    ?>
     <div class="block">
      <?php $block->print_block(); ?>
     </div>
    <?php
   }
 ?>
</div>
</body></html>
Come vedi, avendo una interfaccia comune (la funzione print_block(). 
Interfaccia intesa come API, non come UI :), magari forzata da 
un'interface, o ereditata da una classe padre che ti stampa "nessun output 
per questo blocco" di default, rendi piu` modulare ed estendibile il tutto.
Tra l'altro, in questo modo, non ti interessa se hai la lista dei blocchi 
attivi in un file, in un DB, calcolata al volo in base a cosa c'e` 
disponibile per l'utente o in qualsiasi altro modo. L'index.php non 
cambia, e modifichi solo il codice di BlockConfig, che potrebbe anche 
essere un Factory che si appoggia a backend diversi, che implementano 
ognuno uno dei sistemi che ho elencato, in base a cosa configuri da altre 
parti. Basta che la funzione get_active_blocks_for_user() torni un 
Iterable. Un array e` un iterable, ma puoi anche generare al volo la lista 
man mano che viene richiesta dal foreach.
Prova a contare quante classi abbiamo gia` usato, e quante rappresentano 
l'UI: BlockConfig, User, Block (ed eventualmente BlockInterface), 
PrinterBlock, Noteslock, ReminderBlock, ed eventualmente BlockConfigINI, 
BlockConfig_MySQL, BlockConfig_PgSQL, BlockConfig_LDAP, 
BlockConfig_OnDemand, IterableBlockList.
A cui puoi aggiungere PrinterList per la lista delle stampanti, Printer 
che rappresenta una stampante, NoteBlock, NoteList e Note per astrarre le 
note, ReminderBlock, ReminderList e Reminder per astrarre i reminder, a 
cui puoi aggiungere i genitori (DBRow e DBTable, per esempio, che ti 
forniscono funzioni per astrarre dal DB).
Ognuno di questi oggetti e` molto piu` piccolo, e quindi piu` 
specializzato e piu` mantenibile di un singolo file include pieno di 
funzioni.
Spero di aver reso un po' l'idea. Nel caso, chiedi :)
Bye.

 Spero di aver reso un po' l'idea. Nel caso, chiedi :)
Grazie, sempre gentilissimo..
e come vedi io ne approfitto lol

 dove sbaglio? :)
Non sbagli, in linea di massima.
Puoi anche partire con una struttura come questa che non e` sbagliata. 
Forse poco flessibile per alcuni sviluppi futuri, ma se non ti 
interessano, va benissimo.
Man mano che procederai con lo sviluppo ti accorgerai da solo, un po' alla 
volta, dove puoi specializzare.
Ogni tanto sarai tentato di formattare l'HD dalla frustrazione, ma dopo 
una notte di sonno di solito passa. :)
Comincia dal piccolo: prova ad usare un po' di classi prese da phpclasses 
(per la gestione delle immagini o di LDAP), oppure a usarne qualcuna 
integrata tipo PDO.
Poi prova a modificarle aggiungendo funzionalita` che ti servono.
Poi prova a integrarle tra di loro (per esempio usa una classe per il 
captcha e falle usare la classe per le immagini di sopra, invece di fargli 
usare direttamente le gd, o roba del genere). Man mano fai crescere il 
sistema.
Non buttarti su framework finche` non hai abbastanza chiari i concetti di 
base (ereditarieta`, reimplementazione dei metodi, magic methods, metodi e 
attributi statici e astratti, ecc.)
Personalmente ho trovato le varie descrizioni dei pattern troppo astratte 
per essere comprensibili. Di solito sono fatte per i programmatori Java. 
Se ti interessano i pattern, piuttosto cerca qualcuno che li abbia 
implementati in PHP, e` molto piu` comprensibile. Parti da roba semplice 
come il singleton o il factory, prima di buttarti su MVC o cose piu` 
complicate.
Bye.

 tue intenzioni. ;)
Se mi posso intromettere, io procederei a passi distinguendo una cosa
essenziale: un conto č la realizzazione delle classi per la
visualizzazione o tutto ciň che č inerente a questa (classe per i box,
elementi della form etc..), altra cosa la realizzazione di classi per la
gestione dei dati stessi. 
Come ha giŕ detto Alessandro, tutte le volte che riprenderai in mano una
classe fatta ti chiederai: ma perchč non avevo pensato anche a
quest'aspetto oppure non ho fatto anche una classe per questa proprietŕ??
   Francesco
-- 
questo articolo e` stato inviato via web dal servizio gratuito 
http://www.newsland.it/news
 segnala gli abusi ad 
ab...@newsland.it