Ανέβασμα Φωτογραφιών Και Αποθήκευση

Καλημέρα/καλησπέρα σε όλους…

Μπαίνω κατευθείαν στο θέμα περιγράφοντάς σας το υπάρχον πρόβλημα.

Σε έναν πίνακα βάσης δεδομένων, εκτός των υπολοίπων πεδίων, έχω κι ένα πεδίο όπου θέλω να αποθηκεύεται μια φωτογραφία που έχει να κάνει με μια συγκεκριμένη συγκεκριμένη εγγραφή βέβαια κάθε φορά.

Απ’ ότι έχω δει googlάροντας δεν είναι καλή πρακτική να αποθηκεύεις φωτογραφίες στη Β.Δ για πολλούς και διάφορους λόγους (μεγαλώνει πολύ γρήγορα σε μέγεθος η βάση κλπ). Αυτό που προτείνουν οι περισσότεροι είναι η αποθήκευση της φωτογραφίας στο σύστημα αρχείων του server, και η αποθήκευση της διαδρομής στο δίσκο στη βάση δεδομένων.

Τέλος, θέλω ύστερα από την αποθήκευση να εμφανίζω στη λίστα των εγγραφών και το πεδίο της φωτογραφίας όπου θα εμφανίζεται ένας σύνδεσμος όπου με το πάτημά του να εμφανίζεται η φώτο.

Παρακαλώ όποιον έχει αντιμετωπίσει παρόμοιο πρόβλημα να με κατατοπίσει υποδεικνύοντάς μου σελίδες για διάβασμα ή οτιδήποτε άλλο!!

Τι πρόβλημα αντιμετωπίζεις; Θα έχεις ένα πεδίο στη βάση σου που θα δείχνει στο filesystem του server.

Θα πρέπει να μεριμνήσεις ώστε κατά το ανέβασμα της φωτογραφίας, να αλλάζεις το όνομα του αρχείου σε κάτι μοναδικό, για να μην πάει και γράψει πάνω από κάποιο άλλο αρχείο (και χάσει έτσι το αρχικό). Αυτό πχ. μπορείς να το κάνεις αλλάζοντας το όνομα της φωτογραφίας πχ. στο id του πίνακα. Μετά όταν πας να εμφανίσεις το link, απλά διαβάζεις τη διαδρομή και το όνομα του αρχείο και το εμφανίζεις ως html link.

Αν θέλεις κάτι πιο συγκεκριμένο, πες.

Καλά τα λες αλλά το πρόβλημα είναι ότι δεν έχω ξανακάνει κάτι παρόμοιο και πρέπει να δω κάνα παράδειγμα με κώδικα ώστε να καταλάβω λίγο τι γίνεται, διότι δυστυχώς δεν γνωρίζω άπταιστα την php και τον τρόπο με τον οποίο πρέπει να γίνει κάτι τέτοιο χρησιμοποιώντας ένα mvc framework (καθώς δεν έχω ούτε μήνα που μπήκα στη λογική προγραμματισμού με το Yii)!!

Επίσης μήπως υπάρχει κανένα extension που έχεις χρησιμοποιήσει και μπορεί να βοηθήσει??

Θα έλεγα να προσπαθήσεις να ξεκινήσεις μόνος σου με κώδικα και όπου έχεις πρόβλημα ρωτάς. Σε γενικές γραμμές όμως:

  • Έχεις μια σελίδα με τη φόρμα σου. Ένα από τα πεδία της θα είναι ένα πεδίο για αρχείο (input type="file"). Το action του form tag θα οδηγεί σε ένα controller action από το Yii (ή σε ένα απλό php αν θες να ξεκινήσεις με τα βασικά).
  • Στο form post action αρχείο (ή controller action) θα έχεις κώδικα που θα αντιγράφει το αρχείο που έχει ανεβεί στο server με ένα προσωρινό όνομα και θα το μετακινείς στο σημείο που θέλεις εσύ με το νέο σου όνομα (αυτό που έλεγα παραπάνω να είναι μοναδικό). Παραδείγματα θα βρεις πάρα πολλά στο google σχετικά με το πως γίνεται αυτό.
  • Αφού μετακινηθεί το αρχείο εκεί που πρέπει (από το προηγούμενο βήμα), τότε στο πεδίο της βάσης κρατάς τη διαδρομή και το όνομά του (με απλό string concatenation). Είσαι έτοιμος όσον αφορά το κομμάτι του ανεβάσματος του αρχείου και της αποθήκευσης στη βάση.
  • Εκεί που θες τώρα να εμφανίσεις το σύνδεσμο για το αρχείο, απλά δημιουργείς ένα a href tag που δείχνει στο αρχείο, αφού πρώτα έχεις διαβάσει τη διαδρομή του από τη βάση.

Αυτά.

Θα ακολουθήσω τις οδηγίες σου λοιπόν ευελπιστώντας να τα καταφέρω.

Σ’ ευχαριστώ!!

Επανέρχομαι στο θέμα με πιο συγκεκριμένη απορία.

Αποφάσισα να ακολουθήσω ένα πιο Yii τρόπο εν τέλει, γράφοντας στον Controller τις παρακάτω γραμμές κώδικα:




$uploadedFile=CUploadedFile::getInstance($model,'Infrastructure_Photo');

$fileName = "{$model->Infrastructure_Name}";

$model->Infrastructure_Photo = Yii::app()->basePath.'\images\\'.$fileName.".jpg";     

$uploadedFile->saveAs(Yii::app()->basePath.'/images/'.$fileName.".jpg"); 



Με τον παραπάνω κώδικα αλλάζω το όνομα της φώτο που ανεβάζει ο χρήστης σε κάτι που θέλω εγώ για να αποφύγω και περιπτώσεις overwriting.

Στο αρχείο εμφάνισης της λίστας των εγγραφών:




$widget = $this->widget('zii.widgets.grid.CGridView', array(         

     'id' => 'infrastructures-grid',         

     'dataProvider' => $model->search(),          

     'filter' => $model,         

     'htmlOptions'=>array('class'=>'grid-view clear',                              

     'enctype' => 'multipart/form-data'                            

     ),         

     'columns' => array(                

     'id',

     'Infrastructure_Name',		

     'Infrastructure_Owner',		

     'Infrastructure_Location',                 

     array(                 

     'name'=>'Infrastructure_Type',                

     'value'=> 'CHtml::encode($data->getTypeText())'                 

     ),                 

     array(                 

     'name'=>'Infrastructure_Photo',                 

     'type'=> 'html',                 

     'value'=> 'CHtml::image($data->Infrastructure_Photo)'  		

     ),



κλπ κλπ…

Η φωτογραφία ανεβαίνει και αποθηκεύεται όπως πρέπει, όπως επίσης και η διαδρομή στο δίσκο στο κατάλληλο πεδίο της βάσης δεδομένων. Το πρόβλημα είναι ότι δεν μπορώ να την εμφανίσω χρησιμοποιώντας την εντολή:


 

array(                 

'name'=>'Infrastructure_Photo',                 

'type'=> 'html',                 

'value'=> 'CHtml::image($data->Infrastructure_Photo)'  		

),



ενώ είναι κανονικά αποθηκευμένη η διαδρομή στο πεδίο Infrastructure_Photo του πίνακα της Β.Δ.

Ασχολούμαι κάνα 3ωρο και δεν μπορώ να βρω πού βρίσκεται το λάθος!!!Ίσως η εμπειρία σας δει κάτι που δεν βλέπω εγώ.

Αν θυμάμαι καλά, στο value μέσα στο grid τις ιδιότητες του $data τις παίρνεις ως πίνακα και όχι ως object properties. Για δοκίμασε το


'value'=> 'CHtml::image($data["Infrastructure_Photo"])'

Άκυρο αυτό που είπα. Δεν ισχύει.

Πρόλαβα να το δοκιμάσω και όντως δεν έπαιξε…

Αντί για grid κατευθείαν, δοκίμασε να κάνεις ένα απλό dump (var_dump ή print_r) του object, αφού το βρεις με ::model()->findAll() και να δεις τι σου επιστρέφει. Κατά πάσα πιθανότητα, κάτι δεν βάζεις στο grid σωστά και δεν παίζει.

Την κλάση του μοντέλου πώς την έφτιαξες; Με το gii;

Ναι με το gii την έκανα…θα δοκιμάσω κι αυτό που λες!!

Αντί για αυτό:




array(                 

'name'=>'Infrastructure_Photo',                 

'type'=> 'html',                 

'value'=> 'CHtml::image($data->Infrastructure_Photo)'           

),



έγραψα αυτό:




array(                 

'name'=>'Infrastructure_Photo',                 

'type'=> 'html',                 

'value'=> '$data->Infrastructure_Photo'           

),



και μου επέστρεψε κανονικά το path:

C:\xampp\htdocs\milestonegroup\protected\images\cc.jpg

Δοκίμασα και αυτό:




array(                 

'name'=>'Infrastructure_Photo',                 

'type'=> 'html',                 

'value'=> 'CHtml::image(Yii::app()->request->baseUrl."/protected/images/cc.jpg")'          

),



για να πάρω κατευθείαν την εικόνα και αυτό που μου εμφανίζει φαίνεται εδώ:

Τέλος σχολιάζοντας την τρίτη γραμμή και αλλάζοντας λίγο την τέταρτη (προσθέτοντας και άλλες παραμέτρους που παίρνει η μέθοδος image) δηλαδή:




array(          

'name'=>'Infrastructure_Photo',

//'type'=> 'html',

'value'=>'CHtml::image($data->Infrastructure_Photo,"",array("style"=>"width:25px;height:25px;"))' 

),



παίρνω τα αναμενόμενα δηλ. το source της εικόνας με τις παραμέτρους που έχω θέσει:

Δεν μπορώ να καταλάβω λοιπόν γιατί να μην παίζει κανονικά…

Το path που σου βγάζει δεν είναι σωστό. Είναι με τη μορφή αρχείου σε filesystem, όπως θα το έβλεπες από το windows explorer. Εσύ αυτό που θες είναι url, σχετικό με το web root σου. Δηλαδή, κάτι της μορφής


http://localhost/protected/images/lala.png

Δοκίμασε


'value'=>'CHtml::image(Yii::app()->baseUrl . "/" . $data->Infrastructure_Photo, "",array("style"=>"width:25px;height:25px;"))'

Επίσης, το ‘type’=>‘html’ το θέλεις.

H λύση ευρέθη…Σ’ ευχαριστώ Βασίλη!!