Σίγουρα έχετε προσέξει στα διάφορα eshops ή σε διάφορα fora που έχουν τις κατηγορίες και μέσα σε αυτές κι άλλες κατηγορίες κ.ο.κ.. και εμφανίζονται όλα με κάποια ιεραρχία, οι υποκατηγορίες λίγο πιο μέσα από τις... "γονικές" κατηγορίες κλπ.
Καιρό λοιπόν αναρωτιόμουν πώς γίνεται αυτό με το να εμφανίζονται πιο μέσα οι υποκατηγορίες, αλλά πάντα βαριόμουν να το ψάξω.
Οπότε μιας που πλησιάζει η εξεταστική σκέφτηκα "να η ευκαιρία":
Monday, August 30, 2010
Sunday, August 22, 2010
PHP 100: Σχεδόν εισαγωγή
Ο καιρός που οι σελίδες ήταν ένα συνονθύλευμα από αρχεία HTML, έχει περάσει ανεπιστρεπτί.
Σε αυτό οφείλεται η τεράστια διείσδυση του Internet στις ζωές μας η οποία οφείλεται στις τεράστιες ευκολίες που μας έχει προσφέρει, όπως π.χ. e-shops
Φανταστείτε να γραφόταν ένα e-shop ή ένας οποιοσδήποτε κατάλογος χρησιμοποιώντας σκέτη HTML.
Αρχικά θα ήθελε για κάθε νέο προϊόν να δημιουργείς ένα (τουλάχιστον) νέο αρχείο. Όταν σκοπεύεις να έχεις 2-3 τέτοια είναι καλά, δεν υπάρχει καν λόγος να μπλέξεις με PHP και βάσεις δεδομένων κλπ.
Όταν όμως σκοπεύεις να έχεις 2-3 χιλιάδες τέτοια προϊόντα, και να προσθέτεις, ανανεώνεις, διαγράφεις καθημερινά, αντιλαμβάνεται κανείς ότι κάτι τέτοιο ξεπερνάει τα όρια του κουραστικού, και αγγίζει τα όρια του μαζοχισμού και της ηλιθιότητας.
Tuesday, August 17, 2010
Regular Expressions: Finally an explanation...
Στο προηγούμενο ποστ για το Live Search, κάνω χρήση των regular expressions (θα το λέω έτσι, ή RegExps, ή κάτι τέτοιο, και όχι το ηλίθιο ελληνικό "κανονικές εκφράσεις").
Γνωρίζοντας και από τη σχολή μου τι φόβος υπάρχει γύρω από αυτό το θέμα θα προσπαθήσω να τα εξηγήσω όσο πιο απλά μπορώ. Να προειδοποιήσω ότι πρέπει να είστε προετοιμασμένοι να εκνευριστείτε απίστευτα στις προσπάθειές σας, και να φάτε πολλή ώρα ψάχνοντας να βρείτε την τελεία που νομίζετε ότι είχατε πατήσει, αλλά τελικά δεν πατήθηκε και δεν λειτουργεί η RegExp σας όπως θα περιμένατε.
Πήρατε κουράγιο;
Ωραία..
Πριν ξεκινήσω να εξηγώ, συνιστώ να κατεβάσετε αυτό εδώ το προγραμματάκι, το οποίο για όσους βαριούνται τη διαδικασία υπάρχει και η online έκδοσή του εδώ. Με αυτό το πρόγραμμα θα μπορείτε να βλέπετε αμέσως τα αποτελέσματα αυτών που γράφετε.
Ας ξεκινήσω με ένα παράδειγμα, αρκετά κλασσικό που χρησιμοποιείται σε πολλά site και όχι μόνο.
Την επαλήθευση ότι αυτό που έγραψε ο χρήστης στο πεδίο του e-mail είναι όντως μια διεύθυνση e-mail και όχι ότι κατέβηκε εκείνη την ώρα στη γκλάβα του:
Το ^ σημαίνει την αρχή του string.
To [a-zA-Z0-9] σημαίνει όλα τα πεζά λατινικά γράμματα από a-z, όλα τα κεφαλαία λατινικά από Α-Ζ και όλους τους αριθμούς από 0-9.
Με αυτά τα 2 ζητάμε ουσιαστικά το οποιοδήποτε e-mail να ξεκινάει με χαρακτήρα ή αριθμό.
Η επόμενη αγκύλη [a-zA-Z0-9\._] σημαίνει ακριβώς ότι το προηγούμενο και επιπλέον: την τελεία (\.) και το underscore (_). Ο λόγος που υπάρχει κάθετος πριν την τελεία είναι για να πάρει την τελεία ως χαρακτήρα και όχι με την ιδιότητα που έχει στις RegExps.
Μέχρι στιγμής ζητάμε δηλαδή να ξεκινάει από κεφαλαίο ή μικρό λατινικό γράμμα ή αριθμό και ο επόμενος χαρακτήρας να είναι κεφαλαίο ή μικρό λατινικό γράμμα, ή αριθμός, ή τελεία, ή underscore.
To + που ακολουθεί αμέσως μετά, σημαίνει ότι θέλουμε η προηγούμενη έκφραση (δηλαδή η προηγούμενη αγκύλη) να υπάρχει 1 ή περισσότερες φορές
Το @ δεν έχει κάποια ειδική σημασία, είναι το κλασσικό @ που υπάρχει σε όλα τα e-mails.
H επόμενη αγκύλη μαζί με το + και το \. που ακολουθούν σημαίνουν ακριβώς τα ίδια όπως και παραπάνω, οπότε δεν τα ξαναγράφω.
Τέλος φτάνουμε στο [a-zA-Z]{2-4}
Εδώ είμαστε ουσιαστικά στην κατάληξη του e-mail. Η αγκύλη όπως και παραπάνω, σημαίνει έναν χαρακτήρα από το λατινικό αλφάβητο, κεφαλαίο ή μικρό. Το {2-4} σημαίνει πως ζητάμε η προηγούμενη έκφραση να υπάρχει από 2 μέχρι 4 φορές, δηλαδή η κατάληξη του e-mail να είναι 2 ως 4 λατινικοί χαρακτήρες είτε κεφαλαίοι είτε πεζοί.
Το $ στο τέλος δηλώνει το τέλος του string.
Βλέπει κανείς λοιπόν, ότι ενώ αν το δεις όλο με τη μία τρως μια φρίκη, αν το πάρεις σιγά σιγά, καταλαβαίνεις τι παίζει αρκετά εύκολα.
Πριν κλείσω να προσθέσω μερικούς ακόμα βασικούς ειδικούς χαρακτήρες που είναι ιδιαίτερα χρήσιμοι:
. (τελεία): Σημαίνει οποιονδήποτε χαρακτήρα (εκτός του χαρακτήρα αλλαγής γραμμής)
? : Η προηγούμενη έκφραση γίνεται optional. Ταιριάζει είτε ισχύει, είτε δεν ισχύει η προηγούμενη έκφραση.
* : Η προηγούμενη έκφραση πρέπει να υπάρχει 0 ή περισσότερες φορές. (Μοιάζει με το +, αλλά προσοχή, το + απαιτεί τουλάχιστον 1 φορά να υπάρχει η προηγούμενη έκφραση)
[^a-z]: Το ^ στην αρχή σημαίνει ότι θέλουμε οποιονδήποτε χαρακτήρα εκτός από όσα βρίσκονται στο εύρος a-z.
Για περισσότερες πληροφορίες googlάρετε ή αν βαριέστε LetMeGoogleThatForYou.
Γνωρίζοντας και από τη σχολή μου τι φόβος υπάρχει γύρω από αυτό το θέμα θα προσπαθήσω να τα εξηγήσω όσο πιο απλά μπορώ. Να προειδοποιήσω ότι πρέπει να είστε προετοιμασμένοι να εκνευριστείτε απίστευτα στις προσπάθειές σας, και να φάτε πολλή ώρα ψάχνοντας να βρείτε την τελεία που νομίζετε ότι είχατε πατήσει, αλλά τελικά δεν πατήθηκε και δεν λειτουργεί η RegExp σας όπως θα περιμένατε.
Πήρατε κουράγιο;
Ωραία..
Πριν ξεκινήσω να εξηγώ, συνιστώ να κατεβάσετε αυτό εδώ το προγραμματάκι, το οποίο για όσους βαριούνται τη διαδικασία υπάρχει και η online έκδοσή του εδώ. Με αυτό το πρόγραμμα θα μπορείτε να βλέπετε αμέσως τα αποτελέσματα αυτών που γράφετε.
Ας ξεκινήσω με ένα παράδειγμα, αρκετά κλασσικό που χρησιμοποιείται σε πολλά site και όχι μόνο.
Την επαλήθευση ότι αυτό που έγραψε ο χρήστης στο πεδίο του e-mail είναι όντως μια διεύθυνση e-mail και όχι ότι κατέβηκε εκείνη την ώρα στη γκλάβα του:
^[a-zA-Z0-9][a-zA-Z0-9\._]+@[a-zA-Z0-9\._]+\.[a-zA-Z]{2,4}$Μη τρομάζετε, θα το πάρουμε βήμα-βήμα:
Το ^ σημαίνει την αρχή του string.
To [a-zA-Z0-9] σημαίνει όλα τα πεζά λατινικά γράμματα από a-z, όλα τα κεφαλαία λατινικά από Α-Ζ και όλους τους αριθμούς από 0-9.
Με αυτά τα 2 ζητάμε ουσιαστικά το οποιοδήποτε e-mail να ξεκινάει με χαρακτήρα ή αριθμό.
Η επόμενη αγκύλη [a-zA-Z0-9\._] σημαίνει ακριβώς ότι το προηγούμενο και επιπλέον: την τελεία (\.) και το underscore (_). Ο λόγος που υπάρχει κάθετος πριν την τελεία είναι για να πάρει την τελεία ως χαρακτήρα και όχι με την ιδιότητα που έχει στις RegExps.
Μέχρι στιγμής ζητάμε δηλαδή να ξεκινάει από κεφαλαίο ή μικρό λατινικό γράμμα ή αριθμό και ο επόμενος χαρακτήρας να είναι κεφαλαίο ή μικρό λατινικό γράμμα, ή αριθμός, ή τελεία, ή underscore.
To + που ακολουθεί αμέσως μετά, σημαίνει ότι θέλουμε η προηγούμενη έκφραση (δηλαδή η προηγούμενη αγκύλη) να υπάρχει 1 ή περισσότερες φορές
Το @ δεν έχει κάποια ειδική σημασία, είναι το κλασσικό @ που υπάρχει σε όλα τα e-mails.
H επόμενη αγκύλη μαζί με το + και το \. που ακολουθούν σημαίνουν ακριβώς τα ίδια όπως και παραπάνω, οπότε δεν τα ξαναγράφω.
Τέλος φτάνουμε στο [a-zA-Z]{2-4}
Εδώ είμαστε ουσιαστικά στην κατάληξη του e-mail. Η αγκύλη όπως και παραπάνω, σημαίνει έναν χαρακτήρα από το λατινικό αλφάβητο, κεφαλαίο ή μικρό. Το {2-4} σημαίνει πως ζητάμε η προηγούμενη έκφραση να υπάρχει από 2 μέχρι 4 φορές, δηλαδή η κατάληξη του e-mail να είναι 2 ως 4 λατινικοί χαρακτήρες είτε κεφαλαίοι είτε πεζοί.
Το $ στο τέλος δηλώνει το τέλος του string.
Βλέπει κανείς λοιπόν, ότι ενώ αν το δεις όλο με τη μία τρως μια φρίκη, αν το πάρεις σιγά σιγά, καταλαβαίνεις τι παίζει αρκετά εύκολα.
Πριν κλείσω να προσθέσω μερικούς ακόμα βασικούς ειδικούς χαρακτήρες που είναι ιδιαίτερα χρήσιμοι:
. (τελεία): Σημαίνει οποιονδήποτε χαρακτήρα (εκτός του χαρακτήρα αλλαγής γραμμής)
? : Η προηγούμενη έκφραση γίνεται optional. Ταιριάζει είτε ισχύει, είτε δεν ισχύει η προηγούμενη έκφραση.
* : Η προηγούμενη έκφραση πρέπει να υπάρχει 0 ή περισσότερες φορές. (Μοιάζει με το +, αλλά προσοχή, το + απαιτεί τουλάχιστον 1 φορά να υπάρχει η προηγούμενη έκφραση)
[^a-z]: Το ^ στην αρχή σημαίνει ότι θέλουμε οποιονδήποτε χαρακτήρα εκτός από όσα βρίσκονται στο εύρος a-z.
Για περισσότερες πληροφορίες googlάρετε ή αν βαριέστε LetMeGoogleThatForYou.
Monday, August 16, 2010
Live Search με τη JavaScript
Πάντα γούσταρα την αναζήτηση, ειδικά μετά από τότε που είδα το Spotlight στα Mac, το οποίο με έκανε να σιχαθώ για πάντα την αναζήτηση που είχαν τα XP.
Να σημειώσω εδώ ότι -όπως είναι προφανές- για να είναι άμεση η αναζήτηση, θα πρέπει η συνάρτηση να καλείται σε κάθε πάτημα πλήκτρου.
Επίσης το div μέσα στο οποίο βρίσκεται ο πίνακας είναι με id=livesearch και ο πίνακας με τα δεδομένα έχει id=data.
Με τον καιρό διαβάζοντας από δω κι από εκεί και παρατηρώντας καλύτερα τα διάφορα site, είδα ότι πολλά έχουν αυτό το Live Search.
Σε αυτό το σημείο να διευκρινίσω κάτι:
Μιλάω για Live Search εδώ πέρα, όχι για Ajax Search. Υπάρχουν μερικές βασικές διαφορές μεταξύ αυτών των 2, κυρίως στη βασική ιδέα και, ως εκ τούτου, και στην υλοποίηση τις οποίες δεν θα αναφέρω εδώ, κυρίως επειδή βαριέμαι και κατά δεύτερον επειδή το Ajax Search θα το ανεβάσω στο μέλλον.
Βασική ιδέα:
Τραβάμε όλα τα δεδομένα στα οποία θέλουμε να κάνουμε την αναζήτηση και τα αποθηκεύουμε σε ένα table ή σε list ή σε ό,τι θέλουμε/μας βολεύει.
Σε κάθε πλήκτρο που πατάει ο χρήστης καλούμε την συνάρτηση, η οποία πάει και ψάχνει το κάθε κελί ή το κάθε list item με ένα regular expression. Αν ταιριάζει καλώς, αν δεν ταιριάζει περνάει στο επόμενο κ.ο.κ
Στο παράδειγμα που θα γράψω εδώ, θα χρησιμοποιήσω ένα table το οποίο θα είναι μέσα σε ένα κρυφό div.
Κάθε γραμμή θα έχει 4 κελιά και η συνάρτηση θα κοιτάει και τα 4 κελιά. Μόλις βρει το ταίριασμα που θέλουμε σε οποιοδήποτε κελί θα εμφανίζει μόνο αυτή τη γραμμή και θα περνάει στην επόμενη, και πάει λέγοντας.
function search(query) { if(query!="") { //αφαιρούμε whitespaces var query = query.trim(); //δημιουργούμε τη regExp που χρησιμοποιήσουμε var pat = new RegExp(query+"+?.*", "gi"); //παίρνουμε τον πίνακα var tbl = document.getElementById("data"); //παίρνουμε τις γραμμές του var rowNumb = tbl.rows; //ξεκινάμε την επανάληψη από την 1η γραμμή του πίνακα //γιατί η γραμμή 0 είναι τα headers της κάθε στήλης. var i=1; for(i=1; i<rowNumb.length; i++) { //κάνουμε 'αόρατη' την γραμμή που είμαστε rowNumb[i].style.display='none'; //παίρνουμε όλα τα κελιά της γραμμής var cellNumb = rowNumb[i].cells; //ξεκινάμε την επανάληψη για κάθε κελί var j=0; for(j=0; j<cellNumb.length; j++) { //παίρνουμε το κείμενο κάθε κελιού var cellText = cellNumb[j].innerHTML; //ελέγχουμε αν ταιριάζει με τη RegExp που δημιουργήσαμε πριν if(cellText.match(pat)) { //αν ταιριάξει, τότε εμφανίζουμε το div που περιέχει τον πίνακα document.getElementById('liveSearch').style.display=''; //...και την γραμμή rowNumb[i].style.display=''; //αφου βρέθηκε κάτι που ταιριάζει //δεν ψάχνουμε τα επόμενα κελιά //και περνάμε στην επόμενη γραμμή break; } } } } else { //αν το πεδίο της αναζήτησης είναι κενό, τότε κρύβουμε το div του πίνακα document.getElementById('liveSearch').style.display='none'; } }
Να σημειώσω εδώ ότι -όπως είναι προφανές- για να είναι άμεση η αναζήτηση, θα πρέπει η συνάρτηση να καλείται σε κάθε πάτημα πλήκτρου.
Επίσης το div μέσα στο οποίο βρίσκεται ο πίνακας είναι με id=livesearch και ο πίνακας με τα δεδομένα έχει id=data.
Sunday, August 15, 2010
Java 102 - Κλάσεις & Primitive Data Types (2)
Συνεχίζουμε με Primitive Data Types.
Primitive Data Types (δε θέλω να το μεταφράσω αλλά επειδή επιμένετε...) ή αλλιώς Πρωτόγονοι Τύποι Δεδομένων (μπλιάχ!) ονομάζονται οι διάφοροι τύποι μεταβλητών που μπορούμε να έχουμε σε ένα πρόγραμμα Java οι οποίοι δεν προκύπτουν από κάποια γονική κλάση.
Primitive Data Types (δε θέλω να το μεταφράσω αλλά επειδή επιμένετε...) ή αλλιώς Πρωτόγονοι Τύποι Δεδομένων (μπλιάχ!) ονομάζονται οι διάφοροι τύποι μεταβλητών που μπορούμε να έχουμε σε ένα πρόγραμμα Java οι οποίοι δεν προκύπτουν από κάποια γονική κλάση.
PHP και Ασφάλεια - SQL Injections
Το θέμα "ασφάλεια" δεν απασχολεί μόνο την PHP, αλλά οποιαδήποτε γλώσσα προγραμματισμού.
Πρέπει πάντα να κάνουμε ελέγχους έτσι ώστε να μειώσουμε τα λάθη που θα εμφανιστούν. (Να τα εξαφανίσουμε αποκλείεται, δεν υπάρχει πρόγραμμα στο οποίο να έχουν προβλεφτεί τα πάντα)
Ειδικά στην PHP που λόγω της χρήσης της στο Internet μπορεί η εφαρμογή μας να χρησιμοποιηθεί εν δυνάμει από τους πάντες οφείλουμε να προγραμματίζουμε αμυντικά, κοινώς:
α) Θεωρούμε -και όχι αδίκως- ότι ο τελικός χρήστης είναι παντελώς ηλίθιος.
α) Θεωρούμε -και όχι αδίκως- ότι ο τελικός χρήστης είναι παντελώς ηλίθιος.
β) Δεν ξέρει να διαβάζει.
γ) Είναι 60+ χρονών και θεωρεί ακόμα ότι ο υπολογιστής είναι στα επίπεδα του Eniac.
Οπότε τι κάνουμε;
Ελέγχουμε πάντα ΤΑ ΠΑΝΤΑ.
SQL Injection:
Θεωρώ ότι ο όρος είναι αρκετά γνώριμος (ή απλά είμαι υπεραισιόδοξος).
Σε περίπτωση που δεν τον ξέρετε, το παρακάτω θα σας διαφωτίσει:
Υπάρχουν διάφοροι τρόποι να προστατευτεί κανείς και η PHP μας δίνει αρκετές συναρτήσεις να μας βοηθήσει.
Ουσιαστικά, αυτό που πρέπει να γίνει, είναι να γίνουν escaped όλοι οι ειδικοί χαρακτήρες έτσι ώστε o SQL server που θα εκτελέσει το ερώτημα να μη τους λάβει υπ' όψιν του ως τμήμα του ερωτήματος, αλλά ως περιεχόμενο.
Παλιότερα υπήρχε η συνάρτηση addslashes() η οποία έπαιρνε ένα string, και, όπως λέει και το όνομά της, τοποθετούσε καθέτους πριν από τους ειδικούς χαρακτήρες.
Επίσης για να διευκολύνουν τους προγραμματιστές, έβαλαν και μια directive ονόματι magic_quotes_gpc, η οποία ουσιαστικά όταν ήταν σε λειτουργία εφάρμοζε αυτόματα την addslashes() σε όλες τις gpc ($_GET, $_POST, $_COOKIE) μεταβλητές.
Στις πιο καινούριες εκδόσεις προστέθηκε η πιο αποτελεσματική mysql_real_escape_string() με την οποία και μόνο στη σκέψη να γράφεις όλο αυτό το μακρινάρι για κάθε τιμή που θες να κάνεις ασφαλή είναι να σε πιάνει απόγνωση.
Και άντε, το γράφεις, και σπίτι σου δουλεύει καλά με το τελευταίο xampp που πέρασες, και όλα ωραία. Όταν πας να το ανεβάσεις σε έναν server που δεν έχουν ανανεώσει την php τους και άρα δεν έχουν αυτή τη νέα συνάρτηση τι κάνεις;
Ιδού τι κάνεις:
<?php function mysql_prep($value) { $magic_quotes_active = get_magic_quotes_gpc(); //Ελέγχουμε αν είναι ενεργά τα magic_quotes if(function_exists("mysql_real_escape_string")) // Αν υπάρχει η συνάρτηση mysql_real_escape_string... { // ...τότε, αν είναι ενεργά τα magic_quotes, τα κάνουμε undo για να λειτουργήσει η (καλύτερη) mysql_real_escape_string if($magic_quotes_active) { $value = stripslashes($value); } $value = mysql_real_escape_string($value); } else //αν δεν υπάρχει η mysql_real_escape_string { if(!$magic_quotes_active) // αν δεν είναι ενεργά τα magic_quotes, τότε τη χρησιμοποιούμε μόνοι μας { $value = addslashes($value); } //αν είναι ήδη ενεργά τα magic_quotes τότε έχουν ήδη χρησιμοποιθεί } return $value; } ?>
Enjoy.
Java 102 - Κλάσεις & Primitive Data Types (1)
Θα αρχίσω με λίγη θεωρία και θα μεταφράσω μερικές ερωταπαντήσεις από τo Java Tutorials.
Τι είναι μια κλάση/Τι είναι ένα αντικείμενο;
Στο πραγματικό κόσμο συχνά συναντάμε πολλά ξεχωριστά αντικείμενα του ίδιου τύπου. Μπορεί να υπάρχουνε χιλιάδες ποδήλατα ανα το κόσμο, ίδιας μάρκας και ίδιου μοντέλου. Κάθε ποδήλατο φτιάχτηκε από τo ίδιο πρότυπο/προσχέδιο κι έτσι περιέχει τα ίδια μέρη με όλα τα υπόλοιπα ποδήλατα.
Λέμε ότι το κάθε ξεχωριστό ποδήλατο είναι ένα στιγμιότυπο της γενικότερης κλάσης των αντικειμένων γνωστών ως ποδήλατα.
Η κλάση είναι αυτό το πρότυπο το οποίο αναφέραμε και από το οποίο όλα τα υπόλοιπα ποδήλατα δημιουργούνται.
Αντικείμενα είναι όλα τα μεμονομένα ποδήλατα που προέρχονται/δημιουργούνται από την πρότυπη κλάση.
Ας κάνουμε μια διαφορετική υλοποίηση με αυτοκίνητα αντί για ποδήλατα :
Παραπάνω ορίσαμε μία κλάση αυτοκινήτων η οποία μπορεί να λειτουργήσει ως πρότυπο για πιο εξειδικευμένες κλάσεις/αντικείμενα.
Θα προχωρήσω λίγο το παράδειγμα και θα φτιάξω μια νέα κλάση :
Με αυτή τη πιό λεπτομερή κλάση μπορούμε μετά να δημιουργήσουμε και πιο ολοκλήρωμενα αντικείμενα τα οποία δε θα είναι τόσο "αφηρημένα".
Τι είναι μια κλάση/Τι είναι ένα αντικείμενο;
Στο πραγματικό κόσμο συχνά συναντάμε πολλά ξεχωριστά αντικείμενα του ίδιου τύπου. Μπορεί να υπάρχουνε χιλιάδες ποδήλατα ανα το κόσμο, ίδιας μάρκας και ίδιου μοντέλου. Κάθε ποδήλατο φτιάχτηκε από τo ίδιο πρότυπο/προσχέδιο κι έτσι περιέχει τα ίδια μέρη με όλα τα υπόλοιπα ποδήλατα.
Λέμε ότι το κάθε ξεχωριστό ποδήλατο είναι ένα στιγμιότυπο της γενικότερης κλάσης των αντικειμένων γνωστών ως ποδήλατα.
Η κλάση είναι αυτό το πρότυπο το οποίο αναφέραμε και από το οποίο όλα τα υπόλοιπα ποδήλατα δημιουργούνται.
Αντικείμενα είναι όλα τα μεμονομένα ποδήλατα που προέρχονται/δημιουργούνται από την πρότυπη κλάση.
Ας κάνουμε μια διαφορετική υλοποίηση με αυτοκίνητα αντί για ποδήλατα :
class Car { int engineCC = 0; int horsePower = 0; boolean automaticTransmission = false; void setEngineCC(int newValue) { engineCC = newValue; } void setHorsePower(int newValue) { horsePower = newValue; } void hasAutomaticTransmission(boolean newValue) { automaticTransmission = newValue; } void printCharacteristics() { System.out.println("Engine CC : " + engineCC); System.out.println("Horse Power : " + horsePower); System.out.println("Automatic Transmission : " + automaticTransmission); } }
Παραπάνω ορίσαμε μία κλάση αυτοκινήτων η οποία μπορεί να λειτουργήσει ως πρότυπο για πιο εξειδικευμένες κλάσεις/αντικείμενα.
Θα προχωρήσω λίγο το παράδειγμα και θα φτιάξω μια νέα κλάση :
class BMW extends Car { // inheritance (κληρονομικότητα) η οποία θα καλυφθεί σε αργότερο post. String model = new String(); String color = new String(); int price; BMW() {} void setModel(String newValue) { model = newValue; } void setColor(String newValue) { color = newValue; } void setPrice(int newValue) { price = newValue; } }
Με αυτή τη πιό λεπτομερή κλάση μπορούμε μετά να δημιουργήσουμε και πιο ολοκλήρωμενα αντικείμενα τα οποία δε θα είναι τόσο "αφηρημένα".
class myApplication { public static void main(String[] args) { BMW testCar = new BMW(); } }
Saturday, August 14, 2010
Online users με την php
Ένα πολύ καλό feature που υπάρχει στα περισσότερα fora είναι που έχουν τη δυνατότητα να εμφανίζουν το πόσοι/ποιοι είναι online εκείνη την ώρα, ή για την ακρίβεια τα τελευταία Χ λεπτά.
Μετά από μια αποτυχημένη προσπάθεια ρώτησα σε ένα forum για το πώς μπορεί να γίνει κάτι τέτοιο και μου δείξανε τον σωστό δρόμο.
Η γενική ιδέα είναι η εξής:
Όταν έρχεται κάποιος στο site αποθηκεύουμε κάποιο μοναδικό χαρακτηριστικό του (στην περίπτωσή μας την IP του) είτε σε ένα αρχείο είτε στη βάση μας, μαζί με ένα timestamp για το πότε έγινε η συγκεκριμένη καταχώρηση.
Κάθε φορά μετά που ελέγχουμε το αρχείο, κοιτάμε ποια timestamps έχουν λήξει, σβήνουμε τις αντίστοιχες εγγραφές και ξαναποθηκεύουμε το αρχείο.
Με κώδικα θα είναι πιο κατανοητό το όλο θέμα:
Μπορεί κάλλιστα να επεκταθεί ώστε να κάνει διαχωρισμό και μεταξύ των εγγεγραμμένων ή μη χρηστών, και διάφορα άλλα πράγματα.
Μετά από μια αποτυχημένη προσπάθεια ρώτησα σε ένα forum για το πώς μπορεί να γίνει κάτι τέτοιο και μου δείξανε τον σωστό δρόμο.
Η γενική ιδέα είναι η εξής:
Όταν έρχεται κάποιος στο site αποθηκεύουμε κάποιο μοναδικό χαρακτηριστικό του (στην περίπτωσή μας την IP του) είτε σε ένα αρχείο είτε στη βάση μας, μαζί με ένα timestamp για το πότε έγινε η συγκεκριμένη καταχώρηση.
Κάθε φορά μετά που ελέγχουμε το αρχείο, κοιτάμε ποια timestamps έχουν λήξει, σβήνουμε τις αντίστοιχες εγγραφές και ξαναποθηκεύουμε το αρχείο.
Με κώδικα θα είναι πιο κατανοητό το όλο θέμα:
<?php function checkUsers() { $timeout = 1500; //se deuterolepta $found = false; $users = file("users.txt"); foreach($users as $user) { $line = explode(" ", trim($user)); if(time() - $line[1] < $timeout) // an o xristis se auti ti grammi _DEN_ exei liksei { if($_SERVER['REMOTE_ADDR'] == $line[0]) // an o xristis pou irthe twra yparxei { $found = true; $line[1] = time(); //apla ananewnoume ton xrono tou } $newList[] = $line; //kai kanoume mia lista me tous energous xristes } } if(!$found) //an _DEN_ vrethike o xristis pou irthe twra sto arxeio { //tote dimiourgoume nea eggrafi kai ti vazoume sto telos tis listas me tous energous xristes $line[0] = $_SERVER['REMOTE_ADDR']; $line[1] = time(); $newList[] = $line; } //twra i newList periexei osous einai akoma online, opote kanoume tin eggrafi $pf = fopen("users.txt", "w"); if(is_array($newList) && count($newList) > 0) { foreach($newList as $line) { fwrite($pf, implode(" ", $line) . "\n"); } } fclose($pf); //kai telos epistrefoume ton arithmo twn xristwn pou einai online return count($newList); } ?>
Μπορεί κάλλιστα να επεκταθεί ώστε να κάνει διαχωρισμό και μεταξύ των εγγεγραμμένων ή μη χρηστών, και διάφορα άλλα πράγματα.
Friday, August 13, 2010
Java Common Mistakes - Null Pointer Exception
Πόσες ώρες μπορεί να έχω σπαταλήσει ψάχνοντας για τέτοιου τύπου λάθη;
Θα σας πω μερικά πράγματα για το κλασσικό σφάλμα του Null Pointer Exception για να σας σώσω από πολλές ώρες ψαξίματος και δυσανασχέτισης.
Όταν δηλώνουμε ένα αντικείμενο, στην ουσία δημιουργούμε ένα δείκτη στο αντικείμενο αυτό.
Θα σας πω μερικά πράγματα για το κλασσικό σφάλμα του Null Pointer Exception για να σας σώσω από πολλές ώρες ψαξίματος και δυσανασχέτισης.
Όταν δηλώνουμε ένα αντικείμενο, στην ουσία δημιουργούμε ένα δείκτη στο αντικείμενο αυτό.
Wednesday, August 11, 2010
Java 101 - Εισαγωγή
Καλημέρα,
θα θεωρήσω ότι δεν είστε ΠΑΝΤΕΛΩΣ άσχετοι με τις βασικές έννοιες του προγραμματισμού (μόλις αναδύθηκαν αρκετά πρόσωπα στο μυαλό μου αυτή τη στιγμή). Ας πούμε απλά ότι δε ξέρετε Java και είστε της παλίας σχολής της C με 8πλούς pointers και άλλα τέτοια σαδομαζοχιστικά γούστα.
ΟΚ!
Η Java πρόκειται για μια object-oriented γλώσσα προγραμματισμού (γενικότερα θα χρησιμοποιώ τους αγγλικούς όρους και όχι τους ελληνικούς για να αποφευχθούν παρορμητικές φρικαλεότητες του τύπου gigabytes - γιγάβυτα).
θα θεωρήσω ότι δεν είστε ΠΑΝΤΕΛΩΣ άσχετοι με τις βασικές έννοιες του προγραμματισμού (μόλις αναδύθηκαν αρκετά πρόσωπα στο μυαλό μου αυτή τη στιγμή). Ας πούμε απλά ότι δε ξέρετε Java και είστε της παλίας σχολής της C με 8πλούς pointers και άλλα τέτοια σαδομαζοχιστικά γούστα.
ΟΚ!
Η Java πρόκειται για μια object-oriented γλώσσα προγραμματισμού (γενικότερα θα χρησιμοποιώ τους αγγλικούς όρους και όχι τους ελληνικούς για να αποφευχθούν παρορμητικές φρικαλεότητες του τύπου gigabytes - γιγάβυτα).
Tuesday, August 10, 2010
Blogger και κώδικας
...και πάνω που λες "Ωραία, το φτιάξαμε το blog, πάμε να ποστάρουμε κάναν κώδικα", έρχεται ο μπλόγκερ και σε ξενερώνει.
Πώς να ποστάρεις κώδικα χωρίς να πάει να τον κάνει parse και να διατηρήσεις και το indention όταν δεν σου δίνει ένα code tag;
Ψάχνοντας βρίσκεις, οπότε έψαξα και βρήκα:
Θα το βάλω λέει τον κώδικα μου μέσα σε textarea tags και θα ορίσω λέει και γραμμές και στήλες.
Προσπαθώ το δοκιμάζω και όπως ήταν φυσικό σιγά μην ήταν έτσι εύκολα τα πράγματα.
Το μεν compose του blogger τα εμφάνιζε ωραία, το edit html τα ξέσκιζε, και το preview ήταν 50 φορές χειρότερο.
Καθ' ότι περασμένη η ώρα, βαριέμαι να ψάξω, οπότε λέω θα καταφύγω στην βαθιά σοφία μου και θα τα βάλω σε pre tags:
Αυτό δούλεψε σχετικά, αλλά πρέπει να πειράξεις την html και να βάλεις πχ αντί για <, το "& lt;" αντί για > το "& gt;" κ.ο.κ.
FAIL εν ολίγοις και κάπου εκεί το κλείνεις τσατισμένος και αποφασισμένος να το ξαναπιάσεις την επόμενη μέρα.
Την επόμενη μέρα, βλέποντας από δω κι από 'κει τι λένε, συνειδητοποίησα ότι θα πρέπει να πειράξω το template για να χρησιμοποιήσω το syntaxHighlighter.
και ιδού το αποτέλεσμα:
Πώς γίνεται λοιπόν όλο αυτό;
Θέλουμε να συνδέσουμε στο site μας τα αρχεία shCore.js και shCore.css που έχουν τον βασικό κώδικα και το stylesheet που θα χρησιμοποιείται.
Τα αρχεία αυτά, είτε τα κατεβάζουμε από το παραπάνω site και τα ανεβάζουμε σε κάποιον file hoster, ή χρησιμοποιούμε τα εξής link:
Υπάρχουν 2 τρόποι χρήσης, είτε με pre tags, είτε με script tags.Και τα 2 είναι ιδιαίτερα εύκολα και υπάρχουν οδηγίες εδώ
Πώς να ποστάρεις κώδικα χωρίς να πάει να τον κάνει parse και να διατηρήσεις και το indention όταν δεν σου δίνει ένα code tag;
Ψάχνοντας βρίσκεις, οπότε έψαξα και βρήκα:
Θα το βάλω λέει τον κώδικα μου μέσα σε textarea tags και θα ορίσω λέει και γραμμές και στήλες.
Προσπαθώ το δοκιμάζω και όπως ήταν φυσικό σιγά μην ήταν έτσι εύκολα τα πράγματα.
Το μεν compose του blogger τα εμφάνιζε ωραία, το edit html τα ξέσκιζε, και το preview ήταν 50 φορές χειρότερο.
Καθ' ότι περασμένη η ώρα, βαριέμαι να ψάξω, οπότε λέω θα καταφύγω στην βαθιά σοφία μου και θα τα βάλω σε pre tags:
<?php echo "Hello world"; ?>
Αυτό δούλεψε σχετικά, αλλά πρέπει να πειράξεις την html και να βάλεις πχ αντί για <, το "& lt;" αντί για > το "& gt;" κ.ο.κ.
FAIL εν ολίγοις και κάπου εκεί το κλείνεις τσατισμένος και αποφασισμένος να το ξαναπιάσεις την επόμενη μέρα.
Την επόμενη μέρα, βλέποντας από δω κι από 'κει τι λένε, συνειδητοποίησα ότι θα πρέπει να πειράξω το template για να χρησιμοποιήσω το syntaxHighlighter.
και ιδού το αποτέλεσμα:
<?php echo "Hello world"; ?>
Πώς γίνεται λοιπόν όλο αυτό;
Θέλουμε να συνδέσουμε στο site μας τα αρχεία shCore.js και shCore.css που έχουν τον βασικό κώδικα και το stylesheet που θα χρησιμοποιείται.
Τα αρχεία αυτά, είτε τα κατεβάζουμε από το παραπάνω site και τα ανεβάζουμε σε κάποιον file hoster, ή χρησιμοποιούμε τα εξής link:
τα οποία τα βάζουμε πριν κλείσει το head tag.
Το syntaxHighlighter υποστηρίζει διάφορες γλώσσες, μια λίστα των οποίων μπορείτε να δείτε εδώ.
Βάσει λοιπόν της γλώσσας που θέλετε να γράψετε θα συνδέσετε και το αντίστοιχο αρχείο κάτω από το σχόλιο "add brushes here".
Πχ για php το αρχείο που χρειάστηκα είναι:
Τέλος, για να χρωματιστεί ο κώδικας πρέπει να βάλουμε στο τέλος, πριν κλείσει το body tag το εξής:
Υπάρχουν 2 τρόποι χρήσης, είτε με pre tags, είτε με script tags.Και τα 2 είναι ιδιαίτερα εύκολα και υπάρχουν οδηγίες εδώ
Subscribe to:
Posts (Atom)