ΚΕΝΤΡΟ ΠΛΗ.ΝΕ.Τ. Ν. ΦΛΩΡΙΝΑΣ

Δημιουργία Database-Driven Web Site
με Χρήση PHP και MySQL

 

Η Ανάγκη για ένα Database-Driven Web Site

Σήμερα στο Web, το περιεχόμενο (content) είναι αυτό που κυριαρχεί. Αφού έχετε μάθει πολύ καλά την HTML και μερικά κόλπα στην JavaScript και τη Δυναμική (Dynamic) HTML, μπορείτε να δημιουργήσετε ένα Web site με εντυπωσιακή εμφάνιση. Έρχεται, όμως, η ώρα που πρέπει να γεμίσετε τη σελίδα σας με πραγματικές πληροφορίες (real information). Όποιο site τραβάει το ενδιαφέρον των επισκεπτών σας επανειλημμένα, θα πρέπει να περιέχει καινούργιο και συνεχώς ανανεούμενο περιεχόμενο.

Το πρόβλημα είναι ότι συχνά, οι άνθρωποι που παρέχουν το περιεχόμενο για ένα site δεν είναι οι ίδιοι μ’ αυτούς που κάνουν και τη σχεδίασή του (design). Αλλά είναι σύνηθες, ο παροχέας του περιεχομένου να μην γνωρίζει καθόλου από HTML. Πώς, όμως, μπορούμε να πάρουμε τότε το περιεχόμενο από τον παροχέα και να το εγκαταστήσουμε στο Web site;

Δεν μπορούν φυσικά όλες οι εταιρείες να απασχολούν πλήρως έναν Webmaster και οι περισσότεροι από τους Webmasters έχουν άλλες δουλειές να κάνουν από το να αντιγράφουν αρχεία του Word μέσα σε tags της HTML. Η λύση σ’ αυτό το πρόβλημα είναι το database-driven site design. Πετυχαίνοντας τον πλήρη διαχωρισμό ανάμεσα στη σχεδίαση του site και το περιεχόμενο που θέλουμε να παρουσιάσουμε μέσα σ’ αυτό, μπορούμε να δουλέψουμε με το ένα χωρίς να μας απασχολεί το άλλο.

Αντί να δημιουργούμε ένα HTML αρχείο για την κάθε σελίδα του site, χρειάζεται μόνο να δημιουργήσουμε μια σελίδα για το κάθε είδος πληροφορίας που θέλουμε να παρουσιάσουμε. Αντί να επικολλάμε συνέχεια νέο περιεχόμενο στις σελίδες μας, δημιουργούμε ένα απλό σύστημα διαχείρισης περιεχομένου (content management system) που δίνει τη δυνατότητα στους συγγραφείς να δημοσιεύουν (post) το καινούργιο περιεχόμενό τους οι ίδιοι χωρίς να κάνουν καθόλου χρήση της HTML.

Για να δημιουργήσουμε ένα database-driven Web site, θα χρησιμοποιήσουμε τη γλώσσα συγγραφής σεναρίων στην πλευρά του διακομιστή (server-side scripting language) PHP και τη σχεσιακή βάση δεδομένων (relational database) MySQL. Θα πρέπει, όμως, ο Web host στον οποίο δημοσιεύουμε τις σελίδες μας να υποστηρίζει τον συνδυασμό PHP/MySQL.

 

Η PHP και η MySQL

Θα δούμε όλη τη διαδικασία για τη δημιουργία ενός database-driven Web site. Θα κάνουμε τα πρώτα μας βήματα πέρα από την HTML και την JavaScript και από το περιβάλλον του σχεδιασμού ενός site στην πλευρά του πελάτη (client-side site design). Θα δούμε τι χρειάζεται για να μπορέσουμε να δημιουργήσουμε content-driven sites, που είναι τόσο περιζήτητα σήμερα.

Τα εργαλεία που θα χρησιμοποιήσουμε γι’ αυτή τη δουλειά θα είναι τα προγράμματα PHP και MySQL. Η PHP είναι μια γλώσσα συγγραφής σεναρίων στην πλευρά του διακομιστή (server-side scripting language). Μπορούμε να την φανταστούμε σαν ένα πρόσθετο (plug-in) για τον Web server που του δίνει τη δυνατότητα να κάνει κάτι περισσότερο από το να στέλνει απλά και μόνο απλές ιστοσελίδες (Web pages) όταν τις ζητάνε οι φυλλομετρητές.

Με εγκατεστημένη την PHP, ο Web server θα είναι σε θέση να διαβάζει ένα νέο είδος αρχείων, το αποκαλούμενο PHP script, το οποίο μπορεί να κάνει εργασίες όπως ανάκτηση πληροφοριών της τελευταίας στιγμής (retrieve up-to-the-minute information) από μια βάση δεδομένων και καταχώρησή τους σε μια Web page πριν αυτή αποσταλεί στον φυλλομετρητή που τη ζήτησε.

Για να μπορέσουμε να ανακτήσουμε πληροφορίες από μια βάση δεδομένων, θα πρέπει πρώτα φυσικά να έχουμε μια βάση δεδομένων (database) και αυτός είναι ο λόγος της παρουσίας της MySQL. Η MySQL είναι ένα σύστημα διαχείρισης σχεσιακών βάσεων δεδομένων (relational database management system) ή RDBMS. Σε γενικές γραμμές είναι ένα πακέτο λογισμικού (software package) που είναι πολύ καλό στην οργάνωση και τη διαχείριση μεγάλων ποσοτήτων πληροφοριών.

Με τη χρήση της MySQL είναι εύκολη η πρόσβαση σ’ αυτές τις πληροφορίες χρησιμοποιώντας μια γλώσσα συγγραφής σεναρίων στην πλευρά του διακομιστή (server-side scripting languages), όπως είναι η PHP. Ο κώδικας που θα χρησιμοποιήσουμε εδώ θα μπορεί να εφαρμοσθεί σ’ έναν διακομιστή που βασίζεται στα Windows ή στο Unix.

 

Αν ο Web Host Παρέχει την PHP και την MySQL

Αν ο Web host που μας παρέχει τον χώρο για τις ιστοσελίδες μας (Web space) έχει ήδη εγκαταστήσει και ρυθμίσει την MySQL και την PHP, τότε δεν υπάρχει και πολλή δουλειά που πρέπει να κάνουμε. Πιο συγκεκριμένα, θα χρειαστούμε ένα όνομα χρήστη (username) και έναν κωδικό ασφαλείας (password) για να μπορέσουμε να έχουμε πρόσβαση στον MySQL server που έχει στηθεί για μας. Είναι πολύ πιθανό να έχει στηθεί μια κενή βάση δεδομένων για μας για να μην μπλεχτούμε με τις βάσεις δεδομένων των άλλων χρηστών που χρησιμοποιούν τον ίδιο MySQL server.

Υπάρχουν δύο τρόποι για να έχουμε πρόσβαση στον MySQL server. Ο πρώτος είναι να χρησιμοποιήσουμε το telnet για να συνδεθούμε (log) με τον host και να χρησιμοποιήσουμε τα προγράμματα πελάτη της MySQL, όπως είναι τα mysql, mysqladmin, mysqldump κ.ά., που είναι εγκατεστημένα για να αλληλεπιδρούν (interact) απευθείας με τον MySQL server.

Ο δεύτερος είναι να εγκαταστήσουμε αυτά τα προγράμματα πελάτη (client programs) στον δικό μας υπολογιστή και να τα συνδέσουμε με τον MySQL server. Ο Web host με τον οποίο συνεργαζόμαστε πρέπει να υποστηρίζει τη μια ή και τις δύο από τις δύο παραπάνω μεθόδους.

Αν υποστηρίζει τη σύνδεση (logging in) με το telnet, θα χρειασθούμε ένα όνομα χρήστη (username) και έναν κωδικό ασφαλείας (password) για τη σύνδεση (login) με το telnet εκτός από εκείνα που θα χρησιμοποιήσουμε για να έχουμε πρόσβαση στον MySQL server και που μπορεί να είναι και διαφορετικά.

Αν υποστηρίζει την απομακρυσμένη πρόσβαση (remote access) στον MySQL server, θα πρέπει να φορτώσουμε (download) ένα πρόγραμμα για να μπορέσουμε να συνδεθούμε και να έχουμε αλληλεπίδραση με τον server.

 

Το Πρώτο μας PHP Script

Για να έχουμε μια πρώτη γεύση για το πώς μοιάζει ένα script της PHP σε μια PHP-driven Web page, θα δούμε ένα πολύ απλό αρχικό παράδειγμα. Φορτώνουμε έναν text editor, όπως το Notepad, και δημιουργούμε ένα νέο αρχείο κειμένου με όνομα today.php, όπου γράφουμε τα εξής :

<HTML>

<HEAD>

<TITLE> Η Σημερινή Ημερομηνία </TITLE>

</HEAD>

<BODY>

<P> Η σημερινή ημερομηνία, σύμφωνα με τον Web server, είναι :

<?php

            echo( date("l, F dS Y.") );

?>

</BODY>

</HTML>

Το αποθηκεύουμε και το τοποθετούμε στο Web site όπως ακριβώς θα κάναμε και μ’ ένα κανονικό HTML αρχείο. Μετά, βλέπουμε τι θα εμφανίσει όταν το δούμε στον φυλλομετρητή μας. Αν δούμε τον πηγαίο κώδικα (view source) της σελίδας, αυτό που θα εμφανισθεί θα είναι ένα κανονικό HTML αρχείο που θα περιέχει την τρέχουσα ημερομηνία.

Ο κώδικας της PHP, δηλ. ο,τιδήποτε υπάρχει ανάμεσα στα tags <?php και ?> στον παραπάνω κώδικα, έχει διερμηνευθεί (interpreted) από τον Web server και έχει μετατραπεί σε κανονικό κείμενο (normal text) πριν αποσταλεί στον φυλλομετρητή μας. Η ομορφιά της PHP, όπως και των άλλων γλωσσών server-side scripting, είναι ότι ο Web browser δεν χρειάζεται να γνωρίζει ο,τιδήποτε γι’ αυτό.

 

Ξεκινώντας με την PHP

Θα δούμε τώρα τη γλώσσα συγγραφής σεναρίων στην πλευρά του διακομιστή (server-side scripting language) PHP, η οποία παρέχει πλήρη υποστήριξη για επικοινωνία με τις βάσεις δεδομένων της MySQL. Μια γλώσσα συγγραφής σεναρίων στην πλευρά του διακομιστή (server-side scripting language) είναι παρόμοια με την JavaScript καθώς και οι δύο μας δίνουν τη δυνατότητα να ενσωματώσουμε μικρά προγράμματα (scripts) μέσα στον κώδικα HTML μιας ιστοσελίδας (Web page).

Κατά την εκτέλεση, αυτά τα scripts μάς δίνουν τη δυνατότητα να ελέγχουμε το τι θα εμφανίζεται στο παράθυρο του φυλλομετρητή μ’ έναν πολύ πιο ευέλικτο τρόπο απ’ ό,τι με την απλή HTML. Η ειδοποιός διαφορά ανάμεσα στην JavaScript και την PHP είναι ότι ο Web browser διερμηνεύει (interprets) την JavaScript μόλις έχει φορτωθεί η ιστοσελίδα (Web page) που περιέχει το script, ενώ οι server-side scripting languages, όπως η PHP, διερμηνεύονται από τον Web server πριν ακόμα σταλεί η σελίδα στον browser.

Αφού διερμηνευθεί, ο κώδικας της PHP αντικαθίσταται στην ιστοσελίδα με τα αποτελέσματα του script κι έτσι αυτό που βλέπει ο φυλλομετρητής είναι ένα κανονικό HTML αρχείο. Το script επεξεργάζεται εξ ολοκλήρου από τον server, εξ ου και ο χαρακτηρισμός server-side scripting language.

Ας ξαναδούμε το αρχείο today.php :

<HTML>

<HEAD>

<TITLE> Η Σημερινή Ημερομηνία </TITLE>

</HEAD>

<BODY>

<P> Η σημερινή ημερομηνία, σύμφωνα με τον Web server, είναι :

<?php

echo( date("l, F dS Y.") );

            ?>
</BODY>
</HTML>

Ο περισσότερος κώδικας είναι καθαρή HTML, ενώ η γραμμή ανάμεσα στα <?php και ?> είναι γραμμένη σε κώδικα PHP. Το <?php σημαίνει ότι ξεκινάει ο κώδικας της PHP και το ?> σημαίνει ότι τελειώνει ο κώδικας της PHP.

Ο Web server διερμηνεύει ο,τιδήποτε υπάρχει ανάμεσα σ’ αυτούς τους οριοθέτες (delimiters) και το μετατρέπει σε κανονικό κώδικα HTML πριν στείλει την ιστοσελίδα (Web page) στον φυλλομετρητή (browser) που την ζήτησε. Έτσι, ο φυλλομετρητής θα εμφανίσει κάτι σαν το εξής :

<HTML>

<HEAD>

<TITLE> Η Σημερινή Ημερομηνία </TITLE>

</HEAD>

<BODY>

<P> Η σημερινή ημερομηνία, σύμφωνα με τον Web server, είναι :

Wednesday, June 7th 2000.

</BODY>

</HTML>

Βλέπουμε ότι έχουν χαθεί όλα τα σημάδια του κώδικα της PHP και στη θέση τους έχει εμφανισθεί η έξοδος (το αποτέλεσμα) του script και φαίνεται σαν κανονική HTML.

Απ’ αυτό το παράδειγμα μπορούμε να δούμε τα πολλά πλεονεκτήματα του server-side scripting :

 

Βασική Σύνταξη και Εντολές της PHP

Η σύνταξη της PHP είναι πολύ κοντά στις εξής γλώσσες : C, C++, Java, JavaScript και Perl. Ένα script της PHP αποτελείται από μια σειρά εντολών (commands ή statements), η καθεμία από τις οποίες είναι μια οδηγία (instruction) που πρέπει να ακολουθήσει ο Web server πριν προχωρήσει στην επόμενη. Οι εντολές της PHP τερματίζονται πάντα με τον χαρακτήρα semicolon (;).

Η παρακάτω αποτελεί μια τυπική εντολή της PHP :

echo( "This is a <B>test</B>!" );

Αυτή η εντολή καλεί μια ενσωματωμένη συνάρτηση με όνομα echo() και της μεταβιβάζει το εξής string : This is a <B>test</B>! Η PHP διαθέτει πολλές ενσωματωμένες συναρτήσεις με τις οποίες μπορούμε να κάνουμε πολλά πράγματα από το να στείλουμε e-mail μέχρι να επεξεργαστούμε πληροφορίες που είναι αποθηκευμένες σε διάφορα είδη βάσεων δεδομένων.

Η συνάρτηση echo() απλά λαμβάνει το κείμενο που της μεταβιβάζεται και το τοποθετεί στον HTML κώδικα της σελίδας στην τρέχουσα τοποθεσία. Ας δούμε το εξής :

<HTML>

<HEAD>

<TITLE> Ένα Απλό Παράδειγμα PHP </TITLE>

</HEAD>

<BODY>

<P><?php echo("Πρόκειται για ένα <B>test</B>!"); ?></P>

</BODY>

</HTML>

Αν αποθηκεύσουμε αυτόν τον κώδικα σ’ ένα αρχείο με όνομα test.php, ή test.php3 αν ο Web host δεν έχει ρυθμίσει τα αρχεία .php ώστε να αναγνωρίζονται σαν scripts της PHP, και το τοποθετήσουμε στον Web server, ένας φυλλομετρητής που φορτώνει αυτή τη σελίδα, στην ουσία θα φορτώσει το εξής κείμενο :

<HTML>

<HEAD>

<TITLE> Ένα Απλό Παράδειγμα PHP  </TITLE>

</HEAD>

<BODY>

<P> Πρόκειται για ένα <B>test</B>!</P>

</BODY>
</HTML>

Τα εισαγωγικά που χρησιμοποιήσαμε στη συνάρτηση echo() σημαδεύουν την αρχή και το τέλος των strings κειμένου στην PHP.

 

Μεταβλητές και Τελεστές

Οι μεταβλητές (variables) της PHP είναι ολόιδιες με τις μεταβλητές που υπάρχουν στις περισσότερες γλώσσες προγραμματισμού. Η επόμενη εντολή δημιουργεί μια μεταβλητή με όνομα $testvariable και της εκχωρεί την τιμή 3 :

$testvariable = 3;

Πρέπει να έχουμε υπόψη μας ότι όλα τα ονόματα μεταβλητών στην PHP ξεκινούν με το σύμβολο του δολαρίου ($).

Η PHP αντιμετωπίζει τους τύπους δεδομένων κάπως χαλαρά ("loosely typed" language), το οποίο σημαίνει ότι μια μόνο μεταβλητή μπορεί να περιέχει οποιονδήποτε τύπο δεδομένων, είτε αριθμό (number), είτε string κειμένου ή κάτι άλλο, και ακόμη μπορεί να αλλάζει τύπους δεδομένων σ’ όλη τη διάρκειά της.

Έτσι, αν γράψουμε την επόμενη εντολή μετά από την εντολή που γράψαμε παραπάνω, θα εκχωρήσουμε μια νέα τιμή στη μεταβλητή $testvariable και το περιεχόμενο της μεταβλητής θα αλλάξει από αριθμό σ’ ένα string κειμένου :

$testvariable = "Three";

Το σύμβολο = (equals sign) που χρησιμοποιήσαμε στις δύο τελευταίες εντολές αποκαλείται τελεστής εκχώρησης (assignment operator) γιατί χρησιμοποιείται για να εκχωρήσουμε τιμές σε μεταβλητές. Μπορούμε να χρησιμοποιήσουμε και τους γνωστούς μας αριθμητικούς τελεστές για να κάνουμε μαθηματικές πράξεις σε τιμές, ως εξής :

$testvariable = 1 + 1;         // Εκχωρεί την τιμή 2

$testvariable = 1 – 1;          // Εκχωρεί την τιμή 0

$testvariable = 2 * 2;          // Εκχωρεί την τιμή 4

$testvariable = 2 / 2;            // Εκχωρεί την τιμή 1

Οι παραπάνω γραμμές τελειώνουν μ’ ένα σχόλιο (comment) η καθεμία. Τα σχόλια (comments) αποτελούν έναν τρόπο για να περιγράψουμε το τι κάνει ο κώδικάς μας, εισάγοντας ένα επεξηγηματικό κείμενο στον κώδικά μας και λέγοντας στον διερμηνευτή (interpreter) της PHP να το αγνοήσει. Τα σχόλια αρχίζουν με τους χαρακτήρες // και τελειώνουν στο τέλος της ίδιας γραμμής. Η PHP χρησιμοποιεί επίσης και το στυλ σχολιασμού /* … κείμενο σχολίου … */ που μας είναι γνωστό από άλλες γλώσσες προγραμματισμού.

Η PHP διαθέτει και έναν τελεστή (operator) για να μπορούμε να ενώσουμε strings κειμένου μαζί :

// Εκχωρεί το κείμενο "Hi there!".

$testvariable = "Hi " . "there!";

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

$var1 = "PHP";                    // Εκχωρεί το κείμενο "PHP" στην $var1

$var2 = 5;                             // Εκχωρεί την τιμή 5 στην $var2

$var3 = $var2 + 1;              // Εκχωρεί την τιμή 6 στην $var3

$var2 = $var1;                     // Εκχωρεί το κείμενο "PHP" στην $var2

echo($var1);                         // Εμφανίζει "PHP"

echo($var2);                         // Εμφανίζει "PHP"

echo($var3);                         // Εμφανίζει 6

echo($var1 . " rules!");        // Εμφανίζει "PHP rules!"

echo("$var1 rules!");            // Εμφανίζει "PHP rules!"

echo('$var1 rules!');             // Εμφανίζει '$var1 rules!'

Ας προσέξουμε ιδιαίτερα τις δύο τελευταίες γραμμές. Μπορούμε να συμπεριλάβουμε το όνομα μιας μεταβλητής απευθείας μέσα στο κείμενο ενός string και να αντικατασταθεί το όνομα της μεταβλητής με την τιμή της αν περικλείσουμε το string με διπλά εισαγωγικά (double quotes). Όπως φαίνεται από την τελευταία γραμμή, όμως, ένα string που περικλείεται με μονά εισαγωγικά (single quotes) δεν αντικαθιστά τα ονόματα μεταβλητών με τις τιμές τους.

 

Η Αλληλεπίδραση με τον Χρήστη και οι Φόρμες

Για πολλές από τις ενδιαφέρουσες εφαρμογές της PHP, το να μπορούμε να αλληλεπιδρούμε (interact) με τον χρήστη που βλέπει την ιστοσελίδα μας είναι κάτι πολύ βασικό. Οι χρήστες της JavaScript θα είναι συνηθισμένοι να αναφέρονται στα χειριστήρια συμβάντων (event handlers), τα οποία μας δίνουν τη δυνατότητα να αντιδρούμε απευθείας σε πολλές ενέργειες (actions) του χρήστη, όπως η μετακίνηση του ποντικιού πάνω από έναν σύνδεσμο (link) της σελίδας.

Οι server-side scripting languages, όπως είναι η PHP, έχουν μια πιο περιορισμένη εμβέλεια όσον αφορά την αλληλεπίδραση με τον χρήστη (user interaction). Εφόσον η μόνη περίπτωση που εκτελείται ο κώδικας της PHP είναι όταν ζητείται μια σελίδα από τον server, η αλληλεπίδραση με τον χρήστη μπορεί να λάβει χώρα μ’ έναν τρόπο back-and-forth, με τον χρήστη να στέλνει αιτήσεις (requests) στον server και τον server να απαντάει (response) με δυναμικά παραγόμενες ιστοσελίδες.

Το κλειδί στην αλληλεπίδραση με τον χρήστη στην PHP είναι να κατανοήσουμε τις τεχνικές που υπάρχουν για την αποστολή πληροφοριών μαζί με την αίτηση του χρήστη για μια νέα ιστοσελίδα (Web page). Η PHP μπορεί να το κάνει αυτό πολύ εύκολα. Η απλούστερη μέθοδος για να στείλουμε πληροφορίες μαζί με μια αίτηση για σελίδα (page request) είναι να χρησιμοποιήσουμε το "URL query string". Αν έχετε δει ποτέ ένα URL με τον χαρακτήρα ? μετά από το όνομα του αρχείου, έχετε δει αυτήν την τεχνική σε χρήση.

Θα δούμε ένα απλό παράδειγμα. Δημιουργούμε ένα κανονικό HTML αρχείο, χωρίς επέκταση αρχείου .php εφόσον δεν θα υπάρχει καθόλου PHP κώδικας σ’ αυτό το αρχείο, και καταχωρούμε τον εξής σύνδεσμο (link) :

<A HREF="welcome.php?name=Kevin"> Γεια σας, είμαι ο Kevin! </A>

Αυτός είναι ένας σύνδεσμος (link) προς το αρχείο welcome.php, αλλά εκτός από τη σύνδεση με το αρχείο, περνάμε (μεταβιβάζουμε) επίσης το όνομα και την τιμή μιας μεταβλητής μαζί με την αίτηση για τη σελίδα (page request). Η μεταβλητή μεταβιβάζεται σαν μέρος του "query string", το οποίο είναι το τμήμα του URL που βρίσκεται μετά το ?.

Η μεταβλητή ονομάζεται name και η τιμή της είναι Kevin. Για να συνοψίσουμε, έχουμε δημιουργήσει έναν σύνδεσμο (link) που φορτώνει το αρχείο welcome.php και ενημερώνει τον κώδικα της PHP που περιέχεται σ’ αυτό το αρχείο ότι η μεταβλητή name είναι ίση με Kevin.

Για να δούμε τι σημαίνει αυτό για μας, πρέπει να ρίξουμε μια ματιά στο αρχείο welcome.php. Το δημιουργούμε σαν ένα καινούργιο HTML αρχείο, αλλά με την επέκταση .php, η οποία ενημερώνει τον Web server να είναι έτοιμος να διερμηνεύσει κάποιον κώδικα της PHP που υπάρχει στο αρχείο αυτό.

Αν ο Web server δεν έχει ρυθμισθεί για να δέχεται το .php σαν μια επέκταση αρχείου για τα αρχεία PHP, θα πρέπει να το ονομάσουμε welcome.php3. Στο κυρίως σώμα αυτού του καινούργιου αρχείου γράφουμε τα εξής :

<?php

            echo( "Καλώς ήρθατε στο Web site μας, $name!" );

?>

Τώρα, αν χρησιμοποιήσουμε τον σύνδεσμο (link) που υπάρχει στο πρώτο αρχείο για να φορτώσουμε το δεύτερο αρχείο, θα δούμε ότι η σελίδα εμφανίζει το μήνυμα "Καλώς ήρθατε στο Web site μας, Kevin!". Δηλαδή, η τιμή της μεταβλητής που υπήρχε στο query string του URL τοποθετήθηκε αυτόματα σε μια μεταβλητή της PHP με όνομα $name, την οποία χρησιμοποιήσαμε για να εμφανίσουμε την μεταβιβαζόμενη τιμή σαν μέρος ενός string κειμένου.

Μπορούμε να μεταβιβάσουμε και περισσότερες από μία τιμές στο query string, αν το επιθυμούμε. Θα δούμε μια λίγο πιο πολύπλοκη παραλλαγή του ίδιου παραδείγματος. Αλλάζουμε τον σύνδεσμο (link) στο HTML αρχείο για να είναι ως εξής :

<A HREF="welcome.php?firstname=Kevin&lastname=Yank">

Γεια σας, είμαι ο Kevin Yank! </A>

Αυτή τη φορά μεταβιβάζουμε τις εξής δύο μεταβλητές : firstname και lastname, οι οποίες ξεχωρίζουν μέσα στο query string με τον χαρακτήρα & (ampersand). Μπορούμε να μεταβιβάσουμε κι άλλες μεταβλητές αν χρειασθεί, ξεχωρίζοντας το κάθε ζευγάρι name=value από το κείμενο με τον χαρακτήρα &.

Όπως και πριν, μπορούμε να χρησιμοποιήσουμε τις τιμές των δύο μεταβλητών στο αρχείο welcome.php, ως εξής :

<?php

echo( "Καλώς ήρθατε στο Web site μας, $firstname $lastname!" );

?>

Μέχρι εδώ όλα καλά, αλλά έχουμε δρόμο ακόμη για να πετύχουμε τον στόχο μας για πραγματική αλληλεπίδραση με τον χρήστη (true user interaction), όπου ο χρήστης θα μπορεί πράγματι να καταχωρήσει δικές του τιμές και να τις επεξεργαστεί η PHP.

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

<FORM ACTION="welcome.php" METHOD=GET>

First Name : <INPUT TYPE=TEXT NAME="firstname"><BR>

Last Name : <INPUT TYPE=TEXT NAME="lastname">

<INPUT TYPE=SUBMIT VALUE="Submit">

</FORM>

Αυτή η φόρμα έχει το ίδιο ακριβώς αποτέλεσμα με τον δεύτερο σύνδεσμο που είδαμε προηγουμένως, ο οποίος περιείχε το firstname=Kevin& lastname=Yank στο query string, με τη διαφορά ότι μπορούμε να γράψουμε ό,τι ονόματα θέλουμε.

Όταν κάνουμε κλικ στο πλήκτρο υποβολής (submit button), το οποίο περιέχει την ετικέτα Submit, ο φυλλομετρητής θα φορτώσει το αρχείο welcome. php και θα προσθέσει αυτόματα τις μεταβλητές και τις τιμές τους στο query string για μας.

Παίρνει τα ονόματα των μεταβλητών από τις ιδιότητες (attributes) NAME των tags INPUT TYPE=TEXT και παίρνει τις τιμές που έχει καταχωρήσει ο χρήστης στα πεδία κειμένου (text fields).

Η ιδιότητα METHOD του tag FORM χρησιμοποιείται για να γνωρίζει ο φυλλομετρητής πώς να στείλει τις μεταβλητές και τις τιμές τους μαζί με την αίτηση (request). Η τιμή GET, όπως την χρησιμοποιήσαμε παραπάνω, τις κάνει να μεταβιβάζονται στο query string, αλλά υπάρχει και μια άλλη εναλλακτική λύση. Δεν είναι πάντα επιθυμητό, ή και τεχνικά εφικτό, να εμφανισθούν οι τιμές στο query string.

Τι θα συνέβαινε αν είχαμε ένα tag TEXTAREA στη φόρμα για να μπορεί ο χρήστης να καταχωρήσει μια μεγάλη ποσότητα κειμένου; Ένα URL που περιέχει πολλές παραγράφους κειμένου στο query string θα είναι άσχημα μεγάλο και θα ξεπερνάει κατά πολύ το μέγιστο μήκος του URL στους σημερινούς φυλλομετρητές.

Η εναλλακτική λύση είναι για τον φυλλομετρητή να μεταβιβάσει τις πληροφορίες αόρατα, στο παρασκήνιο. Ο κώδικας γι’ αυτό είναι ακριβώς ο ίδιος, αλλά αντί να θέσουμε την ιδιότητα METHOD της φόρμας ίση με GET, την ορίζουμε ίση με POST :

<FORM ACTION="welcome.php" METHOD=POST>

First Name : <INPUT TYPE=TEXT NAME="firstname"><BR>

Last Name : <INPUT TYPE=TEXT NAME="lastname">

<INPUT TYPE=SUBMIT VALUE="Submit">

</FORM>

Αυτή η φόρμα είναι λειτουργικά ισοδύναμη με την προηγούμενη και η μόνη διαφορά είναι ότι το URL της σελίδας που φορτώνεται όταν ο χρήστης κάνει κλικ στο πλήκτρο Submit δεν θα περιέχει ένα query string. Από την άλλη πλευρά, μπορούμε έτσι να συμπεριλάβουμε μεγάλες ή ευαίσθητες τιμές (όπως κωδικούς εισόδου – passwords) στα δεδομένα που υποβάλλονται από τη φόρμα, χωρίς να εμφανίζονται αυτά στο query string.

Από την άλλη, αν ο χρήστης μαρκάρει (bookmarks) τη σελίδα που προέρχεται από την υποβολή της φόρμας, το bookmark θα είναι άχρηστο, εφόσον δεν θα περιέχει τις τιμές που υποβλήθηκαν. Αυτός, παρεμπιπτόντως, είναι και ο κύριος λόγος που μηχανές αναζήτησης (search engines), όπως η AltaVista, χρησιμοποιούν το query string για να υποβάλλουν στοιχεία για αναζήτηση (search terms).

Αν μαρκάρουμε (bookmark) μια σελίδα που προέκυψε από μια αναζήτηση στην AltaVista, θα μπορούμε να χρησιμοποιήσουμε αυτό το bookmark για να ξανακάνουμε την ίδια αναζήτηση αργότερα, εφόσον τα στοιχεία της αναζήτησης (search terms) περιέχονται στο URL.

 

Οι Δομές Ελέγχου (Control Structures)

Η PHP, όπως όλες οι γλώσσες προγραμματισμού, παρέχει δυνατότητες για να επηρεάσουμε τη ροή ελέγχου (flow of control) σ’ ένα script, δηλ. περιέχει ειδικές εντολές που μας επιτρέπουν να παρεκκλίνουμε από τη σειριακή σειρά εκτέλεσης των εντολών που έχουμε δει μέχρι τώρα. Αυτές οι εντολές αποκαλούνται δομές ελέγχου (control structures).

Η βασικότερη και πιο συχνά χρησιμοποιούμενη δομή ελέγχου είναι η εντολή if-else, η σύνταξη της οποίας είναι η εξής :

if ( <συνθήκη> ) {

            // Εντολή(ές) που θα εκτελεσθούν αν η <συνθήκη>

            // είναι αληθής (true)

} else {

            // (Προαιρετικές) Εντολές που θα εκτελεσθούν

// αν η <συνθήκη> είναι ψευδής (false)

}

Αυτή η δομή ελέγχου μάς δίνει τη δυνατότητα να πούμε στην PHP να εκτελέσει ένα σύνολο εντολών ή κάποιο άλλο ανάλογα με το αν κάποια συνθήκη είναι true ή false. Ακολουθεί ένα παράδειγμα για το αρχείο welcome. php που δημιουργήσαμε προηγουμένως :

if ( $name == "Kevin" ) {

            echo( "Καλώς ήρθες, μεγάλε!" );

} else {

            echo( "Καλώς ήρθες, $name!" );

}

Τώρα, αν η μεταβλητή name που μεταβιβάζεται στη σελίδα έχει την τιμή Kevin, θα εμφανισθεί ένα ειδικό μήνυμα. Αλλιώς, θα εμφανισθεί ένα συνηθισμένο μήνυμα που θα περιέχει το όνομα που καταχώρησε ο χρήστης.

Η δήλωση else είναι προαιρετική. Αν θελήσουμε να εμφανίσουμε το ειδικό μήνυμα αν έχει καταχωρηθεί το κατάλληλο όνομα και αν όχι να μην εμφανισθεί τίποτα, ο κώδικας είναι ο εξής :

if ( $name == "Kevin" ) {

            echo( "Καλώς ήρθες, μεγάλε!" );

}

Το σύμβολο = = που χρησιμοποιήσαμε στην παραπάνω συνθήκη είναι ο τελεστής που χρησιμοποιεί η PHP για να συγκρίνει δύο τιμές και να διαπιστώσει αν είναι ίσες. Δεν πρέπει να ξεχνάμε να γράφουμε και τα δύο =, επειδή το ένα = είναι ο τελεστής εκχώρησης (assignment operator) και αντί να συγκρίνει τις δύο τιμές, κάνει εκχώρηση τιμής στη μεταβλητή.

Μπορούμε να έχουμε και πιο πολύπλοκες συνθήκες από μια απλή σύγκριση για ισότητα. Τροποποιήσαμε προηγουμένως το αρχείο welcome.php3 για να έχουμε τις μεταβλητές firstname και lastname. Αν θελήσουμε να εμφανίσουμε ένα μήνυμα μόνο για ένα συγκεκριμένο άτομο, θα πρέπει να ελέγξουμε τις τιμές και από τα δύο ονόματα με τον λογικό τελεστή and, ως εξής :

if ( "Kevin" == $firstname and "Yank" == $lastname ) {

echo( "Καλώς ήρθες, μεγάλε!" );

}

Η παραπάνω συνθήκη θα είναι αληθής (true) αν και μόνο αν η $firstname έχει την τιμή Kevin και η $lastname έχει την τιμή Yank. Ο τελεστής and στην παραπάνω συνθήκη επιστρέφει την τιμή true αν και οι δύο συγκρίσεις αποτιμηθούν σε true.

Ένας άλλος λογικός τελεστής είναι ο or, ο οποίος επιστρέφει τιμή true αν η μια ή και οι δύο συνθήκες είναι true. Αν είστε περισσότεροι εξοικειωμένοι με την JavaScript ή την C, ο τελεστής && και ο || για το and και το or αντίστοιχα, δουλεύουν εξίσου καλά και στην PHP.

 

Ο Βρόχος While

Μια άλλη χρήσιμη δομή ελέγχου (control structure) της PHP είναι ο βρόχος while. Ενώ η εντολή if-else μάς δίνει τη δυνατότητα να επιλέξουμε αν θα εκτελέσουμε ή όχι ένα σύνολο εντολών ανάλογα με την τιμή επιστροφής μιας συνθήκης, ο βρόχος while μάς δίνει τη δυνατότητα να χρησιμοποιήσουμε μια συνθήκη για να καθορίσουμε πόσες φορές θα εκτελεσθεί επανειλημμένα ένα σύνολο εντολών.

Η σύνταξη του βρόχου while είναι η εξής :

while ( <συνθήκη> ) {

            // εντολές που θα εκτελούνται συνέχεια

            // για όσο διάστημα η <συνθήκη> παραμένει αληθής (true)

}

Θα δούμε ένα απλό παράδειγμα με τον βρόχο while, όπου θα μετρήσουμε ως το 10.

$count = 1;

while ($count <= 10) {

            echo( "$count " );

            $count++;

}

Το αποτέλεσμα από την εκτέλεση του παραπάνω κώδικα θα είναι το εξής string : "1 2 3 4 5 6 7 8 9 10".

Χρησιμοποιήσαμε τον αριθμητικό τελεστή σύγκρισης <= (μικρότερο από ή ίσο) και οι άλλοι αριθμητικοί τελεστές σύγκρισης είναι οι >= (μεγαλύτερο από ή ίσο), < (μικρότερο από), > (μεγαλύτερο από) και != (όχι ίσο).

 

Σελίδες Πολλαπλού Σκοπού (Multi-Purpose Pages)

Ας υποθέσουμε ότι θέλουμε να φτιάξουμε ένα site ώστε να εμφανίζει το όνομα του επισκέπτη (χρήστη) στην κορυφή της κάθε σελίδας. Με το παράδειγμα που είδαμε προηγουμένως με την εμφάνιση του χαιρετιστήριου μηνύματος, έχουμε κάνει τη μισή δουλειά.

Για να μπορέσουμε να επεκτείνουμε το παράδειγμα σ’ αυτό που θέλουμε να πετύχουμε, θα πρέπει να ξεπεράσουμε τα εξής προβλήματα :

Το πρώτο πρόβλημα δεν είναι πολύ δύσκολο να ξεπεραστεί. Εφόσον έχουμε το όνομα του χρήστη σε μια μεταβλητή σε κάποια σελίδα, μπορούμε να το μεταβιβάσουμε σε μια άλλη σελίδα προσθέτοντας το όνομα στο query string όλων των συνδέσμων (links), ως εξής :

<A HREF="newpage.php?name=<?php echo(urlencode($name));?>"> A link </A>

Έχουμε ενσωματώσει τον κώδικα της PHP στη μέση ενός tag της HTML. Αυτό είναι νόμιμο και δουλεύει κανονικά. Η συνάρτηση echo() είναι γνωστή, αλλά η συνάρτηση urlencode() είναι καινούργια και η δουλειά της είναι να λάβει σαν είσοδο κάποιους ειδικούς χαρακτήρες του string, όπως τα κενά για παράδειγμα, και να τους μετατρέψει σε ειδικούς κωδικούς για να μπορέσουν να εμφανισθούν στο query string.

Για παράδειγμα, αν η μεταβλητή $name έχει την τιμή "Kevin Yank", τότε εφόσον δεν επιτρέπονται τα κενά στο query string, η έξοδος της συνάρτησης urlencode() θα είναι "Kevin+Yank", το οποίο θα μετατραπεί πάλι πίσω στο κανονικό όταν θα δημιουργηθεί η μεταβλητή $name στο αρχείο newpage. php.

Μέχρι εδώ έχουμε κατορθώσει να μεταβιβάσουμε το όνομα του χρήστη σ’ όλους τους συνδέσμους (links) του site. Τώρα αυτό που πρέπει να κάνουμε είναι να ζητάμε πρώτα απ’ όλα αυτό το όνομα. Στο παράδειγμα με το μήνυμα καλωσορίσματος, είχαμε μια ειδική HTML σελίδα με μια φόρμα που προέτρεπε τον χρήστη να καταχωρήσει το όνομά του.

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

Η λύση είναι να κάνουμε έναν έλεγχο σε κάθε σελίδα του site για να διαπιστώσουμε αν έχει καταχωρηθεί ένα όνομα και να ζητάμε ένα όνομα από τον χρήστη αν χρειασθεί. Αυτό σημαίνει ότι όλες οι σελίδες του site είτε θα εμφανίζουν το περιεχόμενό τους ή μια προτροπή για να καταχωρηθεί ένα όνομα ανάλογα με το αν έχει μια τιμή η μεταβλητή $name.

Θα αναφερθούμε σε σελίδες που είναι ικανές να εμφανίσουν εντελώς διαφορετικό περιεχόμενο ανάλογα με κάποιες υπό συνθήκη σελίδες πολλαπλού σκοπού. Ο κώδικας για μια σελίδα πολλαπλού σκοπού (multi-purpose page) είναι ως εξής :

<HTML>

<HEAD>

            <TITLE> Σελίδα Πολλαπλο Σκοπού (Mύulti-Purpose Page) </TITLE>

</HEAD>

<BODY>

            <?php if (<συνθήκη>) { ?>

            <!-- HTML περιεχόμενο που θα εμφανισθεί αν η <συνθήκη> είναι αληθής (true) -->

<?php } else { ?>

            <!-- HTML περιεχόμενο που θα εμφανισθεί αν η <συνθήκη> είναι ψευδής (false) -->

<?php } ?>

</BODY>

</HTML>

Ο παραπάνω κώδικας μπορεί να μας μπερδεύει λίγο, αλλά πρόκειται για μια κανονική εντολή if-else με τμήματα HTML κώδικα, που θα εμφανισθούν ανάλογα με την τιμής μιας συνθήκης, αντί για εντολές της PHP. Αυτό το παράδειγμα δείχνει ένα από τα μεγάλα πλεονεκτήματα της PHP, δηλ. το ότι μπορούμε να βγούμε από και να μπούμε σε PHP mode οποτεδήποτε θέλουμε.

Μπορούμε να φανταστούμε το <?php σαν την εντολή για να μπούμε σε PHP mode και το ?> σαν την εντολή για να ξαναγυρίσουμε σε κανονικό HTML mode.

Υπάρχει μια εναλλακτική μορφή της εντολής if-else που μπορεί να κάνει τον κώδικα πιο ευανάγνωστο σε περιπτώσεις όπως η παραπάνω. Ακολουθεί ένα παράδειγμα :

<HTML>

<HEAD>

<TITLE> Σελίδα Πολλαπλο Σκοπού (Mύulti-Purpose Page) </TITLE>

</HEAD>

<BODY>

<?php if (<συνθήκη>): ?>

            <!-- HTML περιεχόμενο που θα εμφανισθεί αν η <συνθήκη> είναι αληθής (true) -->

<?php else: ?>

            <!-- HTML περιεχόμενο που θα εμφανισθεί αν η <συνθήκη> είναι ψευδής (true) -->

<?php endif; ?>

</BODY>

</HTML>

Ας δούμε τώρα μια δειγματική σελίδα (sample page) του site μας :

<HTML>

<HEAD>

<TITLE> Σελίδα - Δείγμα </TITLE>

</HEAD>

<BODY>

<?php if ( isset($name) ): ?>

            <P> Όνομα : <?php echo($name); ?></P>

            <P> Αυτή η παράγραφος περιέχει ένα

            <A HREF="newpage.php?name=<?php echo(urlencode($name)); ?>"> link </A>

                        που μεταβιβάζει τη μεταβλητή name στο επόμενο έγγραφο (document) </P>

<?php else: ?>

<!-- Δεν έχει δοθεί κάποιο όνομα και το ζητάμε από τον χρήστη -->

            <FORM ACTION=<?php echo($PHP_SELF); ?> METHOD=GET>

                        Δώστε το όνομά σας : <INPUT TYPE=TEXT NAME="name">

            <INPUT TYPE=SUBMIT VALUE="Submit">

            </FORM>

<?php endif; ?>

</BODY>

</HTML>

Υπάρχουν δύο καινούργια κόλπα στον παραπάνω κώδικα. Πρώτα απ’ όλα, χρησιμοποιούμε μια νέα συνάρτηση με όνομα isset() μέσα στη συνθήκη. Αυτή η συνάρτηση επιστρέφει την τιμή true αν στη μεταβλητή που της έχει δοθεί σαν όρισμα έχει εκχωρηθεί μια τιμή, δηλ. στη συγκεκριμένη περίπτωση αν έχει δοθεί ένα όνομα, και την τιμή false αν η μεταβλητή δεν υπάρχει, δηλ. στη συγκεκριμένη περίπτωση αν δεν έχει δοθεί ένα όνομα.

Το δεύτερο καινούργιο κόλπο είναι η χρήση της μεταβλητής $PHP_ SELF για να καθορίσουμε την ιδιότητα (attribute) ACTION του tag FORM. Αυτή η μεταβλητή είναι μια από τις πολλές στις οποίες δίνει πάντα αυτόματα τιμή η PHP.

Πιο συγκεκριμένα, η $PHP_SELF θα είναι πάντα ίση με το URL της τρέχουσας σελίδας. Αυτό μας δίνει τη δυνατότητα να δημιουργήσουμε μια φόρμα, η οποία όταν υποβληθεί θα φορτώσει την ίδια σελίδα, αλλά αυτή τη φορά με καθορισμένη τη μεταβλητή $name.

Δημιουργώντας όλες τις σελίδες του site μ’ αυτόν τον τρόπο, θα ζητηθεί από τους επισκέπτες να καταχωρήσουν το όνομά τους στην πρώτη σελίδα που θα επισκεφθούν, όποια κι αν είναι αυτή. Μόλις καταχωρήσουν το όνομα και κάνουν κλικ στο πλήκτρο υποβολής Submit, θα παρουσιαστούν με την ακριβή σελίδα που ζήτησαν. Το όνομα που καταχώρησαν θα μεταβιβασθεί μετά στο query string του κάθε συνδέσμου (link) από δω και πέρα.

 

Δημοσίευση Δεδομένων της MySQL στο Web

Θα δούμε τώρα πώς μπορούμε να πάρουμε τις πληροφορίες που είναι αποθηκευμένες σε μια βάση δεδομένων (database) και να τις εμφανίσουμε σε μια ιστοσελίδα (Web page) για να μπορεί να τις δει κάποιος. Μέχρι τώρα έχουμε μάθει τα βασικά για την MySQL, που είναι μια μηχανή σχεσιακών βάσεων δεδομένων (relational database engine) και την PHP, που είναι μια γλώσσα συγγραφής σεναρίων στην πλευρά του server (server-side scripting language).

Θα δούμε τώρα πώς μπορούμε να χρησιμοποιήσουμε αυτά τα εργαλεία μαζί για να δημιουργήσουμε ένα πραγματικό database-driven Web site. Έχουμε τα εξής δύο πανίσχυρα εργαλεία στη διάθεσή μας : τη γλώσσα συγγραφής σεναρίων (scripting language) PHP και τη μηχανή βάσεων δεδομένων (database engine) MySQL. Είναι σημαντικό να καταλάβουμε το πώς αυτά τα δύο εργαλεία θα μπορέσουν να συνεργαστούν μεταξύ τους.

Η όλη ιδέα πίσω από ένα database-driven Web site είναι να βρίσκεται (εμφανίζεται) το περιεχόμενο (content) του site σε μια βάση δεδομένων και απ’ αυτό το περιεχόμενο της βάσης δεδομένων να εξάγουμε δυναμικά πληροφορίες για να μπορέσουμε να δημιουργήσουμε ιστοσελίδες (Web pages) που να αλλάζουν δυναμικά χωρίς να κάνουμε συνέχεια αλλαγές σ’ αυτές και δημοσίευσή τους (publish).

Έτσι, στο ένα άκρο του συστήματος έχουμε έναν επισκέπτη (visitor) ή χρήστη (user) ή και πελάτη (client) στο site μας, ο οποίος χρησιμοποιεί έναν φυλλομετρητή (Web browser), φορτώνει το http://www.yoursite.com/ και περιμένει να δει μια συνηθισμένη ιστοσελίδα της HTML (HTML Web page). Στο άλλο άκρο έχουμε το περιεχόμενο (content) του site μας που βρίσκεται σ’ έναν ή περισσότερους πίνακες (tables) σε μια βάση δεδομένων της MySQL και το οποίο το μόνο που γνωρίζει είναι πώς να απαντάει σε ερωτήματα (queries) ή εντολές (commands) της SQL.

Η γλώσσα συγγραφής (scripting language) PHP είναι ο ενδιάμεσος που μιλάει και τις δύο γλώσσες. Χρησιμοποιώντας την PHP, μπορούμε να δημιουργήσουμε την παρουσίαση (όψη) του site, δηλ. τα ωραία γραφικά και τις διατάξεις σελίδας (page layouts) σαν υποδείγματα (templates) στην κανονική HTML. Χρησιμοποιούμε τον κώδικα της PHP για να συνδεθούμε στη βάση δεδομένων της MySQL και δημιουργούμε ερωτήματα (queries) της SQL για να μπορέσουμε να ανακτήσουμε και να εμφανίσουμε κάποιο περιεχόμενο της βάσης δεδομένων μέσα σε μια ιστοσελίδα.

Όταν κάποιος επισκεφθεί μια σελίδα σ’ ένα database-driven Web site θα συμβούν τα εξής :

 

Δημιουργία Σύνδεσης της MySQL με την PHP

Πριν μπορέσουμε να πάρουμε το περιεχόμενο μιας βάσης δεδομένων της MySQL για να το εισάγουμε σε μια ιστοσελίδα, πρέπει πρώτα να δούμε πώς θα καθιερώσουμε μια σύνδεση (connection) με την MySQL. Η κλήση στην ακόλουθη συνάρτηση της PHP δημιουργεί αυτή τη σύνδεση :

mysql_connect(<address>, <username>, <password>);

Όπου το <address> είναι η IP διεύθυνση ή το hostname του υπολογιστή στον οποίο εκτελείται το λογισμικό του MySQL server, που είναι το localhost αν εκτελείται στον ίδιο υπολογιστή με το λογισμικό του Web server, και τα <username> και <password> είναι τα ίδια με τα user name και password της MySQL που χρησιμοποιήσαμε για να συνδεθούμε στον MySQL server.

Η συνάρτηση mysql_connect() επιστρέφει έναν αριθμό για να μπορούμε να αναγνωρίσουμε (ξεχωρίσουμε) τη σύνδεση (connection). Μπορούμε να κρατήσουμε αυτή την τιμή σε μια μεταβλητή, ως εξής :

$dbcnx = mysql_connect("localhost", "root", "mypasswd");

Η τιμή που επιστρέφει η συνάρτηση mysql_connect(), που θα την αποκαλούμε connection identifier (αναγνωριστικό σύνδεσης), αποθηκεύεται σε μια μεταβλητή με όνομα $dbcnx.

Εφόσον ο MySQL server αποτελεί ένα εντελώς ξεχωριστό κομμάτι λογισμικού, πρέπει να δούμε και την πιθανότητα να μην είναι διαθέσιμος ο server ή να μην είναι προσβάσιμος εξαιτίας μιας βλάβης στο δίκτυο ή επειδή ο συνδυασμός username/password που δώσαμε δεν γίνεται αποδεκτός από τον server.

Σ’ αυτές τις περιπτώσεις, η συνάρτηση mysql_connect() δεν επιστρέφει έναν connection identifier εφόσον δεν γίνεται κάποια σύνδεση και αντί γι’ αυτόν επιστρέφει την τιμή false. Έχουμε έτσι τη δυνατότητα να αντιδράσουμε σε τέτοιες καταστάσεις χρησιμοποιώντας μια εντολή if, ως εξής :

$dbcnx = @mysql_connect("localhost", "root", "mypasswd");

if (!$dbcnx) {

echo("<P>Η σύνδεση με τον " ."database server είναι αδύνατη</P>");

exit();

}

Υπάρχουν τρία καινούργια κόλπα στον παραπάνω κώδικα. Πρώτα, έχουμε τοποθετήσει το σύμβολο @ μπροστά από τη συνάρτηση mysql_connect(). Πολλές συναρτήσεις, όπως και η mysql_connect(), εμφανίζουν αυτόματα άσχημα μηνύματα λάθους όταν κάτι πάει στραβά. Η τοποθέτηση του συμβόλου @ μπροστά από το όνομα της συνάρτησης μάς δίνει τη δυνατότητα να εμφανίσουμε το δικό μας μήνυμα λάθους, που θα είναι πιο φιλικό.

Δεύτερο, τοποθετήσαμε ένα θαυμαστικό ! μπροστά από τη μεταβλητή $dbcnx μέσα στη συνθήκη της εντολής if. Το ! είναι ο τελεστής άρνησης (negation operator) της PHP, ο οποίος στην ουσία μετατρέπει μια τιμή false σε true και μια τιμή true σε false. Έτσι, αν η σύνδεση αποτύχει και η συνάρτηση mysql_connect() επιστρέψει false, η μεταβλητή !$dbcnx θα γίνει ίση με true και θα εκτελεσθούν οι εντολές που βρίσκονται μέσα στο σώμα της εντολής if.

Αντίθετα, αν γίνει η σύνδεση, ο connection identifier που είναι αποθηκευμένος στη μεταβλητή $dbcnx θα γίνει ίσος με true, καθώς κάθε αριθμός που είναι διαφορετικός από το 0 θεωρείται ότι είναι true στην PHP, και έτσι η !$dbcnx θα αποτιμηθεί σε false και δεν εκτελεσθούν οι εντολές που βρίσκονται μέσα στο σώμα της συνάρτησης if.

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

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

mysql_select_db("jokes", $dbcnx);

Χρησιμοποιούμε τη μεταβλητή $dbcnx που περιέχει το αναγνωριστικό σύνδεσης της βάσης δεδομένων (database connection identifier) για να ενημερώσουμε τη συνάρτηση ποια σύνδεση βάσης δεδομένων να χρησιμοποιήσει. Αυτή είναι μια προαιρετική παράμετρος και όταν παραλείπεται, η συνάρτηση θα χρησιμοποιήσει αυτόματα το αναγνωριστικό σύνδεσης (link identifier) της τελευταίας σύνδεσης που έχει ανοιχθεί.

Αυτή η συνάρτηση επιστρέφει true όταν είναι επιτυχής και false αν συμβεί κάποιο λάθος. Και πάλι, είναι σωστή τακτική η χρήση μιας εντολής if για τον χειρισμό των λαθών :

if (! @mysql_select_db("jokes") ) {

echo( "<P>Αδύνατος ο εντοπισμός της " ."database joke</P>" );

exit();

}

Εφόσον έχουμε καθιερώσει μια σύνδεση (connection) και έχουμε επιλέξει μια βάση δεδομένων, είμαστε έτοιμοι να αρχίσουμε να χρησιμοποιούμε τα δεδομένα που βρίσκονται αποθηκευμένα στη βάση δεδομένων.

 

Εκτέλεση SQL Ερωτημάτων (Queries) με την PHP

Στα προηγούμενα, είδαμε πώς μπορούμε να συνδεθούμε σ’ έναν database server της MySQL με το πρόγραμμα mysql για να μπορέσουμε να γράψουμε ερωτήματα (queries) ή εντολές (commands) της SQL και να δούμε αμέσως τα αποτελέσματα των ερωτημάτων. Στην PHP υπάρχει ένας παρόμοιος μηχανισμός, η συνάρτηση mysql_query().

mysql_query(<query>, <connection id>);

Όπου το <query> είναι ένα string που περιέχει τις εντολές της SQL που θα εκτελεσθούν. Όπως και με τη συνάρτηση mysql_select_db(), η παράμετρος connection identifier (αναγνωριστικό σύνδεσης) είναι προαιρετική.

Η τιμή επιστροφής αυτής της συνάρτησης εξαρτάται από το είδος του ερωτήματος που στέλνεται. Για τις περισσότερες εντολές της SQL, η συνάρτηση mysql_query() επιστρέφει true ή false για να δείξει την επιτυχία ή την αποτυχία της αντίστοιχα.

Το επόμενο παράδειγμα προσπαθεί να δημιουργήσει τον γνωστό μας πίνακα Jokes :

$sql = "CREATE TABLE Jokes ( " .

    "ID INT NOT NULL AUTO_INCREMENT PRIMARY KEY, " .

    "JokeText TEXT, " .

    "JokeDate DATE NOT NULL " .

")";

if ( mysql_query($sql) ) {

            echo("<P> Ο πίνακας Jokes δημιουργήθηκε επιτυχώς </P>");

} else {

            echo("<P> Λάθος στη δημιουργία του πίνακα Jokes : " .

            mysql_error() . "</P>");

}

Η συνάρτηση mysql_error() επιστρέφει ένα string κειμένου που περιγράφει το τελευταίο μήνυμα λάθους (error message) που στάλθηκε από τον MySQL server.

Για τα ερωτήματα DELETE, INSERT και UPDATE, με τα οποία μπορούμε να τροποποιήσουμε τα αποθηκευμένα δεδομένα, η MySQL κατά-γράφει επίσης τον αριθμό των γραμμών του πίνακα (καταχωρήσεων) που επηρεάστηκαν από το ερώτημα (query).

Η επόμενη εντολή της SQL αλλάζει την ημερομηνία όλων των jokes που περιέχουν τη λέξη "chicken" :

$sql = "UPDATE Jokes SET JokeDate='1990-04-01' " .

"WHERE JokeText LIKE '%chicken%'";

Όταν εκτελεσθεί αυτό το ερώτημα, μπορούμε να χρησιμοποιήσουμε τη συνάρτηση mysql_affected_rows() για να δούμε τον αριθμό των γραμμών (rows) που επηρεάστηκαν απ’ αυτήν την ενημέρωση (update) :

if ( mysql_query($sql) ) {

echo("<P> Η ενημέρωση (update) επηρέασε " .

mysql_affected_rows() . " γραμμές (rows).</P>");

} else {

echo("<P> Λάθος κατά την ενημέρωση (update) : " .

mysql_error() . "</P>");

}

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

 

Χειρισμός των Αποτελεσμάτων της Εντολής SELECT

Για τα περισσότερα ερωτήματα της SQL, η συνάρτηση mysql_query() επιστρέφει είτε true για επιτυχία ή false για αποτυχία. Για τα ερωτήματα SELECT αυτό δεν είναι αρκετό. Και αυτό γιατί εκτός από την ένδειξη αν το ερώτημα πέτυχε ή απέτυχε, η PHP πρέπει επίσης να λάβει υπόψη και τα αποτελέσματα του ερωτήματος.

Έτσι, όταν επεξεργαζόμαστε ένα ερώτημα SELECT, η συνάρτηση mysql_query() επιστρέφει έναν αριθμό που δείχνει ένα σύνολο αποτελεσμάτων (result set), που περιέχει μια λίστα όλων των γραμμών (rows) ή καταχωρήσεων (entries) που επιστρέφονται από το ερώτημα.

$result = mysql_query("SELECT JokeText FROM Jokes");

if (!$result) {

echo("<P> Λάθος στην εκτέλεση του ερωτήματος (query) : " .

mysql_error() . "</P>");

exit();

}

Αν δεν συμβεί κάποιο λάθος στην επεξεργασία του ερωτήματος, ο παραπάνω κώδικας θα τοποθετήσει στη μεταβλητή $result ένα σύνολο αποτελεσμάτων (result set) που θα περιέχει το κείμενο όλων των jokes που είναι αποθηκευμένα στον πίνακα Jokes.

Για να επεξεργαστούμε τις γραμμές (rows) του συνόλου αυτού μία κάθε φορά, μπορούμε να χρησιμοποιήσουμε τον βρόχο while, ως εξής :

while ( $row = mysql_fetch_array($result) ) {

// επεξεργασία της γραμμής (row)

}

Θα μελετήσουμε την παρακάτω εντολή που περιέχει η συνθήκη :

$row = mysql_fetch_array($result);

Η συνάρτηση mysql_fetch_array() δέχεται ένα σύνολο αποτελεσμάτων (result set) σαν παράμετρο, που είναι αποθηκευμένο στη μεταβλητή $result στη συγκεκριμένη περίπτωση, και επιστρέφει την επόμενη γραμμή του result set σαν έναν πίνακα (array). Όταν δεν υπάρχουν άλλες γραμμές στο result set, η συνάρτηση mysql_fetch_array() επιστρέφει την τιμή false.

Η παραπάνω εντολή εκχωρεί μια τιμή στη μεταβλητή $row, αλλά ταυτόχρονα η ίδια η εντολή αποκτά την ίδια τιμή. Αυτός είναι ο λόγος που μπορούμε να χρησιμοποιήσουμε την εντολή για τη συνθήκη του βρόχου while.

Εφόσον οι βρόχοι while συνεχίζουν να εκτελούνται μέχρις ότου η συνθήκη τους γίνει ίση με false, ο βρόχος θα επαναληφθεί για όσο υπάρχουν γραμμές στο result set, με τη μεταβλητή $row να αποκτά κάθε φορά την τιμή της επόμενης γραμμής. Αυτό που έμεινε είναι να δούμε πώς μπορούμε κάθε φορά να παίρνουμε τις τιμές της μεταβλητής $row.

Οι γραμμές ενός result set παριστάνονται σαν πίνακες (arrays), οι θέσεις του οποίου ονομάζονται σύμφωνα με τις στήλες του πίνακα του result set. Έτσι, αν το $row είναι μια γραμμή στο result set, τότε το $row["Joke-Text"] είναι η τιμή της στήλης JokeText αυτής της γραμμής.

Αν θελήσουμε να εκτυπώσουμε το κείμενο όλων των jokes της βάσης δεδομένων, ο βρόχος while θα πρέπει να είναι ως εξής :

while ( $row = mysql_fetch_array($result) ) {

echo("<P>" . $row["JokeText"] . "</P>");

}

Για να συνοψίσουμε, ακολουθεί ο πλήρης κώδικας μιας PHP Web page που θα συνδεθεί με μια βάση δεδομένων, θα πάρει το κείμενο όλων των jokes της βάσης δεδομένων και θα τα εμφανίσει σε παραγράφους της HTML, ως εξής :

<HTML>

<HEAD>

<TITLE> Η Λίστα των Jokes </TITLE>

<HEAD>

<BODY>

<?php

// Σύνδεση με τον database server

$dbcnx = @mysql_connect("localhost", "root", "mypasswd");

if (!$dbcnx) {

echo( "<P> Αδύνατη η σύνδεση με τον " .

"database server αυτήν την ώρα. </P>" );

exit();

}

            // Επιλογή της βάσης δεδομένων jokes

            if (! @mysql_select_db("jokes") ) {

                        echo( "<P> Αδύνατος ο εντοπισμός της βάσης δεδομένων " .

                        "joke αυτήν την ώρα. </P>" );

                        exit();

            }

?>

            <P> Τα jokes της βάσης δεδομένων είναι τα εξής : </P>

            <BLOCKQUOTE>

<?php

            // Αναζήτηση του κειμένου όλων των jokes

            $result = mysql_query(

            "SELECT JokeText FROM Jokes");

            if (!$result) {

                        echo("<P> Λάθος στην εκτέλεση του ερωτήματος (query) : " .

                        mysql_error() . "</P>");

                        exit();

            }

            // Εμφάνιση του κειμένου του κάθε joke σε μια παράγραφο

            while ( $row = mysql_fetch_array($result) ) {

                        echo("<P>" . $row["JokeText"] . "</P>");

             }

?>

            </BLOCKQUOTE>

</BODY>

</HTML>

 

Εισαγωγή Δεδομένων στη Βάση Δεδομένων

Θα δούμε τώρα πώς μπορούμε να δώσουμε τη δυνατότητα στους επισκέπτες (χρήστες) του site μας να προσθέσουν τις δικές τους εγγραφές (γραμμές) στη βάση δεδομένων. Για να μπορέσει να γίνει κάτι τέτοιο, είναι απαραίτητη η χρήση μιας φόρμας (form), ως εξής :

<FORM ACTION="<?php echo($PHP_SELF); ?>" METHOD=POST>

<P> Γράψτε το joke εδώ : <BR>

<TEXTAREA NAME="joketext" ROWS=10 COLS=40 WRAP>

</TEXTAREA><BR>

<INPUT TYPE=SUBMIT NAME="submitjoke" VALUE="SUBMIT">

</FORM>

Όταν υποβληθεί αυτή η φόρμα, θα φορτώσει την ίδια ακριβώς σελίδα, λόγω της χρήσης της μεταβλητής $PHP_SELF στην ιδιότητα ACTION της φόρμας, αλλά με δύο μεταβλητές συνδεδεμένες με την αίτηση (request).

Η πρώτη, η $joketext, θα περιέχει το κείμενο του joke όπως καταχωρήθηκε στην περιοχή κειμένου (text area). Η δεύτερη, η $submitjoke, θα περιέχει πάντα την τιμή "SUBMIT", η οποία μπορεί να χρησιμοποιηθεί σαν μια ένδειξη ότι έχει υποβληθεί ένα joke. Για να καταχωρηθεί το υποβαλλόμενο joke στη βάση δεδομένων, πρέπει να χρησιμοποιήσουμε τη συνάρτηση mysql_query() για να εκτελέσουμε ένα ερώτημα INSERT, χρησιμοποιώντας τη μεταβλητή $joketext για την τιμή που θα υποβληθεί, ως εξής :

if ("SUBMIT" == $submitjoke) {

            $sql = "INSERT INTO Jokes SET " .

            "JokeText='$joketext', " .

            "JokeDate=CURDATE()";

            if (mysql_query($sql)) {

                        echo("<P> Το joke έχει προστεθεί. </P>");

            } else {

                        echo("<P> Λάθος κατά την προσθήκη του joke : " .

                        mysql_error() . "</P>");

            }

}

Χρησιμοποιήσαμε τη συνάρτηση CURDATE() της MySQL για να εκχωρήσουμε την τρέχουσα ημερομηνία στην τιμή της στήλης JokeDate. Έχουμε τώρα τον κώδικα που δίνει τη δυνατότητα σ’ έναν χρήστη να καταχωρήσει ένα joke και να το προσθέσει στη βάση δεδομένων. Θα πρέπει τώρα να τον ενσωματώσουμε στην ήδη υπάρχουσα σελίδα εμφάνισης των jokes. Ακολουθεί ο κώδικας.

<HTML>

...

<BODY>

<?php

// Αν ο χρήστης θελήσει να προσθέσει ένα joke

            if (isset($addjoke)):

?>

<FORM ACTION="<?php echo($PHP_SELF); ?>" METHOD=POST>

            <P> Γράψτε εδώ το joke : <BR>

            <TEXTAREA NAME="joketext" ROWS=10 COLS=40 WRAP>

            </TEXTAREA><BR>

            <INPUT TYPE=SUBMIT NAME="submitjoke" VALUE="SUBMIT">

</FORM>

<?php

            else:

            // Σύνδεση με τον database server

            $dbcnx = @mysql_connect("localhost", "root", "mypasswd");

            if (!$dbcnx) {

                        echo( "<P> Αδύνατη η σύνδεση με τον " .

                        "database server αυτή τη στιγμή. </P>" );

                        exit();

             }

            // Επιλογή της βάσης δεδομένων jokes

            if (! @mysql_select_db("jokes") ) {

                        echo( "<P> Αδύνατος ο εντοπισμός της βάσης δεδομένων " .

                        " joke αυτή τη στιγμή.</P>" );

                        exit();

            }

            // Αν έχει υποβληθεί ένα joke, το προσθέτουμε στη βάση δεδομένων

            if ("SUBMIT" == $submitjoke) {

                        $sql = "INSERT INTO Jokes SET " .

                        "JokeText='$joketext', " .

                        "JokeDate=CURDATE()";

                        if (mysql_query($sql)) {

                                    echo("<P>Το joke έχει προστεθεί. </P>");

                        } else {

                                    echo("<P> Λάθος στην προσθήκη του joke : " .

                                    mysql_error() . "</P>");

                        }

            }

echo("<P> Αυτά είναι όλα τα jokes " .

"που υπάρχουν στη βάση δεδομένων : </P>");

            // Επιλογή του κειμένου όλων των jokes

            $result = mysql_query(

            "SELECT JokeText FROM Jokes");

            if (!$result) {

                        echo("<P> Λάθος στην εκτέλεση του query : " .

                        mysql_error() . "</P>");

                        exit();

            }

            // Εμφάνιση του κειμένου του κάθε joke σε μια παράγραφο

            while ( $row = mysql_fetch_array($result) ) {

                        echo("<P>" . $row["JokeText"] . "</P>");

            }

            // Όταν γίνει κλικ, αυτός ο σύνδεσμος (link) θα φορτώσει αυτή τη

// σελίδα με εμφανισμένη τη φόρμα υποβολής joke

            echo("<P><A HREF='$PHP_SELF?addjoke=1'>" .

            "Πρόσθεσε ένα Joke!</A></P>");

            endif;

?>

</BODY>

</HTML>

 

Διαγραφή Δεδομένων από τη Βάση Δεδομένων

Θα δούμε τώρα πώς μπορούμε να τοποθετήσουμε ένα link με ετικέτα "Delete this Joke" δίπλα σε κάθε joke στη σελίδα, το οποίο όταν θα γίνεται κλικ, θα αφαιρεί αυτό το joke από τη βάση δεδομένων και θα εμφανίζει την ενημερωμένη λίστα των jokes.

            Ακολουθούν μερικές οδηγίες πριν δούμε τη λύση :

Οι ακόλουθες αλλαγές έπρεπε να γίνουν για να προσθέσουμε το link "Delete this Joke" δίπλα σε κάθε joke :

Ακολουθεί ο πλήρης κώδικας :

<HTML>

            ...
<BODY>

<?php

// Αν ο χρήστης θελήσει να προσθέσει ένα joke

if (isset($addjoke)):

?>

<FORM ACTION="<?php echo($PHP_SELF); ?>" METHOD=POST>

            <P> Γράψτε εδώ το joke : <BR>

            <TEXTAREA NAME="joketext" ROWS=10 COLS=40 WRAP>

            </TEXTAREA><BR>

            <INPUT TYPE=SUBMIT NAME="submitjoke" VALUE="SUBMIT">

</FORM>

<?php

            else:

            // Σύνδεση με τον database server

            $dbcnx = @mysql_connect("localhost", "root", "mypasswd");

            if (!$dbcnx) {

                        echo( "<P> Αδύνατη η σύνδεση με τον " .

                        "database server αυτή τη στιγμή. </P>" );

                        exit();

            }

            // Επιλογή της βάσης δεδομένων jokes

            if (! @mysql_select_db("jokes") ) {

                        echo( "<P> Αδύνατος ο εντοπισμός της βάσης δεδομένων " .

                        "joke αυτή τη στιγμή. </P>" );

                        exit();

             }

            // Αν έχει υποβληθεί ένα joke, το προσθέτουμε στη βάση δεδομένων

            if ("SUBMIT" == $submitjoke) {

                        $sql = "INSERT INTO Jokes SET " .

                        "JokeText='$joketext', " .

                        "JokeDate=CURDATE()";

                        if (mysql_query($sql)) {

                                    echo("<P> Το joke έχει προστεθεί. </P>");

                        } else {

                                    echo("<P> Λάθος στην προσθήκη του joke : " .

                                    mysql_error() . "</P>");

                        }

            }

            // Αν έχει διαγραφεί ένα joke, το αφαιρούμε από τη βάση δεδομένων

            if (isset($deletejoke)) {

                        $sql = "DELETE FROM Jokes " .

                        "WHERE ID=$deletejoke";

                        if (mysql_query($sql)) {

                                    echo("<P> Το joke έχει διαγραφεί. </P>");

                        } else {

                                    echo("<P> Λάθος στη διαγραφή του joke : " .

                                    mysql_error() . "</P>");

                        }

            }

            echo("<P> Ακολουθεί μια λίστα μ’ όλα τα jokes " .

            "της βάσης δεδομένων : </P>");

            // Αναζήτηση (request) του ID και του κειμένου όλων των jokes

            $result = mysql_query("SELECT ID, JokeText FROM Jokes");

            if (!$result) {

                        echo("<P> Λάθος στην εκτέλεση του query : " .

                        mysql_error() . "</P>");

                        exit();

            }

            // Εμφάνιση του κειμένου του κάθε joke σε μια παράγραφο

            // μ’ ένα link "Delete this Joke" δίπλα στο καθένα

            while ( $row = mysql_fetch_array($result) ) {

                        $jokeid = $row["ID"];

                        $joketext = $row["JokeText"];

                        echo("<P>$joketext " .

                        "<A HREF='$PHP_SELF?deletejoke=$jokeid'>" .

                        "Delete this Joke</A></P>");

            }

            // Όταν γίνει κλικ, αυτό το link θα φορτώσει αυτή τη σελίδα

            // με εμφανισμένη τη φόρμα υποβολής joke

            echo("<P><A HREF='$PHP_SELF?addjoke=1'>" .

            "Add a Joke!</A></P>");

endif;
?>

</BODY>

</HTML>

 

Σχεδίαση Σχεσιακών Βάσεων Δεδομένων

Ας ξαναδούμε τη δομή του πίνακα Jokes που έχουμε χρησιμοποιήσει μέχρι τώρα. Περιέχει τις εξής τρεις στήλες : ID, JokeText και JokeDate, με τις οποίες μπορούμε να αναγνωρίσουμε τα jokes (ID) και να παρακολουθούμε το κείμενό τους (JokeText) καθώς και την ημερομηνία καταχώρησής τους (JokeDate).

Ας υποθέσουμε τώρα ότι θέλουμε να έχουμε κι άλλη μια πληροφορία για τα jokes, όπως είναι τα ονόματα των ανθρώπων που τα καταχωρούν (υποβάλλουν). Φαίνεται φυσικό να θελήσουμε να προσθέσουμε μια καινούργια στήλη στον πίνακα Jokes προς τον σκοπό αυτόν, και αυτό θα το κάνουμε με τη βοήθεια της εντολής ALTER της SQL.

Συνδεόμαστε στον MySQL server με το πρόγραμμα mysql από τη γραμμή εντολών, επιλέγουμε τη βάση δεδομένων με την οποία θέλουμε να δουλέψουμε, προφανώς την jokes, και δίνουμε την εξής εντολή :

mysql> ALTER TABLE Jokes ADD COLUMN

            -> AuthorName VARCHAR(100);

Η παραπάνω εντολή προσθέτει μια στήλη με όνομα AuthorName στον πίνακα Jokes. Ο τύπος δεδομένων είναι ένα string μεταβλητού μήκους χαρακτήρων μέχρι 100 χαρακτήρες σε μήκος. Θα προσθέσουμε επίσης μια στήλη για την ηλεκτρονική διεύθυνση (e-mail) του συγγραφέα, ως εξής :

mysql> ALTER TABLE Jokes ADD COLUMN

-> AuthorEMail VARCHAR(100);

Χρησιμοποιώντας ερωτήματα με την εντολή UPDATE, θα μπορούμε τώρα να προσθέσουμε στοιχεία για τους συγγραφείς σ’ όλα τα jokes του πίνακα. Πριν, όμως, γίνει αυτό, πρέπει να σταματήσουμε και να δούμε αν πήραμε τη σωστή απόφαση. Στην περίπτωση αυτή, αποδεικνύεται ότι όχι.

Η προσθήκη του ονόματος και του e-mail του συγγραφέα σε κάθε joke σίγουρα έχει κάποιο νόημα, αλλά ο τρόπος που το κάναμε παραπάνω δημιουργεί πολλά προβλήματα :

mysql> SELECT DISTINCT AuthorName, AuthorEMail

-> FROM Jokes;

Η λέξη κλειδί DISTINCT στο παραπάνω query λέει στην MySQL να μην εμφανίσει τις διπλότυπες γραμμές. Για παράδειγμα, αν η Joan Smith υπέβαλλε 20 jokes στο site, το όνομα και η διεύθυνση του e-mail της θα εμφανισθούν 20 φορές στη λίστα αντί για μία μόνο αν δεν χρησιμοποιήσουμε την επιλογή DISTINCT.

·        Αν για κάποιο λόγο αποφασίσουμε να διαγράψουμε όλα τα jokes που έχει υποβάλλει στο site ένας συγκεκριμένος συγγραφέας, θα αφαιρε-θούν επίσης και όλα τα στοιχεία αυτού του ατόμου από τη βάση δεδομένων. Οι ειδήμονες στη σχεδίαση των βάσεων δεδομένων αναφέρονται σ’ αυτό το είδος προβλήματος σαν ανωμαλία διαγραφής (delete anomaly).

·        Δεν υπάρχει καμία εγγύηση ότι η Joan Smith δεν θα καταχωρήσει το όνομά της σαν Joan Smith την μια μέρα ή σαν J. Smith την επομένη και σαν Smith, Joan σε μια άλλη περίπτωση. Αυτό θα κάνει την παρακολούθηση ενός συγκεκριμένου συγγραφέα πάρα πολύ δύσκολη.

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

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

Μπορούμε μετά να χρησιμοποιήσουμε τα ID’s των συγγραφέων στον πίνακα Jokes για να συσχετίσουμε τους συγγραφείς με τα jokes που έχουν υποβάλλει. Η πλήρης διάταξη της βάσης δεδομένων (database layout) είναι ως εξής :

Jokes

ID JokeText JokeDate AID
1 Τι έκανε ο ... 2004-06-01 1
2 Κάποιος μια μέρα ... 2004-05-10 1
3 Μια φορά κι έναν ... 2003-12-10 2

 

Authors

ID Name Email
1 Nick Nikolaidis nick@something.com
2 John Papadopoulos john@greek.gr

Αυτό που δείχνουν οι δύο παραπάνω πίνακες είναι τρία jokes και δύο συγγραφείς (authors). Η στήλη AID (Author ID) του πίνακα Jokes παρέχει μια σχέση (relationship) ανάμεσα στους δύο πίνακες, που δείχνει ότι ο Nick Nikolaidis υπέβαλλε τα jokes 1 και 2 και o John Papadopoulos υπέβαλλε το joke 3.

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

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

Αυτός είναι ένας εμπειρικός κανόνας (rule of thumb) που πρέπει πάντα να έχουμε υπόψη μας όταν σχεδιάζουμε μια βάση δεδομένων : το κάθε είδος αντικειμένου ή οντότητας (entity) για το οποίο θέλουμε να αποθηκεύσουμε πληροφορίες, πρέπει να διαθέτει τον δικό του πίνακα.

Η δημιουργία της παραπάνω βάσης δεδομένων από το μηδέν είναι απλή υπόθεση : εκτελούμε δύο ερωτήματα CREATE TABLE, αλλά εφόσον θέλουμε να κάνουμε αυτές τις αλλαγές χωρίς να απωλέσουμε δεδομένα, θα πρέπει να χρησιμοποιήσουμε την εντολή ALTER. Πρώτα, θα διαγράψουμε από τον πίνακα Jokes τις στήλες που αναφέρονται στον συγγραφέα (author) :

mysql> ALTER TABLE Jokes DROP COLUMN AuthorName;

Query OK, 0 rows affected (0.00 sec)

Records: 0  Duplicates: 0  Warnings: 0

mysql> ALTER TABLE Jokes DROP COLUMN AuthorEMail;

Query OK, 0 rows affected (0.00 sec)

Records: 0  Duplicates: 0  Warnings: 0

Τώρα δημιουργούμε τον καινούργιο πίνακα :

mysql> CREATE TABLE Authors (

-> ID INT NOT NULL AUTO_INCREMENT PRIMARY KEY,

-> Name VARCHAR(100),

-> EMail VARCHAR(100)

-> );

Τέλος, προσθέτουμε τη στήλη AID στον πίνακα Jokes :

mysql> ALTER TABLE Jokes ADD COLUMN AID INT;

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

 

Χειρισμός Πολλών Πινάκων

Με τα δεδομένα μας να βρίσκονται τώρα σε δύο πίνακες, φαίνεται σαν να κάνουμε πιο περίπλοκη τη διαδικασία ανάκτησης αυτών των δεδομένων. Ας δούμε, για παράδειγμα, τον αρχικό μας στόχο : να εμφανίσουμε μια λίστα των jokes με το όνομα και τη διεύθυνση e-mail του συγγραφέα δίπλα σε κάθε joke. Στη λύση μ’ έναν πίνακα, θα μπορούμε να εμφανίσουμε όλα αυτά τα στοιχεία με μια μόνο εντολή SELECT μέσα στον κώδικα της PHP :

$jokelist = mysql_query(

"SELECT JokeText, AuthorName, AuthorEMail ".

"FROM Jokes");

while ($joke = mysql_fetch_array($jokelist)) {

$joketext = $joke["JokeText"];

$name = $joke["AuthorName"];

$email = $joke["AuthorEMail"];

// Εμφάνιση του joke με τα στοιχεία του συγγραφέα

echo( "<P>$joketext<BR>" .

"(by <A HREF='mailto:$email'>$name</A>)</P>" );

}

Στο νέο σύστημα, αυτό δεν φαίνεται δυνατό με μια πρώτη ματιά. Εφόσον οι λεπτομέρειες για τον συγγραφέα του κάθε joke δεν αποθηκεύονται στον πίνακα Jokes, μπορεί να σκεφθεί κανείς ότι πρέπει να πάρουμε αυτά τα στοιχεία ξεχωριστά για το κάθε joke που θέλουμε να εμφανίσουμε. Ο κώδικας για να γίνει αυτό είναι ο εξής :

// Εμφάνιση της λίστας των jokes

$jokelist = mysql_query(

"SELECT JokeText, AID FROM Jokes");

while ($joke = mysql_fetch_array($jokelist)) {

// Εμφάνιση του κειμένου και του ID του συγγραφέα για το joke

$joketext = $joke["JokeText"];

$aid = $joke["AID"];

// Εμφάνιση των στοιχείων του συγγραφέα για το joke

$authordetails = mysql_query(

"SELECT Name, Email FROM Authors WHERE ID=$aid");

$author = mysql_fetch_array($authordetails);

$name = $author["Name"];

$email = $author["EMail"];

// Εμφάνιση του joke με τα στοιχεία του συγγραφέα

echo( "<P>$joketext<BR>" .

"(by <A HREF='mailto:$email'>$name</A>)</P>" );

}

Αρκετά μπερδεμένο και περιέχει ένα ερώτημα (query) στη βάση δεδομένων για το κάθε joke που θέλουμε να εμφανίσουμε, κάτι που μπορεί να επιβραδύνει σημαντικά την εμφάνιση της σελίδας.

Ευτυχώς, οι σχεσιακές βάσεις δεδομένων (relational databases) είναι σχεδιασμένες για να κάνουν εύκολη την εργασία με δεδομένα που είναι αποθηκευμένα σε πολλούς πίνακες. Χρησιμοποιώντας μια νέα μορφή της εντολής SELECT, που αποκαλείται join (ένωση), μπορούμε να πάρουμε στοιχεία και από τους δύο πίνακες.

Με τα joins μπορούμε να αντιμετωπίσουμε τα συσχετισμένα δεδομένα που βρίσκονται σε πολλούς πίνακες σαν να ήταν αποθηκευμένα σ’ έναν μόνο πίνακα. Η σύνταξη ενός join είναι ως εξής :

mysql> SELECT <columns> FROM <tables>

-> WHERE <συνθήκη(ες) για τα δεδομένα>;

Στην περίπτωσή μας, οι στήλες που μας ενδιαφέρουν είναι η JokeText στον πίνακα Jokes και οι Name και Email στον πίνακα Authors. Η συνθήκη για να συσχετίζεται μια καταχώρηση του πίνακα Jokes με μια καταχώρηση του πίνακα Authors, είναι η τιμή της στήλης AID στον πίνακα Jokes να είναι ίση με την τιμή της στήλης ID στον πίνακα Authors.

Ακολουθεί ένα παράδειγμα ενός join. Τα δύο πρώτα ερωτήματα βρίσκονται για να μας δείξουν τι περιέχεται στους δύο πίνακες.

mysql> SELECT LEFT(JokeText,20), AID FROM Jokes;

+----------------------+------+
| LEFT(JokeText,20)    | AID  |

+----------------------+------+
|
Τι έκανε ο ...               |    1 |

| Κάποιος μια μέρα ...  |    1 |

| Μια φορά κι έναν ...   |    2 |

+----------------------+------+
3 rows in set (0.00 sec)

mysql> SELECT * FROM Authors;

+----+------------+---------------------+
| ID | Name       | EMail               |

+----+------------+---------------------+

|  1 | Nick Nikolaidis | nick@something.com |

|  2 | John Papadopoulos | john@greek.gr |

+----+------------+---------------------+

2 rows in set (0.00 sec)

 

mysql> SELECT LEFT(JokeText,15), Name, Email

-> FROM Jokes, Authors WHERE AID = Authors.ID;

+-------------------+------------+--------- -- -

| LEFT(JokeText,15) | Name       | Email

+-------------------+------------+--------- -- -

|  Τι έκανε ο ...            | Nick Nikolaidis| nick@something.com

| Κάποιος μια μέρα ... | Nick Nikolaidis| nick@something.com

| Μια φορά κι έναν ...  | John Papadopoulos | john@greek.gr |

+-------------------+------------+--------- -- -

3 rows in set (0.00 sec)

Τα αποτελέσματα του τρίτου SELECT, το οποίο είναι ένα join, ομαδοποιούν τις τιμές που είναι αποθηκευμένες στους δύο πίνακες σ’ έναν μόνο πίνακα αποτελεσμάτων, με τα συσχετισμένα δεδομένα να είναι σωστά ομαδοποιημένα. Ακόμη κι αν τα δεδομένα βρίσκονται αποθηκευμένα σε δύο πίνακες, μπορούμε να πάρουμε όλες τις πληροφορίες που χρειαζόμαστε για να παράγουμε τη λίστα με τα jokes στην ιστοσελίδα μ’ ένα μόνο ερώτημα βάσης δεδομένων.

Προσέχουμε στο ερώτημα ότι, εφόσον υπάρχουν στήλες με όνομα ID και στους δύο πίνακες, έπρεπε να προσδιορίσουμε το όνομα του πίνακα όταν αναφερόμαστε στη στήλη ID στον πίνακα Authors (Authors.ID). Αν δεν είχαμε καθορίσει το όνομα του πίνακα, η MySQL δεν θα ήξερε σε ποια στήλη ID αναφερόμασταν και θα έβγαζε το εξής λάθος :

mysql> SELECT LEFT(JokeText,20), Name, Email

-> FROM Jokes, Authors WHERE AID = ID;

ERROR 1052: Column: 'ID' in where clause is ambiguous

Τώρα που γνωρίζουμε πώς να φθάσουμε στα δεδομένα που είναι αποθηκευμένα στους δύο πίνακες, μπορούμε να ξαναγράψουμε τον κώδικα για τη λίστα με τα jokes, για να εκμεταλλευτούμε τα joins :

$jokelist = mysql_query(

            "SELECT JokeText, Name, EMail " .

            "FROM Jokes, Authors WHERE AID=Authors.ID");

while ($joke = mysql_fetch_array($jokelist)) {

            $joketext = $joke["JokeText"];

            $name = $joke["Name"];

            $email = $joke["EMail"];

            // Εμφάνιση του joke με τα στοιχεία του συγγραφέα

            echo( "<P>$joketext<BR>" .

            "(by <A HREF='mailto:$email'>$name</A>)</P>" );

}

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

Ας δούμε, για παράδειγμα, το παρακάτω ερώτημα, το οποίο εμφανίζει μια λίστα όλων των jokes που έχουν γραφεί από την Joan Smith :

mysql> SELECT JokeText FROM Jokes, Authors WHERE

-> Name="Joan Smith" AND AID=Authors.ID;

Τα αποτελέσματα που δημιουργούνται από το παραπάνω ερώτημα προέρχονται μόνο από τον πίνακα Jokes, αλλά χρησιμοποιούμε ένα join για να μπορούμε να αναζητήσουμε jokes που βασίζονται σε μια τιμή που είναι αποθηκευμένη στον πίνακα Authors.

 

Απλές Σχέσεις Δεδομένων (Ένα-Προς-Ένα και Ένα-Προς-Πολλά)

Το καλύτερο είδος διάταξης βάσης δεδομένων (database layout) για μια δεδομένη κατάσταση καθορίζεται συνήθως από τον τύπο της σχέσης που υπάρχει ανάμεσα στα δεδομένα με τα οποία δουλεύουμε. Θα δούμε τους συνηθέστερους τύπους σχέσεων και πώς μπορούμε να τους παραστήσουμε σε μια σχεσιακή βάση δεδομένων (relational database).

Στην περίπτωση μιας απλής ένα-προς-ένα σχέσης, αυτό που χρειάζεται είναι ένας μόνον πίνακας. Ένα παράδειγμα μιας σχέσης ένα-προς-ένα είναι η e-mail διεύθυνση του κάθε συγγραφέα στη βάση δεδομένων joke. Εφόσον υπάρχει μια διεύθυνση e-mail για τον κάθε συγγραφέα και ένας συγγραφέας για την κάθε e-mail διεύθυνση, δεν υπάρχει κανένας λόγος να καταχωρήσουμε τις διευθύνσεις σ’ έναν ξεχωριστό πίνακα.

Μια σχέση ένα-προς-πολλά είναι λίγο περισσότερο πολύπλοκη, αλλά έχουμε ήδη συναντήσει μια τέτοια περίπτωση. Το κάθε joke στη βάση δεδομένων συσχετίζεται μ’ έναν μόνον συγγραφέα, αλλά πολλά jokes μπορεί να έχουν γραφεί από τον ίδιο συγγραφέα. Αυτή η σχέση joke-συγγραφέα είναι ένα-προς-πολλά (many-to-one).

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

Χωρίζοντας τα δεδομένα σε δύο πίνακες και χρησιμοποιώντας μια στήλη ID για να τα συνδέσουμε, αντιμετωπίζονται όλα τα παραπάνω προβλήματα. Στην περίπτωση που μερικοί συγγραφείς διαθέτουν περισσότερα από ένα e-mail, μπορούμε να δημιουργήσουμε έναν πίνακα EMails και να τον συσχετίσουμε με τον πίνακα Authors με τη στήλη ID.

Authors

ID Name
1 Nick Nikolaidis
2 John Ioannidis

 

EMails

ID EMail AID
1 nick100@florina.gr 1
2 nick@in.gr 1
3 john200@florina.gr 2
4 johngr@in.gr 2

Χρησιμοποιώντας ένα join, μπορούμε εύκολα να εμφανίσουμε τις διευθύνσεις e-mail που ανήκουν σ’ έναν συγκεκριμένο συγγραφέα :

mysql> SELECT EMail FROM Authors, EMails WHERE

          -> Name="Nick Nikolaidis" AND AID=Authors.ID;

+---------------------+

| EMail               |

+---------------------+

| nick100@florina.gr |

| nick@in.gr |

+---------------------+

2 rows in set (0.00 sec)

 

Σχέσεις Πολλά-προς-Πολλά

Αν αποφασίσουμε να χωρίσουμε τα jokes σε κατηγορίες, θα πρέπει να δημιουργήσουμε έναν ξεχωριστό πίνακα, ως εξής :

mysql> CREATE TABLE Categories (

-> ID INT NOT NULL AUTO_INCREMENT PRIMARY KEY,

-> Name VARCHAR(100),

-> Description TEXT

-> );

Query OK, 0 rows affected (0.00 sec)

Θα πρέπει τώρα να εκχωρήσουμε κατηγορίες στα jokes, αλλά ένα joke μπορεί να ανήκει σε πολλές κατηγορίες και η κάθε κατηγορία θα περιέχει πολλά jokes. Αυτή είναι μια σχέση πολλά-προς-πολλά (many-to-many relationship).

Για να μπορέσουμε να παραστήσουμε μια σχέση πολλά-προς-πολλά, θα πρέπει να χρησιμοποιήσουμε έναν τρίτο πίνακα αναζήτησης (lookup table), ο οποίος  δεν θα περιέχει πραγματικά δεδομένα αλλά απλά θα διασυνδέει τους δύο πίνακες των Jokes και των κατηγοριών.

Jokes

 

JokeLookup

 

Categories

ID JokeText   JID CID   ID Name
1 Τι έγινε ...   1 2   1 Πολιτικά
2 Ποιος είναι ...   2 4   2 Παιδικά
3 Μια φορά κι έναν...   2 5   3 Οικογενειακά
4 Πώς λέγεται ...   3 1   4 Τοπικά
      4 3   5 Διάφορα

 

Ο πίνακας JokeLookup συσχετίζει τα ID's των jokes  (JID) με τα ID's της κατηγορίας (CID). Για παράδειγμα, βλέπουμε ότι το joke με ID 2 ανήκει σε δύο κατηγορίες, τις 4 και 5, που είναι οι "Τοπικά" και "Διάφορα" αντίστοιχα.

Η δημιουργία ενός πίνακα αναζήτησης (lookup table) γίνεται όπως και η δημιουργία ενός οποιοδήποτε άλλου πίνακα. Η διαφορά βρίσκεται στην επιλογή του πρωτεύοντος κλειδιού (primary key). Ο κάθε πίνακας που έχουμε δημιουργήσει μέχρι τώρα είχε μια στήλη με όνομα ID χαρακτηρισμένη σαν PRIMARY KEY κατά τη δημιουργία του πίνακα.

Ο χαρακτηρισμός μιας στήλης σαν primary key (πρωτεύον κλειδί) λέει στην MySQL να μην επιτρέψει σε δύο καταχωρήσεις να έχουν την ίδια τιμή σ’ αυτή τη στήλη. Επίσης, επιταχύνει τις λειτουργίες join που βασίζονται σ’ αυτή τη στήλη.

Στην περίπτωση ενός πίνακα αναζήτησης (lookup table), δεν υπάρχει κάποια στήλη που να έχει μοναδικές τιμές. Το κάθε joke ID μπορεί να εμφανισθεί περισσότερες από μία φορές εφόσον ένα joke μπορεί να ανήκει σε περισσότερες από μία κατηγορίες και το ID μιας κατηγορίας μπορεί να εμφανισθεί περισσότερες από μία φορές εφόσον μια κατηγορία μπορεί να περιέχει πολλά jokes.

Εκείνο που δεν θέλουμε να επιτρέψουμε είναι να υπάρχει το ίδιο ζευγάρι τιμών δύο φορές μέσα στον πίνακα. Συνήθως δημιουργούμε πίνακες αναζήτησης (lookup tables) μ’ ένα πεδίο κλειδί πολλαπλών στηλών, ως εξής :

mysql> CREATE TABLE JokeLookup (

-> JID INT NOT NULL,

-> CID INT NOT NULL,

-> PRIMARY KEY(JID, CID)

-> );

Η παραπάνω εντολή δημιουργεί τον πίνακα με τις στήλες JID και CID να αποτελούν μαζί το πεδίο κλειδί (primary key). Αυτό επιβάλλει τη μοναδικότητα που πρέπει να υπάρχει σ’ έναν πίνακα αναζήτησης, εμποδίζοντας ένα joke από το να εκχωρηθεί στην ίδια κατηγορία περισσότερες από μία φορές.

Εφόσον έχουμε δημιουργήσει τον πίνακα αναζήτησης και έχουμε κάνει κάποιες καταχωρήσεις, μπορούμε να χρησιμοποιήσουμε τα joins για να δημιουργήσουμε μερικά ενδιαφέροντα ερωτήματα. Το επόμενο query εμφανίζει όλα τα jokes της κατηγορίας "Παιδικά" :

mysql> SELECT JokeText

-> FROM Jokes, Categories, JokeLookup

-> WHERE Name="Παιδικά" AND

-> CID=Categories.ID AND JID=Jokes.ID;

Το επόμενο query εμφανίζει τις κατηγορίες στις οποίες ανήκουν τα jokes που αρχίζουν με το κείμενο "Τι έγινε ..." :

mysql> SELECT Categories.Name

-> FROM Jokes, Categories, JokeLookup

-> WHERE JokeText LIKE "Τι έγινε%"

-> AND CID=Categories.ID AND JID=Jokes.ID;

Το επόμενο query, το οποίο επίσης χρησιμοποιεί τον πίνακα Authors για να δημιουργήσει ένα join από τέσσερις πίνακες, εμφανίζει τα ονόματα όλων των συγγραφέων που έχουν γράψει Παιδικά jokes :

mysql> SELECT Authors.Name

-> FROM Jokes, Authors, Categories, JokeLookup

-> WHERE Categories.Name="Παιδικά"

-> AND CID=Categories.ID AND JID=Jokes.ID

-> AND AID=Authors.ID;

 

back.gif (9867 bytes)

Επιστροφή