Newsgroup: it.comp.www.php
Titolo: PHP5 OOP newbie: la mio primo vero approccio con le classi (e i primi  problemi)

backgroundHeight);
    }
    public function GetImagesList(){
        return $this->rayImages;
    }
    public function SetQuality($x){
        $this->outputQuality = $x;
    }
}
$mioThumb = new dResizer();
$mioThumb->SetQuality(30);
$mioThumb->SetBackgroundImage('sfondo.jpg');
$mioThumb->SetImage('primo.jpg', 'default', 'thumbs/');
$mioThumb->SetImage('secondo.jpg', 'seconda-immagine-cribbio.jpg',
'thumbs/');
$mioThumb->SetImage('terzo.jpg', 'default', 'thumbs/');
$mioThumb->SetImage('quarto.jpg', 'numero-4.jpg', 'thumbs/');
$mioThumb->SetImage('quinto.jpg', 'sono-il-5.jpg', 'thumbs/');
//print_r($mioThumb->GetBackgroundSize());
//var_dump($mioThumb->GetImagesList());
$mioThumb->createThumbs();
----------------------------------------------------------
che ve ne pare?
Avrei altre domande: io in questo esempio salvo l'handler di ogni
immagine, prima di creare il thumb, dentro un array.. è cosa buona o
cattiva? conviene salvare solo l'url dell'immagine nell'array, e
creare l'handler e tutte le varie orpeazioni solo al momento di
elaborare l'immagine?
Secondo punto: io vorrei definire ogni immagine da rimpicciolire come
'figlio' della classe madre dResizer, cioè, se attualmente aggiungo le
immagini così:
$mioThumb->SetImage('quarto.jpg', 'numero-4.jpg', 'thumbs/');
che può anche andare bene, ma una volta dichiarata l'immagine come
posso alterarne dei valori, o rimuoverla?
Potrei creare un metodo passando il nome originale dell'immagine, e
quindi il valore da cambiare, ciclare l'array di immagini e così
via... ma non mi pare un buon metodo.
Esiste un modo per definire ogni immagine da elaborare come un'istanza
a se stante, ma comunque facente parte di dResizer (classe madre)?
Sapendo in anticipo di non essere stato per niente chiaro nella
domanda, spero che qualcuno con molta pazienza mi risponda ;)

 l'array di immagini e così via... ma non mi pare un buon metodo.
Specializza. Dividi e Impera.
Crea una classe Image per gestire una singola immagine, non infilare tutto 
dentro dResizer (a cui cambierei nome perche` non si capisce bene a cosa 
si riferisca).
La classe Image avra` tutti gli attributi dell'immagine (url, dimensioni, 
nome, ecc.) e le funzioni per lavorarci (thumb, resize, caricamento, 
salvataggio, ecc.)
Quindi avrai una classe (diciamo ImageComposition) che avra` un array di 
Image e le funzioni per gestirle (addImage, moveImage, resizeImage, 
addBackground, ecc.). Alcune useranno direttamente le funzioni di Image 
(rendendo il codice di ImageComposition molto piu` agile e gestibile), 
altre saranno specifiche.
Potresti avere anche una classe intermedia (ComposableImage) che eredita 
da Image aggiungendo parametri come la posizione all'interno della 
composizione, la trasparenza o cose del genere.
 
Bye.

thumbHeight);
    }
}
class ImageComposer{
    function resizeImage($image){
        list($thW, $thH) = $image->getThumbDimensions();
        //etc...
    }
}
Fin qui, se mi dici che non ho scritto porcate immani, dovrei
esserci ;)
Però, rimanendo al tuo esempio, il metodo addImage di ImageComposer,
come potrebbe essere strutturato?
La prima cosa che mi viene in mente è una cosa simile:
class ImageComposer{
    private $elencoImmagini;
    function __construct(){
        $this->elencoImmagini = array();
    }
    function addImage($imageHandler){
        list($thW, $thH) = $image->getThumbDimensions();
        //prendo tutte le info che i servono dall'istanza di Image...
        $this->elencoImmagini[] = array(//altezza, larghezza, ratio,
bla bla bla);
        //....?
    }
}
ma, definire tutti gli attributi nella classe Image per poi
immagazzinarli in un'arrai nella classe ImageComposer, non è una
ripetizione?
Anche a livello di impiego di memoria, non credo sia corretto avere
praticamente due volte le stesse variabili..
Quindi, dove sbaglio?

 ripetizione?
Appunto la OOP serve ad evitare ripetizioni.
Definisci le classi per poi comporle e usarle in altre classi.
Addirittura, se ComposableImage (cui accennavo nell'altro messaggio) e` 
una estensione di Image, la puoi usare ovunque ti aspetti una Image, ma 
forse e` ancora prestino per parlare di ereditarieta`, per ora cerca di 
capire come suddividere i problemi in oggetti.
Bye.

 Puoi fare la stessa cosa con $immagine->getWidth(), volendo.
Tutto chiaro (credo), il mio errore era che ero nell'ottica che prima
definivo ogni immagine con new Image($url), dopo le passavo una ad una
al ImageComposer... mentre posso tranquillamente fare la dichiarazione
dentro a ImageComposer, e bom.
Ok ok, comincio a capirci.. ora devo solo esercitarmi un pò, tornerò
quando avrò un pò più di esperienza ;)
Ultima cosa: le proprietà di ogni classe, è obbligatorio dichiararle
sempre? immagino che la risposta sia si...

 Quindi, dove sbaglio?
Nel fatto che trascuri la possibilità di concatenare la
deferenziazione... Se crei una classe "container" che ne raccoglie
altre di tipo gerarchicamente più semplice puoi tranquillamente
accedere ai metodi e proprietà delle classi "contenute", ad es.
$result = $ImageComposer->getImage($i)->getSize()
Supponendo che getImage($i) ti restituisca l'i-esimo oggetto di tipo
image contenuto in Imagecomposer, e che getSize() sia uno dei metodi
dell'oggetto image.
bye!

 sempre? immagino che la risposta sia si...
No.
PHP e` molto dinamico, puoi anche non definirle, e inizializzarle in vari 
posti, ma conviene sempre tenere le cose in ordine, come hai fatto tu: 
dichiararle in testa alla classe e inizializzarle nel costruttore.
Ti conviene anche prendere l'abitudine di dichiarare sempre public/private/
protected sia per gli attributi/proprieta` che per i metodi/funzioni.
Ora, per compatibilita`, tutto quello che non specifichi diventa public, 
ma potrebbe cambiare in futuro.
Bye.

thumbHeight);
    }
}
-----------------------------------------
Ora, quello che vorrei fare è una cosa simile (che ovviamente non
funziona):
$myBatch = new ImageComposer();
$prima = $myBatch->addImage('primo.jpg');
$prima->setThumbDimensions('w', 180);
Cioè, credo sarebbe comodo istanziare una classe 'madre' (myBatch),
aggiungere le immagini una ad una ma avere un identificatore per
ognuna di esse, in modo da poter in qualsiasi momento modificarne le
proprietà..
Alcune di queste proprietà potranno essere differenti (e settate
differentemente) per ogni immagine, come ad esempio la dimensione del
thumb e (ovviamente) l'url dell'immagine di origine.
Lo sò, probabilmente questa classe non ha senso, ma a me serve per
imparare l'OOP... quindi mi sono posto un problema da risolvere:
1. voglio settare un'immagine
2. ne voglio settare un'altra
3. settare la dimensione del thumb della prima immagine, con altezza
fissa (setThumbDimensions('h', $pixel))
4. settare la dimensione del thumb della seconda immagine, con altezza
fissa (setThumbDimensions('h', $pixel))
5. controllare la presunta larghezza del primo thumb
6. controllare la presunta larghezza del secondo thumb
7. se la larghezza del primo è maggiore della larghezza del secondo
thumb, rilancio setThumbDimensions('w', $larghezza_primo_thumb)
8. per finire in bellezza, specifico due outputh path diverse per i
due thumb.
9. Mi godo un caffè rileggendomi il risultato finale dicendomi quanto
sono fico
Se riesco a scrivere una classe che mi permetta la procedura dal punto
1 al punto 8 potrei dirmi soddisfatto del mio primo approccio OOP (e
cominciare ad approfondire).. che dite?
Cosa che, ideologicamente, ho ipotizzato così:
$myBatch = new ImageComposer();
$primo = $myBatch->addImage('primo.jpg');
$secondo = $myBatch->addImage('secondo.jpg');
$primo->setThumbDimensions('h', 180);
$secondo->setThumbDimensions('h', 95);
$primoD = $primo->getThumbDimensions();
$secondoD = $secondo->getThumbDimensions();
if($primoD['w'] > $secondoD['w']){
    $secondo->setThumbDimensions('w', $primoD['w']);
}
$primo->setOutputPath('primo/');
$secondo->setOutputPath('secondo-thumb-qui/');
$myBatch->processImages();
cosa che logicamente non funziona... perchè?
è errata la sintassi?
le due classi dovrebbero essere strutturate diversamente?
quello che ho scritto è tutto l'opposto dell'ideologia OOP?
grazie per l'aiuto...

imageRatio;
        }
    }
    public function setThumbPath($path){
        if(is_dir($path)){
            $this->outputPath = realpath($path);


     public $imageHeight;
Questa la chiamerei semplicemente $width. E cosi` le successive,tranne 
thumbWidth e thumbHeight

 del genere:
Questo è quello che intendevo!
E dire che a pensarci non era poi così impossibile, bastava ritornare
l'istanza.. funziona benissimo.
A questo punto però, ho anche modificato il metodo di ImageComposition
'removeImage':
    public function removeImage($imageHandler){
        //remove the imageHandler from the array
        $this->imageList = array_diff($this->imageList, array
($imageHandler));
    }
E dovrebbe funzionare alla perfezione, dato che si basa sul valore
dell'array e a questo punto la chiave non è più necessaria (ho provato
anche a shufflare l'array e và tutto bene)
Grazie ancora!

handler);
        $this->ratio = $this->width / $this->height;
    }
}
class BackgroundColor{
    public $color;
    public $handler;
    public $width;
    public $height;
    public $type;
    public function __construct($color, $width, $height){
        $this->type = 'color';
        $this->handler = imagecreatetruecolor($width, $height);
        echo "<br />sono in bgcolor<br />";
        var_dump($this->handler);
        echo "<br />esco da bgcolor<br />";
        $this->width = $width;
        $this->height = $height;
        $this->color = $color;
        list($cRed, $cGreen, $cBlue) = sscanf($color, '#%2x%2x%2x');
        $bgColor = imagecolorallocate($this->handler, $cRed, $cGreen,
$cBlue);
        imagefill($this->handler, 0, 0, $bgColor);
    }
}
/*
$myBatch = new ImageComposer();
$primo = $myBatch->addImage('primo.jpg');
$myBatch->setThumb($primo, 'h', 280);
$secondo = $myBatch->addImage('img/secondo.jpg');
$myBatch->setThumb($secondo, 'h', 257);
*/
$myBatch = new ImageComposer();
$myBatch->defaultBg = new BackgroundImage('sfondo.jpg');
$primo = $myBatch->addImage('primo.jpg');
$primo->setThumbSize('w', 50);
$primo->thName = 'thumb-primo.jpg';
$primo->thPath = 'thumbs';
$secondo = $myBatch->addImage('secondo.jpg');
$secondo->setThumbSize('w', 50);
$secondo->thName = 'thumb-secondo.jpg';
$secondo->thPath = 'thumbs';
$secondo->bg = 'simple';
$terzo = $myBatch->addImage('terzo.jpg');
$terzo->setThumbSize('w', 50);
$terzo->thName = 'thumb-terzo.jpg';
$terzo->thPath = 'thumbs';
$terzo->bg = new BackgroundColor('#EDF3FE', 400, 400);
$myBatch->Process();
-----------------------------------------------
L'unica cosa che mi lascia perplesso è  che devo ricreare l'istanza
del background a ogni immagine:
$finalThumb = new BackgroundColor($bgThumb->color, $bgThumb->width,
$bgThumb->height);
$finalThumbHandler = $finalThumb->handler;
ma non credo sia un problema di classe quanto di GD: anche con
l'approccio procedurale sembra che ogni handler immagine gd sia 'usa e
getta'