Project

General

Profile

Actions

Database » History » Revision 6

« Previous | Revision 6/16 (diff) | Next »
Panayotis Katsaloulis, 06/01/2014 21:37


Σύνδεση με τη βάση δεδομένων μέσω του αντικειμένου Database

Η σύνδεση με τη βάση δεδομένων από την έκδοση του Open eClass 3 και μετά γίνεται με τη χρήση του αντικειμένου Database που ορίζεται στο modules/db/database.php. Στη κανονική χρήση των βιβλιοθηκών το αντικείμενο αυτό παρέχεται στο χρήστη μέσω της init.php, οπότε δε χρειάζεται κάποιο require ή include για να χρησιμοποιηθεί, απλά να χρησιμοποιηθούν οι μέθοδοί του.

Η πρόσβαση στο αντικείμενο αυτό γίνεται κυρίως με τη static μέθοδο get(). Αν είναι δυνατή η κατασκευή ενός τέτοιου αντικειμένου, δεν είναι προτιμόμενη μέθοδος, γιατί μέσω της get() υπάρχουν ορισμένες βελτιστοποιήσεις κατά τη σύνδεση με τη βάση. Σε περίπτωση που θέλουμε να συνδεθούμε στη προκαθορισμένη βάση δεδομένων του eClass τότε η πρόσβαση γίνεται ως εξής:

  Database::get();

Αν θέλουμε να συνδεθούμε σε κάποια άλλη βάση, π.χ. σε ένα μάθημα, τότε δίνουμε στη μέθοδο get() μία παράμετρο. Παράδειγμα, για να συνδεθούμε στη βάση TM001 τότε η σωστή σύνταξη είναι η εξής:

  Database::get("TM001");

Οι μέθοδοι που υποστηρίζονται είναι οι εξής:

Database::get()->query($statement);
Database::get()->querySingle($statement);
Database::get()->queryArray($statement);
Database::get()->queryFunc($statement, $callback_function);

Σε κάθε μία μέθοδο, η πρώτη παράμετρος είναι το επερώτημα SQL που μας ενδιαφέρει να εκτελέσουμε, ακολουθούμενο από μία λίστα με παραμέτρους που θα γίνει εισαγωγή στο επερώτημα. Είναι λάθος πρακτική σε περίπτωση που θέλουμε να εισάγουμε κάποια παράμετρος στο επερώτημα να τη δώσουμε λεκτικά στο επερώτημα αυτό καθ'εαυτό, από το να το δώσουμε σαν επιπρόσθετη παράμετρος. Για να σημειώσουμε στο ίδιο το επερώτημα σε ποιο σημείο είναι η κάθε παράμετρος, χρησιμοποιούμε το σύμβολο «?».

Για παράδειγμα, αν θέλουμε να εκτελέσουμε το επόμενο επερώτημα SQL

DELETE FROM course_review WHERE course_id = 1;
o σωστός τρόπος να συντάξουμε τις παραμέτρους είναι ο εξής:
Database::get()->query("DELETE FROM course_review WHERE course_id = ?", 1);

Είναι σημαντικός ο τύπος των παραμέτρων που δίνουμε. Αν αναμένουμε π.χ. πως η παράμετρος είναι ακέραιος, είναι προτιμότερο να δίνεται ως int_value($param) αντί για σκέτο $param

Πριν τη λίστα με τις παραμέτρους που θα εισαγχθούν στο επερώτημα, είναι δυνατόν να παρέχουμε ως παράμετρο μια συνάρτηση επανάκλησης (callback function) ώστε να ενημερωθούμε αν κάτι δε πάει καλά. Υποχρεωτικά αυτή η συνάρτηση θα πρέπει να είναι δεύτερη παράμετρος (ή ειδικά για την queryFunc να είναι τρίτη παράμετρος), αλλιώς θα αγνοηθεί από το σύστημα. Αν η δεύτερη (ή αντίστοιχα τρίτη) παράμετρος δεν είναι συνάρτηση, τότε η δυνατότητα επανάκλησης δε θα ενεργοποιηθεί καθόλου. Ένα παράδειγμα της χρήσης αυτής της μεδόδου δίνεται στη μέθοδο query($statement) και queryFunc($statement, $callback_function)

Μέθοδος query($statement);

Με τη μέθοδο αυτή εκτελούμε ένα απλό επερώτημα. Η επιστρεφόμενη τιμή αυτής της συνάρτησης είναι το last insert id, σε περίπτωση που το query είναι τύπου "insert". Σε κάθε άλλη περίπτωση η επιστρεφόμενη τιμή μπορεί να μην έχει νόημα (και να είναι 0). Παράδειγμα χρήσης:

$cid = 1;
Database::get()->query("DELETE FROM course_review WHERE course_id = ?", $cid);

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

$cid = 1;
Database::get()->query("DELETE FROM course_review WHERE course_id = ?", function ($errormsg) {
        echo "An error has occured: " . $errormsg;
    },  $cid);

Μέθοδος querySingle($statement);

Με τη μέθοδο αυτή εκτελούμε ένα επερώτημα από το οποίο περιμένουμε να λάβουμε ως αποτέλεσμα ένα μοναδικό στοιχείο, ή με άλλα λόγια μία και μόνο μία γραμμή. Ο αριθμός των στηλών του αποτελέσματος δεν έχει σημασία. Η σύνταξη είναι ίδια με αυτή της μεθόδου query($statement);

Ως αποτέλεσμα λαμβάνουμε ένα αντικείμενο όπου κάθε ιδότητά του (property) έχει τιμή ίδια με το όνομα της στήλης σε περιβάλλον SQL. Για το λόγο αυτό είναι προτιμότερο κάθε στήλη να έχει ένα μοναδικό όνομα, ώστε να είναι μετά άμεση η προσπέλαση σε αυτό. Αν δεν υπάρχουν αποτελέσματα επιστρέφεται το null, οπότε είναι θεμιτό να γίνεται έλεγχος για null σε περίπτωση που ξέρουμε πως μπορεί να μην υπάρχουν αποτελέσματα. Για παράδειγμα

$stat_object = Database::get()->querySingle("SELECT status FROM course_user WHERE user_id = ? AND course_id = ?", $uid, $course_id);
if ($stat_object) {
  $status = $stat_object->status;
}

Ένα άλλο παράδειγμα:
$openCoursesNum = Database::get()->querySingle("SELECT COUNT(id) as count FROM course_review WHERE is_certified = 1")->count;

Μέθοδος queryArray($statement);

Αυτή η μέθοδος εκτελείται όταν περιμένουμε από το επερώτημα να επιστρέψει περισσότερο από ένα στοιχείο (ή γραμμή) και θέλουμε να πάρουμε αμέσως όλα τα αντικείμενα σε έναν πίνακα. Η μέθοδος αυτή μπορεί να χρησιμοποιηθεί σε περίπτωση που περιμένουμε τα αποτελέσματα να είναι λίγα στον αριθμό. Σε περίπτωση που είναι αρκετά, είναι προτιμότερη η χρήση της μεθόδου queryFunc.

Η σύνταξη της μεθόδου είναι αντίστοιχη ομοίως της query($statement);

Η επιστρεφόμενη τιμή είναι ένας πίνακας με αντικείμενα, όπου τα αντικείμενα είναι αντίστοιχα με της μεθόδου querySingle($statement);

Παράδειγμα χρήσης της μεθόδου

$moduleIDs = Database::get()->queryArray("SELECT module_id FROM course_module WHERE visible = 1 AND course_id = ?", $course_id);
foreach ($moduleIDs as $module) {
  $publicModules[] = $module->module_id;
}

Μέθοδος queryFunc($statement, $callback_function);

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

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

Επειδή η ορατότητα των εξωτερικών μεταβλητών μέσα στη συνάρτηση είναι περιορισμένη, μπορούμε να χρησιμοποιήσουμε το λεκτικό use($param1, &$param2 ...), ώστε να ενημερώσουμε την PHP πως ενδιαφερόμαστε να χρησιμοποιήσουμε τις μεταβλητές $param1 και $param2 εσωτερικά στη συνάρτησή μας. Ειδικά για τη παράμετρο $param2, με τη χρήση του συμβόλου & υποδηλώνουμε πως η γίνεται «καθ'αναφορά» η δήλωση της μεταβλητής, δηλαδή οποιαδήποτε αλλαγή που θα γίνει εσωτερικά, θα αλλάζει συνολικά την τιμή της μεταβλητής αυτής.

Ένα απλό παράδειγμα της μεθόδου αυτής είναι το εξής:

DataBase::get()->queryFunc("SELECT title  FROM course_units WHERE course_id = ?", function($unit) {
    echo "title: " . $unit->title;
  }, intval($courseId));

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

$counter = 0;
Database::get()->queryFunc("SELECT course.id as cid, course.code as code, FROM course WHERE course.id = ?" , function ($course_info) use ($outer_variable, &$counter, &$title) {
    $counter++;
    echo "For item #" . $counter . " with outer variable " . $outer_variable . " the course id is . " $course_info->id . " while the course code is " . $course_info->code;
  } , function ($errormsg) use($urlServer) {
    echo "Error " . $errormsg . " while connected on " . $urlServer;
    exit();
  } , $dbname);

Updated by Panayotis Katsaloulis about 10 years ago · 6 revisions