μεθόδους pdo. Γιατί πρέπει να χρησιμοποιείτε ΠΟΠ για πρόσβαση σε βάσεις δεδομένων; Επεξεργασία αποτελεσμάτων, μέθοδοι FETCH και FETCHALL

Ορος Π.Ο.Πείναι συντομογραφία της έννοιας Αντικείμενα δεδομένων PHP. Όπως υποδηλώνει το όνομα, αυτή η τεχνολογία σάς επιτρέπει να εργάζεστε με τα περιεχόμενα της βάσης δεδομένων μέσω αντικειμένων.

Γιατί όχι myqli ή mysql;

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

Αντικειμενικός Προσανατολισμός ΠΟΠ

PHPΑναπτύσσεται πολύ ενεργά και προσπαθεί να γίνει ένα από τα καλύτερα εργαλεία για την ταχεία ανάπτυξη διαδικτυακών εφαρμογών, τόσο σε μαζικό όσο και σε εταιρικό επίπεδο.

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

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

Αφαίρεση

Ας φανταστούμε ότι αναπτύσσουμε μια εφαρμογή εδώ και πολύ καιρό χρησιμοποιώντας MySQL. Και τότε, σε μια ωραία στιγμή, καθίσταται απαραίτητο να αντικατασταθεί MySQLεπί PostgreSQL.

Τουλάχιστον, θα πρέπει να αντικαταστήσουμε όλες τις κλήσεις mysqli_connect() (mysql_connect())επί pg_connect()και, κατ' αναλογία, άλλες συναρτήσεις που χρησιμοποιούνται για την αναζήτηση και την επεξεργασία δεδομένων.

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

Δέσμευση παραμέτρων

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

Λήψη δεδομένων ως αντικείμενα

Αυτοί που ήδη χρησιμοποιούν ORM(αντικειμενική-σχεσιακή αντιστοίχιση - αντικειμενική-σχεσιακή αντιστοίχιση δεδομένων), για παράδειγμα, Δόγμα, γνωρίζουν την ευκολία της αναπαράστασης δεδομένων από πίνακες βάσεων δεδομένων με τη μορφή αντικειμένων. Π.Ο.Πσας επιτρέπει να λαμβάνετε δεδομένα με τη μορφή αντικειμένων και χωρίς χρήση ORM.

Η επέκταση mysql δεν υποστηρίζεται πλέον

Υποστήριξη επέκτασης mysqlαφαιρέθηκε οριστικά από το νέο PHP 7. Εάν σκοπεύετε να μετεγκαταστήσετε το έργο σε μια νέα έκδοση PHP, θα πρέπει να χρησιμοποιήσετε τουλάχιστον το mysqli σε αυτό τώρα. Φυσικά, είναι καλύτερα να αρχίσετε να χρησιμοποιείτε Π.Ο.Παν δεν το έχετε κάνει ήδη.

Μου φαίνεται ότι αυτοί οι λόγοι είναι επαρκείς για να ανατρέψουν τη ζυγαριά υπέρ της χρήσης Π.Ο.Π. Επιπλέον, δεν χρειάζεται να εγκαταστήσετε τίποτα επιπλέον.

Έλεγχος παρουσίας ΠΟΠ στο σύστημα

εκδόσεις PHP 5.5και υψηλότερα, τις περισσότερες φορές, περιέχουν ήδη μια επέκταση για εργασία Π.Ο.Π. Για έλεγχο, απλώς εκτελέστε μια απλή εντολή στην κονσόλα:

php -i | grep "pdo"

Τώρα ας το ανοίξουμε σε οποιοδήποτε πρόγραμμα περιήγησης και ας βρούμε τα απαραίτητα δεδομένα κάνοντας αναζήτηση ανά γραμμή Π.Ο.Π.

Γνωριμία με Π.Ο.Π

Διαδικασία εργασίας με Π.Ο.Πόχι πολύ διαφορετικό από το παραδοσιακό. Γενικά η διαδικασία χρήσης Π.Ο.Πμοιάζει με αυτό:

  1. Συνδεθείτε στη βάση δεδομένων.
  2. Εάν είναι απαραίτητο, προετοιμάστε ένα αίτημα και παραμέτρους σύνδεσης.
  3. Εκτέλεση του αιτήματος.

Σύνδεση στη βάση δεδομένων

Για να συνδεθείτε στη βάση δεδομένων πρέπει να δημιουργήσετε ένα νέο αντικείμενο Π.Ο.Πκαι περάστε το το όνομα της πηγής δεδομένων, επίσης γνωστή ως DSN.

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

Για MySQL, η σύνδεση γίνεται ως εξής:

$connection = new PDO("mysql:host=localhost;dbname=mydb;charset=utf8", "root", "root");

$σύνδεση = νέο ΠΟΠ ( "mysql:host=localhost;dbname=mydb;charset=utf8", "root" , "root" );

Σε αυτήν την περίπτωση, DSNπεριέχει το όνομα του προγράμματος οδήγησης mysql, ένδειξη κεντρικού υπολογιστή (πιθανή μορφή host=HOST_NAME:PORT), όνομα βάσης δεδομένων, κωδικοποίηση, όνομα χρήστη MySQLκαι τον κωδικό του.

Αιτήσεων

Διαφορετικός mysqli_query(), V Π.Ο.Πυπάρχουν δύο είδη αιτημάτων:

  • Επιστρέφοντας το αποτέλεσμα ( επιλογή, εμφάνιση);
  • Δεν επιστρέφει αποτέλεσμα ( εισάγετε, λεπτομέρειακαι άλλοι).

Πρώτα απ 'όλα, ας εξετάσουμε τη δεύτερη επιλογή.

Εκτέλεση ερωτημάτων

Ας δούμε ένα παράδειγμα εκτέλεσης ενός αιτήματος χρησιμοποιώντας το παράδειγμα εισάγετε.

$connection->exec("INSERT INTO users VALUES (1, "somevalue"");

$connection -> exec () ;

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

$affectedRows = $connection->exec("INSERT INTO users VALUES (1, "somevalue""); echo $affectedRows;

$affectedRows = $connection -> exec ( "INSERT INTO users VALUES (1, "somevalue"") ;

echo $affectedRows ;

Λήψη αποτελεσμάτων ερωτήματος

Σε περίπτωση χρήσης mysqli_query(), ο κωδικός θα μπορούσε να είναι ο εξής.

$result = mysql_query("SELECT * FROM users"); while($row = mysql_fetch_assoc($result)) ( echo $row["id"] . " " . $row["name"];)

$result = mysql_query ("SELECT * FROM users" );

ενώ ($row = mysql_fetch_assoc ($result) ) (

Για Π.Ο.Π, ο κώδικας θα είναι απλούστερος και πιο συνοπτικός.

foreach($connection->query("SELECT * FROM users") ως $row) ( echo $row["id"] . " " . $row["name"]; )

foreach ($connection -> ερώτημα ("SELECT * FROM users") ως $row ) (

echo $row [ "id" ] . " " . $row["name"];

Τρόποι απόκτησης δεδομένων

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

  • ΠΟΠ::FETCH_ASSOC— επιστρέφει έναν πίνακα με ευρετήριο με το όνομα της στήλης στον πίνακα της βάσης δεδομένων.
  • ΠΟΠ::FETCH_NUM— επιστρέφει έναν πίνακα με ευρετήριο με αριθμό στήλης.
  • ΠΟΠ::FETCH_OBJ- επιστρέφει ένα ανώνυμο αντικείμενο με ονόματα ιδιοτήτων που αντιστοιχούν στα ονόματα των στηλών. Για παράδειγμα, το $row->id θα περιέχει την τιμή από τη στήλη id.
  • ΠΟΠ::FETCH_CLASS— επιστρέφει μια νέα παρουσία της κλάσης, με τιμές ιδιοτήτων που αντιστοιχούν στα δεδομένα από τη γραμμή του πίνακα. Εάν η παράμετρος έχει καθοριστεί ΠΟΠ::FETCH_CLASSTYPE(Για παράδειγμα ΠΟΠ::FETCH_CLASS | ΠΟΠ::FETCH_CLASSTYPE), το όνομα της κλάσης θα καθοριστεί από την τιμή της πρώτης στήλης.

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

Ένα παράδειγμα απόκτησης ενός συσχετιστικού πίνακα:

$statement = $connection->query("SELECT * FROM users"); while($row = $statement->fetch(PDO::FETCH_ASSOC)) ( echo $row["id"] . " " . $row["name"]; )

$statement = $connection ->

ενώ ($row = $statement -> fetch (PDO::FETCH_ASSOC) ) (

echo $row [ "id" ] . " " . $row["name"];

Σημείωση: Συνιστάται να καθορίζετε πάντα τη λειτουργία δειγματοληψίας επειδή η λειτουργία ΠΟΠ::FETCH_BOTHθα απαιτήσει διπλάσια μνήμη - στην πραγματικότητα, θα δημιουργηθούν δύο πίνακες, συνειρμικοί και κανονικοί.

Σκεφτείτε να χρησιμοποιήσετε τη λειτουργία δειγματοληψίας ΠΟΠ::FETCH_CLASS. Ας δημιουργήσουμε μια τάξη Χρήστης:

class User ( προστατευμένο $id; προστατευμένο $όνομα; δημόσια συνάρτηση getId() ( return $this->id; ) δημόσια συνάρτηση setId($id) ( $this->id = $id; ) δημόσια συνάρτηση getName() ( return $this->name ) δημόσια συνάρτηση setName($name) ( $this->name = $name; ) )

Χρήστης κατηγορίας

προστατευμένο $id ;

προστατευμένο $name ;

δημόσια συνάρτηση getId()

επιστροφή $this -> id ;

δημόσια συνάρτηση setId ($id)

$this -> id = $id ;

δημόσια συνάρτηση getName()

επιστροφή $this -> name ;

δημόσια συνάρτηση setName ($name)

$this -> name = $name ;

Τώρα ας επιλέξουμε τα δεδομένα και ας εμφανίσουμε τα δεδομένα χρησιμοποιώντας μεθόδους κλάσης:

$statement = $connection->query("SELECT * FROM users"); while($row = $statement->fetch(PDO::FETCH_CLASS, "User")) ( echo $row->getId() . " " . $row->getName(); )

$statement = $connection -> ερώτημα ("SELECT * FROM users" ) ;

ενώ ($row = $statement -> fetch (PDO::FETCH_CLASS, "User") ) (

echo $row -> getId() . " " . $row -> getName () ;

Προετοιμασμένα ερωτήματα και δέσμευση παραμέτρων

Για να κατανοήσετε την ουσία και όλα τα οφέλη της δέσμευσης παραμέτρων, πρέπει να ρίξετε μια πιο προσεκτική ματιά στους μηχανισμούς Π.Ο.Π. Κατά την κλήση $statement -> query()στον παραπάνω κώδικα, Π.Ο.Πθα ετοιμάσει ένα αίτημα, θα το εκτελέσει και θα επιστρέψει το αποτέλεσμα.

Κατά την κλήση $connection -> προετοιμασία()δημιουργείται ένα έτοιμο αίτημα. Τα προετοιμασμένα ερωτήματα είναι η ικανότητα ενός συστήματος διαχείρισης βάσης δεδομένων να λαμβάνει ένα πρότυπο ερωτήματος, να το συντάσσει και να το εκτελεί μετά την ανάκτηση των τιμών των μεταβλητών που χρησιμοποιούνται στο πρότυπο. Οι μηχανές προτύπων λειτουργούν με παρόμοιο τρόπο. ΈξυπνοςΚαι Κλαδάκι.

Κατά την κλήση $statement -> execute()Οι τιμές για αντικατάσταση μεταφέρονται στο πρότυπο ερωτήματος και το DBMS εκτελεί το ερώτημα. Αυτή η ενέργεια είναι παρόμοια με την κλήση της λειτουργίας κινητήρα προτύπου καθιστώ().

Ένα παράδειγμα χρήσης προετοιμασμένων ερωτημάτων στο PHP ΠΟΠ:

Στον παραπάνω κωδικό ετοιμάζεται αίτημα για επιλογή εγγραφής με πεδίο ταυτότηταίση με την τιμή που θα αντικατασταθεί : id. Σε αυτό το στάδιο, το DBMS θα αναλύσει και θα μεταγλωττίσει το αίτημα, πιθανώς χρησιμοποιώντας προσωρινή αποθήκευση (ανάλογα με τις ρυθμίσεις).

Τώρα πρέπει να περάσετε την παράμετρο που λείπει και να εκτελέσετε το αίτημα:

$id = 5; $statement->execute([ ":id" => $id ]);

Οφέλη από τη χρήση συνδεδεμένων παραμέτρων

Ίσως μετά την εξέταση του τρόπου λειτουργίας των προετοιμασμένων ερωτημάτων και των σχετικών παραμέτρων, τα οφέλη από τη χρήση τους γίνονται εμφανή.

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

Αντίθετα, τώρα είναι σκόπιμο να κάνετε αυτό:

Μπορείτε ακόμη να συντομεύσετε περαιτέρω τον κώδικα χρησιμοποιώντας αριθμημένες παραμέτρους αντί για ονομαστές:

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

$numberOfUsers = $connection->query("SELECT COUNT(*) FROM users")->fetchColumn(); $χρήστες = ; $statement = $connection->prepare("SELECT * FROM users WHERE id = ? LIMIT 1"); για ($i = 1; $i<= 5; $i++) { $id = rand(1, $numberOfUsers); $users = $statement->execute([$id])->fetch(PDO::FETCH_OBJ); )

$numberOfUsers = $connection -> ερώτημα ("SELECT COUNT(*) FROM users" ) -> fetchColumn () ;

$χρήστες = ;

για ($i = 1 ; $i<= 5 ; $i ++ ) {

$id = rand (1 , $numberOfUsers ) ;

$users = $statement -> execute ([ $id ] ) -> fetch (PDO::FETCH_OBJ ) ;

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

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

Δεσμευμένες τιμές και ο χειριστής IN

Συχνά, όταν αρχίζετε να εργάζεστε με Π.Ο.Π, προκύπτουν δυσκολίες με τον χειριστή ΣΕ. Για παράδειγμα, φανταστείτε ότι ο χρήστης εισάγει πολλά ονόματα διαχωρισμένα με κόμμα. Η είσοδος χρήστη αποθηκεύεται σε μια μεταβλητή $names.

Σύνδεση βάσης δεδομένωνορίζεται όταν δημιουργείται μια παρουσία της κλάσης PDO. Δεν έχει σημασία ποιο πρόγραμμα οδήγησης θα επιλέξετε να χρησιμοποιήσετε. Θα πρέπει πάντα να χρησιμοποιείτε την κλάση PDO. Ο κατασκευαστής του δέχεται παραμέτρους για τον καθορισμό της προέλευσης της βάσης δεδομένων (γνωστή ως DSN) και προαιρετικές παραμέτρους για ένα όνομα χρήστη και έναν κωδικό πρόσβασης.

Σύνδεση με MySQL:

$dbh = νέο ΠΟΠ ("mysql:host=localhost;dbname=test", $user, $pass);

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

Χειρισμός σφαλμάτων σύνδεσης:

try ( $dbh = new PDO("mysql:host=localhost;dbname=test", $user, $pass); foreach($dbh->query('SELECT * from FOO') as $row) ( print_r($ row ) $dbh = null;

Προσοχή:Εάν δεν συλλάβετε την εξαίρεση που τίθεται από τον κατασκευαστή PDO, η προεπιλεγμένη ενέργεια που πραγματοποιείται από τη μηχανή zend είναι να σταματήσει το σενάριο και να εμφανιστεί ένα traceback. Αυτό το χάλι θα αποκαλύψει όλες τις προσωπικές λεπτομέρειες της επικοινωνίας σας με τη βάση δεδομένων. Αυτό είναι θα εμφανίσει λεπτομερείς λεπτομέρειες σύνδεσης βάσης δεδομένων, συμπεριλαμβανομένου του ονόματος χρήστη και του κωδικού πρόσβασης!Εναπόκειται σε εσάς να πιάσετε αυτήν την εξαίρεση, είτε ρητά (μέσω δήλωσης προσπάθησε να πιάσεις), ή σιωπηρά μέσω set_exception_handler().

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

Κλείσιμο σύνδεσης:

$dbh = νέο ΠΟΠ ("mysql:host=localhost;dbname=test", $user, $pass); // Κάτι κάνουμε εδώ: ... // Και τώρα, προσοχή: τέλος σύνδεσης! $dbh = null;

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

Ρύθμιση μόνιμης σύνδεσης:

$dbh = new PDO("mysql:host=localhost;dbname=test", $user, $pass, array(PDO::ATTR_PERSISTENT => true));

Θυμήσου:Εάν θέλετε να χρησιμοποιήσετε μια μόνιμη σύνδεση, πρέπει να ορίσετε ΠΟΠ::ATTR_PERSISTENTστον πίνακα επιλογών προγραμμάτων οδήγησης, ο οποίος μεταβιβάζεται στον κατασκευαστή κλάσης PDO. Ρυθμίζοντας αυτό το χαρακτηριστικό μέσω του PDO::setAttribute() μετά την εγκατάσταση του αντικειμένου, το πρόγραμμα οδήγησης δεν θα χρησιμοποιεί μόνιμους συνδέσμους. Και επίσης, σε αυτήν την περίπτωση, δεν θα μπορείτε να επεκτείνετε την κλάση PDOStatement για ορισμένες από τις ανάγκες σας, π.χ. δεν θα είναι δυνατή η εγκατάσταση: ΠΟΠ::ATTR_STATEMENT_CLASS

  • Μετάφραση

Πολλοί προγραμματιστές PHP έχουν συνηθίσει να χρησιμοποιούν τις επεκτάσεις mysql και mysqli για να εργαστούν με βάσεις δεδομένων. Αλλά από την έκδοση 5.1 στην PHP υπάρχει ένας πιο βολικός τρόπος - PHP Data Objects. Αυτή η τάξη, που ονομάζεται για συντομία PDO, παρέχει μεθόδους εργασίας με αντικείμενα και προετοιμασμένες δηλώσεις που θα βελτιώσουν σημαντικά την παραγωγικότητά σας!

Εισαγωγή στην Π.Ο.Π

"PDO - PHP Data Objects είναι ένα επίπεδο που προσφέρει έναν καθολικό τρόπο εργασίας με πολλές βάσεις δεδομένων."

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


Αυτό το άρθρο είναι γραμμένο για άτομα που χρησιμοποιούν mysql και mysqli για να τους βοηθήσει να μεταβούν στο πιο ισχυρό και ευέλικτο PDO.

Υποστήριξη DBMS

Αυτή η επέκταση μπορεί να υποστηρίξει οποιοδήποτε σύστημα διαχείρισης βάσης δεδομένων για το οποίο υπάρχει πρόγραμμα οδήγησης PDO. Κατά τη στιγμή της σύνταξης, είναι διαθέσιμα τα ακόλουθα προγράμματα οδήγησης:
  • PDO_CUBRID (CUBRID)
  • PDO_DBLIB (FreeTDS / Microsoft SQL Server / Sybase)
  • PDO_FIREBIRD (Firebird/Interbase 6)
  • PDO_IBM (IBM DB2)
  • PDO_INFORMIX (Δυναμικός διακομιστής IBM Informix)
  • PDO_MYSQL (MySQL 3.x/4.x/5.x)
  • PDO_OCI (Διασύνδεση κλήσεων Oracle)
  • PDO_ODBC (ODBC v3 (IBM DB2, unixODBC και win32 ODBC))
  • PDO_PGSQL (PostgreSQL)
  • PDO_SQLITE (SQLite 3 και SQLite 2)
  • PDO_SQLSRV (Microsoft SQL Server)
  • PDO_4D (4D)
Ωστόσο, δεν είναι όλα στον διακομιστή σας. Μπορείτε να δείτε τη λίστα με τα διαθέσιμα προγράμματα οδήγησης ως εξής:
print_r(PDO::getAvailableDrivers());

Σύνδεση

Οι μέθοδοι σύνδεσης σε διαφορετικά DBMS ενδέχεται να διαφέρουν ελαφρώς. Ακολουθούν παραδείγματα σύνδεσης με τα πιο δημοφιλή. Θα παρατηρήσετε ότι τα τρία πρώτα έχουν την ίδια σύνταξη, σε αντίθεση με το SQLite.
δοκιμάστε ( # MS SQL Server and Sybase via PDO_DBLIB $DBH = new PDO("mssql:host=$host;dbname=$dbname", $user, $pass); $DBH = new PDO("sybase:host=$host ;dbname=$dbname", $user, $pass); # MySQL μέσω PDO_MYSQL $DBH = νέο PDO("mysql:host=$host;dbname=$dbname", $user, $pass); # SQLite $DBH = new PDO("sqlite:my/database/path/database.db" catch(PDOException $e) (echo $e->getMessage();
Παρακαλούμε δώστε προσοχή στο μπλοκ try/catch - αξίζει πάντα να τυλίξετε όλες τις λειτουργίες PDO σας σε αυτό και να χρησιμοποιήσετε τον μηχανισμό εξαίρεσης (περισσότερα για αυτό αργότερα).

Το $DBH σημαίνει "χειρισμός βάσης δεδομένων" και θα χρησιμοποιηθεί σε όλο το άρθρο.

Μπορείτε να κλείσετε οποιαδήποτε σύνδεση επαναπροσδιορίζοντας τη μεταβλητή της σε null.
# κλείνει τη σύνδεση $DBH = null;
Περισσότερες πληροφορίες σχετικά με το θέμα των διακριτικών επιλογών διαφορετικών DBMS και τις μεθόδους σύνδεσης με αυτά μπορείτε να βρείτε στο php.net.

Εξαιρέσεις και Π.Ο.Π

Το PDO μπορεί να δημιουργήσει εξαιρέσεις σε σφάλματα, επομένως όλα θα πρέπει να βρίσκονται σε ένα μπλοκ δοκιμής/αλίευσης. Αμέσως μετά τη δημιουργία μιας σύνδεσης, το PDO μπορεί να τεθεί σε οποιαδήποτε από τις τρεις καταστάσεις σφάλματος:
$DBH->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_SILENT); $DBH->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_WARNING); $DBH->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
Αλλά αξίζει να σημειωθεί ότι ένα σφάλμα κατά την προσπάθεια σύνδεσης θα δημιουργεί πάντα μια εξαίρεση.

ΠΟΠ::ERRMODE_SILENT

Αυτή είναι η προεπιλεγμένη λειτουργία. Πιθανότατα θα χρησιμοποιήσετε περίπου το ίδιο πράγμα για να εντοπίσετε σφάλματα στις επεκτάσεις mysql και mysqli. Οι επόμενες δύο λειτουργίες είναι πιο κατάλληλες για προγραμματισμό DRY.

ΠΟΠ::ERRMODE_WARNING

Αυτή η λειτουργία θα προκαλέσει μια τυπική προειδοποίηση και θα επιτρέψει στο σενάριο να συνεχίσει να εκτελείται. Βολικό για εντοπισμό σφαλμάτων.

ΠΟΠ::ERRMODE_EXCEPTION

Στις περισσότερες περιπτώσεις, αυτός ο τύπος ελέγχου εκτέλεσης σεναρίου είναι προτιμότερος. Δημιουργεί μια εξαίρεση, επιτρέποντάς σας να χειρίζεστε έξυπνα τα σφάλματα και να αποκρύπτετε ευαίσθητες πληροφορίες. Όπως, για παράδειγμα, εδώ:
# συνδεθείτε στη βάση δεδομένων δοκιμάστε ( $DBH = νέο PDO ("mysql:host=$host;dbname=$dbname", $user, $pass); $DBH->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION) ? "PDOErrors" .txt", $e->getMessage(), FILE_APPEND); )
Υπάρχει ένα συντακτικό σφάλμα στην έκφραση SQL που θα δημιουργήσει μια εξαίρεση. Μπορούμε να καταγράψουμε τις λεπτομέρειες του σφάλματος σε ένα αρχείο καταγραφής και να υποδείξουμε στον χρήστη σε ανθρώπινη γλώσσα ότι κάτι έχει συμβεί.

Εισαγωγή και ενημέρωση

Η εισαγωγή νέων δεδομένων και η ενημέρωση υπαρχόντων δεδομένων είναι μερικές από τις πιο κοινές λειτουργίες βάσης δεδομένων. Στην περίπτωση της ΠΟΠ, αυτή η διαδικασία συνήθως αποτελείται από δύο στάδια. (Η επόμενη ενότητα αφορά τόσο την ΕΝΗΜΕΡΩΣΗ όσο και την ΕΙΣΑΓΩΓΗ)


Ένα ασήμαντο παράδειγμα εισαγωγής νέων δεδομένων:
# STH σημαίνει "Διαχείριση δήλωσης" $STH = $DBH->prepare("INSERT INTO folks (first_name) values‎ ("Cathy")"); $STH->execute();
Στην πραγματικότητα, μπορείτε να κάνετε το ίδιο πράγμα με μία μέθοδο exec(), αλλά η μέθοδος δύο βημάτων παρέχει όλα τα πλεονεκτήματα των προετοιμασμένων δηλώσεων. Βοηθούν στην προστασία από ενέσεις SQL, επομένως είναι λογικό να τα χρησιμοποιείτε ακόμη και για ένα ερώτημα.

Έτοιμες δηλώσεις

Η χρήση προετοιμασμένων δηλώσεων ενισχύει την προστασία έναντι των ενέσεων SQL.

Μια πρόταση Prepared είναι μια προ-μεταγλωττισμένη πρόταση SQL που μπορεί να εκτελεστεί επανειλημμένα στέλνοντας μόνο διαφορετικά σύνολα δεδομένων στον διακομιστή. Ένα πρόσθετο πλεονέκτημα είναι ότι είναι αδύνατο να πραγματοποιηθεί ένεση SQL μέσω των δεδομένων που χρησιμοποιούνται στα κράτη μέλη θέσης.

Ακολουθούν τρία παραδείγματα προετοιμασμένων δηλώσεων.
# χωρίς σύμβολα κράτησης θέσης - η πόρτα για τις ενέσεις SQL είναι ανοιχτή! $STH = $DBH->prepare("INSERT INTO folks (name, adr, city) values‎‎ ($name, $addr, $city)"); # unnamed placeholders $STH = $DBH->prepare("INSERT INTO folks (name, adr, city) values‎ (?, ?, ?)"); # namedplaceholders $STH = $DBH->prepare("INSERT INTO folks (name, adr, city) values‎‎ (:name, :addr, :city)");
Το πρώτο παράδειγμα είναι εδώ μόνο για σύγκριση και πρέπει να αποφεύγεται. Η διαφορά μεταξύ ανώνυμων και επώνυμων θέσεων κράτησης θέσης είναι ο τρόπος με τον οποίο μεταβιβάζετε δεδομένα σε έτοιμες δηλώσεις.

Άγνωστα σύμβολα κράτησης θέσης

# εκχωρήστε μεταβλητές σε κάθε σύμβολο κράτησης θέσης, με δείκτες από 1 έως 3 $STH->bindParam(1, $name); $STH->bindParam(2, $addr); $STH->bindParam(3, $city); # insert one line $name = "Daniel" $addr = "1 Wicked Way"; $city = "Άρλινγκτον Χάιτς"; $STH->execute(); # εισαγάγετε μια άλλη γραμμή, με διαφορετικά δεδομένα $name = "Steve" $addr = "5 Circle Drive"; $city = "Schaumburg"; $STH->execute();
Υπάρχουν δύο βήματα εδώ. Στην πρώτη, εκχωρούμε μεταβλητές σε όλα τα σύμβολα κράτησης θέσης (γραμμές 2-4). Στη συνέχεια, εκχωρούμε τιμές σε αυτές τις μεταβλητές και εκτελούμε το ερώτημα. Για να στείλετε ένα νέο σύνολο δεδομένων, απλώς αλλάξτε τις τιμές των μεταβλητών και εκτελέστε ξανά το αίτημα.

Εάν η έκφρασή σας SQL έχει πολλές παραμέτρους, τότε η εκχώρηση μιας μεταβλητής σε καθεμία είναι πολύ άβολη. Σε τέτοιες περιπτώσεις, μπορείτε να αποθηκεύσετε τα δεδομένα σε έναν πίνακα και να τα μεταβιβάσετε:
# το σύνολο δεδομένων που θα εισαγάγουμε $data = array("Cathy", "9 Dark and Twisty Road", "Cardiff"); $STH = $DBH->prepare("INSERT INTO folks (όνομα, διεύθυνση, πόλη) τιμές (?, ?, ?)"); $STH->execute($data);
Το $data θα εισαχθεί στη θέση του πρώτου placeholder, το $data στη θέση του δεύτερου κ.λπ. Αλλά να είστε προσεκτικοί: εάν τα ευρετήρια σας είναι μπερδεμένα, αυτό δεν θα λειτουργήσει.

Επώνυμα σύμβολα κράτησης θέσης

# το πρώτο όρισμα είναι το όνομα του σύμβολο κράτησης θέσης # συνήθως ξεκινά με άνω και κάτω τελεία #, αν και λειτουργεί χωρίς αυτά $STH->bindParam(":name", $name);
Εδώ μπορείτε επίσης να περάσετε έναν πίνακα, αλλά πρέπει να είναι συσχετιστικός. Τα κλειδιά θα πρέπει να είναι, όπως μπορείτε να μαντέψετε, τα ονόματα των placeholders.
# τα δεδομένα που εισάγουμε $data = array("name" => "Cathy", "addr" => "9 Dark and Twisty", "city" => "Cardiff"); $STH = $DBH->prepare("INSERT INTO folks (name, adr, city) values‎ (:name, :addr, :city)"); $STH->execute($data);
Μία από τις ευκολίες της χρήσης ονομασμένων θέσεων κράτησης θέσης είναι η δυνατότητα εισαγωγής αντικειμένων απευθείας στη βάση δεδομένων εάν τα ονόματα ιδιοτήτων ταιριάζουν με τα ονόματα των παραμέτρων. Για παράδειγμα, μπορείτε να εισαγάγετε δεδομένα ως εξής:
# class για ένα άτομο κατηγορίας απλού αντικειμένου ( δημόσιο $name; δημόσιο $addr; δημόσιο $city; συνάρτηση __construct($n,$a,$c) ( $this->name = $n; $this->addr = $ a ; $this->city = $c ) # so on... ) $cathy = new person("Cathy","9 Dark and Twisty","Cardiff"); # και εδώ είναι το ενδιαφέρον μέρος $STH = $DBH->prepare("INSERT INTO folks (name, adr, city) values‎‎ (:name, :addr, :city)"); $STH->execute((array)$cathy);
Η μετατροπή ενός αντικειμένου σε πίνακα κατά τη διάρκεια της execute() προκαλεί τις ιδιότητες να αντιμετωπίζονται ως κλειδιά πίνακα.

Δειγματοληψία δεδομένων



Τα δεδομένα μπορούν να ανακτηθούν χρησιμοποιώντας τη μέθοδο ->fetch(). Προτού το καλέσετε, καλό είναι να αναφέρετε ρητά σε ποια μορφή τα χρειάζεστε. Υπάρχουν πολλές επιλογές:
  • ΠΟΠ::FETCH_ASSOC:επιστρέφει έναν πίνακα με ονόματα στηλών ως κλειδιά
  • PDO::FETCH_BOTH (προεπιλογή):επιστρέφει έναν πίνακα με ευρετήρια τόσο με τη μορφή ονομάτων στηλών όσο και με τους σειριακούς αριθμούς τους
  • ΠΟΠ::FETCH_BOUND:εκχωρεί τιμές στηλών στις αντίστοιχες μεταβλητές που καθορίζονται χρησιμοποιώντας τη μέθοδο ->bindColumn()
  • ΠΟΠ::FETCH_CLASS:εκχωρεί τιμές στηλών στις αντίστοιχες ιδιότητες της καθορισμένης κλάσης. Εάν δεν υπάρχει ιδιότητα για κάποια στήλη, θα δημιουργηθεί
  • PDO::FETCH_INTO:ενημερώνει μια υπάρχουσα παρουσία της καθορισμένης κλάσης
  • ΠΟΠ::FETCH_LAZY:συνδυάζει PDO::FETCH_BOTH και PDO::FETCH_OBJ
  • ΠΟΠ::FETCH_NUM:επιστρέφει έναν πίνακα με κλειδιά ως αριθμούς στηλών
  • ΠΟΠ::FETCH_OBJ:επιστρέφει ένα ανώνυμο αντικείμενο με ιδιότητες που αντιστοιχούν στα ονόματα των στηλών
Στην πράξη, συνήθως θα χρειαστείτε τρία: FETCH_ASSOC, FETCH_CLASS και FETCH_OBJ. Για να καθορίσετε τη μορφή δεδομένων, χρησιμοποιήστε την ακόλουθη σύνταξη:
$STH->setFetchMode(PDO::FETCH_ASSOC);
Μπορείτε επίσης να το ρυθμίσετε απευθείας όταν καλείτε τη μέθοδο ->fetch().

FETCH_ASSOC

Αυτή η μορφή δημιουργεί έναν συσχετιστικό πίνακα με ονόματα στηλών ως ευρετήρια. Θα πρέπει να είναι οικείο σε όσους χρησιμοποιούν τις επεκτάσεις mysql/mysqli.
# δεδομένου ότι αυτό είναι ένα κανονικό ερώτημα χωρίς σύμβολα κράτησης θέσης, # μπορείτε να χρησιμοποιήσετε αμέσως τη μέθοδο query() $STH = $DBH->query("SELECT name, adr, city from folks"); # ορίστε τη λειτουργία ανάκτησης $STH->setFetchMode(PDO::FETCH_ASSOC); while($row = $STH->fetch()) ( echo $row["name"] . "\n"; echo $row["addr"] . "\n"; echo $row["city"] "\n" ;
Ο βρόχος while() θα επαναληφθεί σε ολόκληρο το αποτέλεσμα του ερωτήματος.

FETCH_OBJ

Αυτός ο τύπος απόκτησης δεδομένων δημιουργεί μια παρουσία της κλάσης std για κάθε γραμμή.
# δημιουργήστε ένα ερώτημα $STH = $DBH->ερώτημα ("ΕΠΙΛΟΓΗ ονόματος, διεύθυνσης, πόλης από άτομα"); # επιλέξτε τη λειτουργία ανάκτησης $STH->setFetchMode(PDO::FETCH_OBJ); # εκτυπώστε το αποτέλεσμα while($row = $STH->fetch()) ( echo $row->name . "\n"; echo $row->addr . "\n"; echo $row->city . " \ n";)

FETCH_CLASS

Όταν χρησιμοποιείτε fetch_class, τα δεδομένα εγγράφονται σε παρουσίες της καθορισμένης κλάσης. Σε αυτήν την περίπτωση, οι τιμές εκχωρούνται στις ιδιότητες του αντικειμένου ΠΡΙΝ καλέσετε τον κατασκευαστή. Εάν δεν υπάρχουν ιδιότητες με ονόματα που αντιστοιχούν σε ονόματα στηλών, θα δημιουργηθούν αυτόματα (με το εύρος κοινό).

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

Για παράδειγμα, ας πάρουμε μια κατάσταση όπου πρέπει να αποκρύψετε μέρος της διεύθυνσης κατοικίας ενός ατόμου.
class secret_person ( public $name; public $addr; public $city; public $other_data; function __construct($other = "") ( $this->addr = preg_replace("//", "x", $this-> addr); $this->other_data = $other;
Κατά τη δημιουργία ενός αντικειμένου, όλα τα πεζά λατινικά γράμματα πρέπει να αντικατασταθούν με x. Ας ελέγξουμε:
$STH = $DBH->query("ΕΠΙΛΟΓΗ ονόματος, διεύθυνσης, πόλης από άτομα"); $STH->setFetchMode(PDO::FETCH_CLASS, "secret_person"); while($obj = $STH->fetch()) ( echo $obj->addr; )
Εάν η διεύθυνση στη βάση δεδομένων μοιάζει με '5 Rosebud', τότε η έξοδος θα είναι '5 Rxxxxxx'.

Φυσικά, μερικές φορές θα θέλετε να καλείται ο κατασκευαστής ΠΡΙΝ την εκχώρηση τιμών. Το ΠΟΠ το επιτρέπει και αυτό.
$STH->setFetchMode(PDO::FETCH_CLASS | PDO::FETCH_PROPS_LATE, "secret_person");
Τώρα που έχετε συμπληρώσει το προηγούμενο παράδειγμα με μια πρόσθετη επιλογή (PDO::FETCH_PROPS_LATE), η διεύθυνση δεν θα τροποποιηθεί, καθώς δεν συμβαίνει τίποτα μετά την εγγραφή των τιμών.

Τέλος, εάν είναι απαραίτητο, μπορείτε να μεταβιβάσετε ορίσματα στον κατασκευαστή απευθείας κατά τη δημιουργία του αντικειμένου:
$STH->setFetchMode(PDO::FETCH_CLASS, "secret_person", array("stuff"));
Μπορείτε ακόμη και να περάσετε διαφορετικά ορίσματα σε κάθε αντικείμενο:
$i = 0; while($rowObj = $STH->fetch(PDO::FETCH_CLASS, "secret_person", πίνακας($i))) ( // κάντε κάτι $i++; )

Άλλες Χρήσιμες Μέθοδοι

Αν και αυτό το άρθρο δεν μπορεί (και δεν επιχειρεί) να καλύψει κάθε πτυχή της εργασίας με το PDO (είναι μια τεράστια ενότητα!), τα ακόλουθα λίγα χαρακτηριστικά δεν μπορούν να παραληφθούν χωρίς αναφορά.
$DBH->lastInsertId();
Η μέθοδος ->lastInsertId() επιστρέφει το αναγνωριστικό της τελευταίας εγγραφής που εισήχθη. Αξίζει να σημειωθεί ότι καλείται πάντα σε ένα αντικείμενο βάσης δεδομένων (που ονομάζεται $DBH σε αυτό το άρθρο) και όχι σε ένα αντικείμενο με έκφραση ($STH).
$DBH->exec("DELETE FROM folks WHERE 1"); $DBH->exec("SET time_zone = "-8:00"");
Η μέθοδος ->exec() χρησιμοποιείται για λειτουργίες που δεν επιστρέφουν δεδομένα εκτός από τον αριθμό των εγγραφών που επηρεάζονται από αυτές.
$safe = $DBH->quote($unsafe);
Η μέθοδος ->quote() τοποθετεί εισαγωγικά σε δεδομένα συμβολοσειράς έτσι ώστε να είναι ασφαλής η χρήση τους σε ερωτήματα. Χρήσιμο εάν δεν χρησιμοποιείτε έτοιμες δηλώσεις.
$rows_affected = $STH->rowCount();
Η μέθοδος ->rowCount() επιστρέφει τον αριθμό των εγγραφών που συμμετείχαν στη λειτουργία. Δυστυχώς, αυτή η συνάρτηση δεν λειτουργούσε με ερωτήματα SELECT μέχρι την PHP 5.1.6. Εάν δεν είναι δυνατή η ενημέρωση της έκδοσης PHP, ο αριθμός των εγγραφών μπορεί να ληφθεί ως εξής:
$sql = "SELECT COUNT(*) FROM folks"; if ($STH = $DBH->query($sql)) ( # ελέγξτε τον αριθμό των εγγραφών εάν ($STH->fetchColumn() > 0) ( # κάντε μια πλήρη επιλογή εδώ επειδή βρέθηκαν τα δεδομένα! ) else ( # εκτυπώστε ένα μήνυμα ότι δεν βρέθηκαν δεδομένα που να ικανοποιούν το αίτημα) )

συμπέρασμα

Ελπίζω ότι αυτό το υλικό θα βοηθήσει ορισμένους από εσάς να μεταναστεύσουν από τις επεκτάσεις mysql και mysqli.


3 Ιουνίου 2018 Αντρέι Τσερνίσοφ Φροντιστήριο μετάφρασης 1737 0

Το PDO είναι ένα αρκτικόλεξο του PHP Data Objects: είναι μια επέκταση PHP για εργασία με βάσεις δεδομένων χρησιμοποιώντας αντικείμενα. Ένα από τα πλεονεκτήματά του έγκειται στο γεγονός ότι δεν συνδέεται άμεσα με μια συγκεκριμένη βάση δεδομένων: η διεπαφή του σας επιτρέπει να έχετε πρόσβαση σε πολλά διαφορετικά περιβάλλοντα, όπως: MySQL, SQLite, PostgreSQL, Microsoft SQL Server.

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

Δημιουργία δοκιμαστικής βάσης δεδομένων και πίνακα

Πρώτα απ 'όλα, θα δημιουργήσουμε μια βάση δεδομένων:

ΔΗΜΙΟΥΡΓΙΑ ΒΑΣΗΣ ΔΕΔΟΜΕΝΩΝ solar_system; ΠΑΡΑΧΩΡΗΣΤΕ ΟΛΑ ΤΑ ΠΡΟΝΟΜΙΑ ΣΤΟ solar_system.* ΣΤΟΝ "testuser"@"localhost" ΠΟΥ ΑΝΑΓΝΩΡΙΖΕΤΑΙ ΑΠΟ "testpassword".

Έχουμε παραχωρήσει στον χρήστη testuser όλα τα δικαιώματα στη βάση δεδομένων solar_system χρησιμοποιώντας το testpassword για τον κωδικό πρόσβασης. Τώρα ας δημιουργήσουμε έναν πίνακα και ας τον συμπληρώσουμε με μερικές πληροφορίες:

ΧΡΗΣΗ ηλιακού συστήματος. ΔΗΜΙΟΥΡΓΙΑ ΠΛΑΑΝΤΩΝ ΠΙΝΑΚΑΣ (ID TINYINT(1) ΜΗ ΥΠΟΓΡΑΦΗ ΜΗ NULL AUTO_INCREMENT, ΚΥΡΙΟ ΚΛΕΙΔΙ(id), όνομα VARCHAR(10) NOT NULL, χρώμα VARCHAR(10) NOT NULL); INSERT INTO πλανήτες (όνομα, χρώμα) ΤΙΜΕΣ ("γη", "μπλε"), ("άρης", "κόκκινο"), ("Δίας", "παράξενο");

Περιγραφή της σύνδεσης DSN (Όνομα πηγής δεδομένων).

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

  • Τύπος προγράμματος οδήγησης που χρησιμοποιείται για σύνδεση.
  • Το όνομα του κεντρικού υπολογιστή στον οποίο εκτελείται η βάση δεδομένων.
  • Θύρα σύνδεσης (προαιρετικό).
  • Ονομα βάσης δεδομένων;
  • Κωδικοποίηση (προαιρετικό).

Η μορφή συμβολοσειράς στην περίπτωσή μας θα είναι αυτή (θα την αποθηκεύσουμε στη μεταβλητή $dsn):

$dsn = "mysql:host=localhost;port=3306;dbname=solar_system;charset=utf8";

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

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

Δημιουργία αντικειμένου ΠΟΠ

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

$options = [ PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION, PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC ]; $pdo = new PDO($dsn, "testuser", "testpassword", $options);

Οι ρυθμίσεις μπορούν επίσης να οριστούν μετά τη δημιουργία του αντικειμένου, χρησιμοποιώντας τη μέθοδο SetAttribute():

$pdo->SetAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);

Διαμόρφωση ΠΟΠ για την προβολή σφαλμάτων

Ας ρίξουμε μια ματιά σε μερικές από τις διαθέσιμες επιλογές για το PDO::ATTR_ERRMODE. Αυτές οι επιλογές είναι εξαιρετικά σημαντικές γιατί καθορίζουν πώς συμπεριφέρεται το PDO όταν συμβαίνουν σφάλματα. Πιθανές επιλογές:

ΠΟΠ::ERRMODE_SILENT

Προεπιλεγμένη επιλογή. Το PDO θα στείλει απλώς έναν κωδικό σφάλματος και ένα μήνυμα σφάλματος. Μπορούν να ληφθούν χρησιμοποιώντας τις μεθόδους errorCode() και errorInfo().

ΠΟΠ::ERRMODE_EXCEPTION

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

ΠΟΠ::ERRMODE_WARNING

Με αυτήν την επιλογή, το PDO θα εμφανίσει έναν κωδικό σφάλματος και ένα μήνυμα ακριβώς όπως το PDO::ERRMODE_SILENT , αλλά θα εμφανίσει επίσης μια προειδοποίηση ΠΡΟΕΙΔΟΠΟΙΗΣΗ που δεν διακόπτει το σενάριο.

Ρύθμιση της προεπιλεγμένης μεθόδου δειγματοληψίας

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

ΠΟΠ::FETCH_BOTH

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

$stmt = $pdo->query("SELECT * FROM planets"); $results = $stmt->fetch(PDO::FETCH_BOTH); Πίνακας ( => 1 => 1 => γη => γη => μπλε => μπλε)

ΠΟΠ::FETCH_ASSOC

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

$stmt = $pdo->query("SELECT * FROM planets"); $results = $stmt->fetch(PDO::FETCH_ASSOC); Πίνακας ( => 1 => γη => μπλε)

ΠΟΠ::FETCH_NUM

Χρησιμοποιώντας τη σταθερά PDO::FETCH_NUM παίρνουμε έναν πίνακα με ευρετήριο 0:

Πίνακας ( => 1 => γη => μπλε)

ΠΟΠ::FETCH_COLUMN

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

$stmt = $pdo->query("SELECT name FROM planets");

Σαν άποτέλεσμα:

Πίνακας ( => γη => Άρης => Δίας)

ΠΟΠ::FETCH_KEY_PAIR

Αυτή η σταθερά είναι χρήσιμη όταν χρειάζεται να λάβετε τιμές από δύο στήλες. Η μέθοδος fetchAll() θα επιστρέψει τα αποτελέσματα ως συσχετιστικό πίνακα. Σε αυτόν τον πίνακα, τα δεδομένα από την πρώτη στήλη θα καθοριστούν με τη μορφή κλειδιών και από τη δεύτερη - ως τιμές:

$stmt = $pdo->query("SELECT name, color FROM planets"); $result = $stmt->fetchAll(PDO::FETCH_KEY_PAIR);

Σαν άποτέλεσμα:

Πίνακας ( => μπλε => κόκκινο => παράξενο)

ΠΟΠ::FETCH_OBJECT

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

$results = $stmt->fetch(PDO::FETCH_OBJ); Αντικείμενο stdClass ( => γη => μπλε)

ΠΟΠ::FETCH_CLASS

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

Κλάση Planet ( ιδιωτικό $name; ιδιωτικό $color; δημόσια συνάρτηση setName($planet_name) ( $this->name = $planet_name; ) δημόσια συνάρτηση setColor($planet_color) ( $this->color = $planet_color; ) δημόσια συνάρτηση getName () ( return $this->name; ) δημόσια συνάρτηση getColor() ( return $this->color; ) )

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

Όταν χρησιμοποιείτε το fetch() με το PDO::FETCH_CLASS, πρέπει να χρησιμοποιήσετε τη μέθοδο setFetchMode() στο αντικείμενο πριν επιχειρήσετε να ανακτήσετε τα δεδομένα, για παράδειγμα:

$stmt = $pdo->query("SELECT name, color FROM planets"); $stmt->setFetchMode(PDO::FETCH_CLASS, "Planet");

Καθορίζουμε τη σταθερά PDO::FETCH_CLASS ως το πρώτο όρισμα της μεθόδου setFetchMode() και το όνομα της κλάσης που χρησιμοποιήθηκε για τη δημιουργία του αντικειμένου (στην περίπτωσή μας "Planet") ως δεύτερο όρισμα. Τώρα ας τρέξουμε τον κώδικα:

$planet = $stmt->fetch();

Αυτό θα πρέπει να έχει ως αποτέλεσμα ένα αντικείμενο Planet:

Var_dump($planet); Πλανητικό αντικείμενο ( => γη => μπλε)

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

Εκχώρηση χαρακτηριστικών μετά τη δημιουργία ενός αντικειμένου

Η κλάση "Planet" δεν είχε συγκεκριμένο κατασκευαστή, επομένως δεν υπήρχαν προβλήματα με την εκχώρηση χαρακτηριστικών. αλλά τι γίνεται αν η κλάση έχει έναν κατασκευαστή στον οποίο τίθενται και αλλάζουν τα χαρακτηριστικά; Δεδομένου ότι οι τιμές εκχωρούνται πριν από την εκτέλεση του κατασκευαστή, θα αντικατασταθούν.

Το PDO βοηθά στην παροχή της σταθεράς FETCH_PROPS_LATE: όταν χρησιμοποιείται, οι τιμές θα εκχωρούνται μετά τη δημιουργία του αντικειμένου. Παράδειγμα:

Class Planet ( ιδιωτικό $name; ιδιωτικό $color; δημόσια συνάρτηση __construct($name = φεγγάρι, $color = γκρι) ( $this->name = $name; $this->color = $color; ) δημόσια συνάρτηση setName($ planet_name) ( $this->name = $planet_name; ) δημόσια συνάρτηση setColor($planet_color) ( $this->color = $planet_color; ) δημόσια συνάρτηση getName() ( return $this->name; ) δημόσια συνάρτηση getColor() ( επιστροφή $this->color; ) )

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

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

$stmt = $pdo->query("SELECT name, color FROM solar_system WHERE name = "earth""); $stmt->setFetchMode(PDO::FETCH_CLASS, "Planet"); $planet = $stmt->fetch();

Τώρα ας ρίξουμε μια ματιά στο αντικείμενο Planet και ας ελέγξουμε ποιες τιμές αντιστοιχούν στα χαρακτηριστικά του:

Var_dump($planet); object(Planet)#2 (2) ( ["name":"Planet":private]=> string(4) "moon" ["color":"Planet":private]=> string(4) "grey" )

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

$stmt->setFetchMode(PDO::FETCH_CLASS|PDO::FETCH_PROPS_LATE, "Planet"); $planet = $stmt->fetch(); var_dump($planet); object(Planet)#4 (2) ( ["name":"Planet":private]=> string(5) "earth" ["color":"Planet":private]=> string(4) "blue" )

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

Class Planet ( ιδιωτικό $name; ιδιωτικό $color; δημόσια συνάρτηση __construct($name, $color) ( $this->name = $name; $this->color = $color; ) [...] )

Τα ορίσματα του κατασκευαστή απαιτούνται τώρα, επομένως τρέχουμε:

$stmt->setFetchMode(PDO::FETCH_CLASS|PDO::FETCH_PROPS_LATE, "Planet", ["moon", "grey"]);

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

Ανάκτηση πολλαπλών αντικειμένων

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

Ενώ ($planet = $stmt->fetch()) ( // Κάτι που έχει να κάνει με τα αποτελέσματα )

Ή λήψη όλων των αποτελεσμάτων ταυτόχρονα. Σε αυτήν την περίπτωση, όπως αναφέρθηκε προηγουμένως, όταν χρησιμοποιείτε τη μέθοδο fetchAll() θα χρειαστεί να καθορίσετε τη λειτουργία ανάκτησης όχι πριν εκτελέσετε τη μέθοδο, αλλά τη στιγμή που εκτελείται:

$stmt->fetchAll(PDO::FETCH_CLASS|PDO_FETCH_PROPS_LATE, "Planet", ["moon", "grey"]);

PDO::FETCH_INTO

Όταν χρησιμοποιείται αυτή η σταθερά, το PDO δεν δημιουργεί ένα νέο αντικείμενο, αλλά ενημερώνει τα χαρακτηριστικά ενός υπάρχοντος, αλλά μόνο εάν είναι δημόσιο ή εάν η μέθοδος __set() χρησιμοποιείται μέσα στο αντικείμενο.

Προετοιμάστηκε έναντι άμεσων αιτημάτων

Η ΠΟΠ έχει δύο τρόπους εργασίας με ερωτήματα: χρησιμοποιώντας άμεσες και τον πιο αξιόπιστο - προετοιμασμένοι.

Άμεσα αιτήματα

Υπάρχουν δύο κύριες μέθοδοι για τη χρήση άμεσων ερωτημάτων: query() και exec() . Το πρώτο δημιουργεί ένα αντικείμενο PDOSstatemnt, στο οποίο μπορείτε να προσπελάσετε μέσω των μεθόδων fetch() ή fetchAll(): εάν τις χρησιμοποιήσετε σε περιπτώσεις όπου ο πίνακας δεν αλλάζει, όπως SELECT .

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

Έτοιμα ερωτήματα

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

$stmt = $pdo->prepare("INSERT INTO planets(name, color) VALUES(?, ?)");

Όπως αναφέρθηκε προηγουμένως, χρησιμοποιούμε τη μέθοδο προετοιμασίας() που παίρνει το ερώτημα SQL ως όρισμα, χρησιμοποιώντας προσωρινές τιμές για τις μεταβλητές. Οι προσωρινές τιμές μπορούν να είναι δύο τύπων: θέσεις και ονομαστικές.

Θέσεως

Χρησιμοποιώντας? προσωρινές τιμές θέσης, ο κώδικας είναι πιο συνοπτικός, αλλά πρέπει να καθορίσουμε τα δεδομένα που θα εισαχθούν με την ίδια σειρά με τα ονόματα στηλών στον πίνακα που παρέχονται ως όρισμα στη μέθοδο execute():

$stmt->execute([$planet->name, $planet->color]);

Εξατομικευμένη

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

$stmt = $pdo->prepare("INSERT INTO planets(name, color) VALUES(:name, :color)"); $stmt->execute(["name" => $planet->name, "color" => $planet->color]);

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

Οι μέθοδοι bindValue() και bindParam().

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

$stmt->bindValue("name", $planet->name, PDO::PARAM_STR);

Συνδέουμε την τιμή του $planet->name σε μια προσωρινή τιμή:name . Σημειώστε ότι χρησιμοποιώντας και τις δύο μεθόδους bindValue() και bindParam() μπορούμε επίσης να καθορίσουμε τον τύπο της μεταβλητής ως το τρίτο όρισμα χρησιμοποιώντας μια κατάλληλη σταθερά PDO, σε αυτήν την περίπτωση PDO::PARAM_STR .

Χρησιμοποιώντας την bindParam() αντ' αυτού μπορούμε να συνδέσουμε τη μεταβλητή σε μια κατάλληλη προσωρινή τιμή που χρησιμοποιείται στην προετοιμασία του ερωτήματος. Σημειώστε ότι σε αυτήν την περίπτωση, η μεταβλητή είναι δεσμευμένη σε αναφορά και η τιμή της θα αλλάξει σε προσωρινή μόνο όταν εκτελείται η μέθοδος execute(). Η σύνταξη είναι ίδια με την προηγούμενη φορά:

$stmt->bindParam("name", $planet->name, PDO::PARAM_STR)

Έχουμε δεσμεύσει τη μεταβλητή, όχι την τιμή της, $planet->name σε:name ! Όπως αναφέρθηκε παραπάνω, η αντικατάσταση θα γίνει μόνο όταν εκτελείται η μέθοδος execute(), οπότε η προσωρινή τιμή θα αντικατασταθεί με την τιμή της μεταβλητής εκείνη τη στιγμή.

Συναλλαγές ΠΟΠ

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

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

$pdo->beginTransaction(); try ( $stmt1 = $pdo->exec("DELETE FROM planets"); $stmt2 = $pdo->prepare("INSERT INTO planets(name, color) VALUES (?, ?)"); foreach ($planets as $planet) ( $stmt2->execute([$planet->getName(), $planet->getColor()]); ) $pdo->commit() ) catch (PDOException $e) ( $pdo-> rollBack ()

Πρώτα απ 'όλα, η μέθοδος beginTransaction() στο αντικείμενο PDO απενεργοποιεί την αυτόματη δέσμευση του αιτήματος και, στη συνέχεια, τα αιτήματα ξεκινούν με την απαιτούμενη σειρά. Σε αυτό το σημείο, εκτός εάν παρουσιαστεί PDOException, τα αιτήματα περνούν αυτόματα μέσω της μεθόδου commit() διαφορετικά, οι συναλλαγές ακυρώνονται μέσω της μεθόδου rollBack() και η αυτόματη δέσμευση αποκαθίσταται.

Με αυτόν τον τρόπο, με πολλαπλά αιτήματα, θα υπάρχει πάντα συνέπεια. Αυτό είναι αρκετά προφανές, αλλά οι συναλλαγές PDO μπορούν να χρησιμοποιηθούν μόνο από το PDO::ATTR_ERRMODE που έχει οριστεί σε PDO::ERRMODE_EXCEPTION .

Πλαίσιο εκκίνησης: γρήγορη προσαρμοστική διάταξη

Βήμα προς βήμα μάθημα βίντεο σχετικά με τα βασικά της προσαρμοστικής διάταξης στο πλαίσιο Bootstrap.

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

Διάταξη για παραγγελία και πληρωμή.

Δωρεάν μάθημα "Ιστότοπος στο WordPress"

Θέλετε να κατακτήσετε το WordPress CMS;

Λάβετε μαθήματα σχεδίασης και διάταξης ιστότοπου στο WordPress.

Μάθετε να εργάζεστε με θέματα και να κόβετε διατάξεις.

Δωρεάν βίντεο μάθημα σχεδίασης, σχεδίασης, διάταξης και εγκατάστασης ιστοσελίδας σε CMS WordPress!

*Τοποθετήστε το ποντίκι για παύση της κύλισης.

Πίσω μπροστά

Βασικά στοιχεία εργασίας με την επέκταση ΠΟΠ

Σήμερα θα συζητήσουμε ένα πολύ ενδιαφέρον θέμα - τα βασικά της εργασίας με την επέκταση. Π.Ο.Πγια PHP.

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

Πώς θα έπρεπε να είχαμε συνδεθεί με τη βάση δεδομένων πριν MySQL?

Mysql_connect($host, $user, $password); mysql_select_db($db);

Για να συνδεθείτε με SQLiteέπρεπε να το είχαμε γράψει ως εξής:

Sqlite_open($db);

Αν χρειαζόμαστε βάση δεδομένων PostgreSQL, τότε πρέπει να το γράψετε ως εξής:

Pg_connect("host=$host, dbname=$db, user=$user, password=$password");

Δεν είναι πολύ βολικό, σωστά; Αποδεικνύεται ότι αν θέλουμε να αλλάξουμε τη βάση δεδομένων, θα πρέπει να ξανακάνουμε πολύ κώδικα. Και έτσι, για να διορθωθεί αυτό, εμφανίστηκε μια ειδική επέκταση PHP - Π.Ο.Π.

Ας δούμε πώς μπορούμε τώρα να συνδεθούμε στη βάση δεδομένων:

$db = νέο ΠΟΠ("mysql:host=$host;dbname=$db", $user, $password);

$db = new PDO("sqlite:$db);

PostgreSQL:

$db = νέο ΠΟΠ("pgsql:host=$host;dbname=$db", $user, $password);

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


Τώρα ας δούμε πώς έπρεπε να εκτελούμε ερωτήματα:

$sql = "INSERT INTO(name, email) VALUES($name, $email)"; // MySQL mysql_query($sql); // SQLite sqlite_query($sql); // PostgreSQL pg_query($sql);

Τώρα μπορούμε να αφαιρέσουμε από αυτό:

// ΠΟΠ $result = $db->exec($sql);

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

Ωστόσο, δεν θα μπορούμε να επιλέξουμε κάτι από τη βάση δεδομένων με αυτόν τον τρόπο. Για δειγματοληψία πρέπει να χρησιμοποιήσουμε όχι εκτελεστ, ΕΝΑ ερώτηση.

$sql = "ΕΠΙΛΟΓΗ ονόματος ΑΠΟ χρήστες"; $result = $db->query($sql);

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

$sql = "SELECT * FROM users WHERE name = $name"; $name = $_POST["όνομα"]; // MySQL $name = mysql_real_escape_string($name); // SQLite $name = sqlite_escape_string($name); // PostgreSQL $name = pg_escape_string($name);

Τώρα δεν χρειάζεται να το κάνουμε αυτό. Π.Ο.Πθα κάνει τα πάντα για εμάς.

$name = $db->quote($name); $result = $db->query($sql);

Η ίδια η ΠΟΠ θα ελέγξει τα πάντα και θα επεξεργαστεί τα μεταδιδόμενα δεδομένα. Cool; :) Ακόμα πιο δροσερό να έρθει! Ας συνεχίσουμε.

Πώς μετατρέψαμε το αποτέλεσμα σε πίνακα πριν;Ας δούμε τη βάση δεδομένων ως παράδειγμα MySQL.

$result = mysql_query($sql); // Άρα $row = mysql_fetch_assoc($result); // Ή κάπως έτσι... $row = mysql_fetch_array($result, FETCH_ASSOC);

Ακριβώς όπως το συσχετιστικό, θα μπορούσαμε επίσης να πάρουμε έναν αριθμημένο πίνακα. Τώρα ας δούμε πώς γίνεται αυτό σε Π.Ο.Π:

$stmt = $db->query($sql); //Συσχετικός $result = $stmt->FETCH(PDO::FETCH_ASSOC); // Αριθμημένο $result = $stmt->FETCH(PDO::FETCH_NUM); // Και οι δύο τύποι πινάκων ταυτόχρονα $result = $stmt->FETCH(PDO::FETCH_BOTH); // Αντικείμενο $result = $stmt->FETCH(PDO::FETCH_OBJ);

Είναι επίσης πολύ εύκολο στη χρήση:

// Associative echo $result["name"]; // Αριθμημένη ηχώ $result; // Αντικείμενο echo $result->name;

Για τους «τεμπέληδες» υπάρχει το εξής:

$stmt = $db->query($sql); $result = $stmt->FETCH(PDO::FETCH_LAZY);

Επιστρέφει και τους 3 τύπους ταυτόχρονα. Εκείνοι. Αυτό FETCH_BOTHΚαι FETCH_OBJμαζί. Όπως ίσως έχετε μαντέψει, μετά από αυτό τα δεδομένα είναι προσβάσιμα με οποιονδήποτε από τους τρεις τρόπους:

Echo $result->name; echo $result["name"]; echo $result;

Ωστόσο Φέρωεπιστρέφει μόνο μία εγγραφή, οπότε αν θέλουμε να πάρουμε όλες τις εγγραφές, τότε πρέπει να χρησιμοποιήσουμε FetchAll.

$stmt = $db->query("SELECT * FROM users"); $result = $stmt->FetchAll(PDO::FETCH_ASSOC); foreach($result ως $user) ( echo $user["name"]."
"; }

Αλλά υπάρχει ένα άλλο ωραίο πράγμα που σχετίζεται με Φέρω. Με τη βοήθειά του μπορούμε να γεμίσουμε την τάξη μας με δεδομένα από τη βάση δεδομένων αυτομάτως.

Χρήστης τάξης ( δημόσια $login; δημόσια $id; δημόσια συνάρτηση showInfo() ( echo " ".$this->id.""." : ".$this->login."
"; ) ) $db = νέο PDO("mysql:host=localhost;dbname=test", "root", ""); $stmt = $db->query("SELECT * FROM `users`"); $ result = $stmt->fetchAll(PDO::FETCH_CLASS, "User" foreach($result as $user) ( $user->showInfo();

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

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

Μεταξύ άλλων, μπορούμε να δημιουργήσουμε τα λεγόμενα έτοιμες ερωτήσεις. Ποια είναι τα πλεονεκτήματά τους;

1. Μπορούμε να ετοιμάσουμε ένα αίτημα μία φορά και μετά να το εκτελέσουμε όσες φορές χρειαζόμαστε. Και με τις ίδιες και με άλλες παραμέτρους.

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

2. Οι προετοιμασμένες παράμετροι ερωτήματος δεν χρειάζεται να διαφεύγουν με εισαγωγικά το πρόγραμμα οδήγησης το κάνει αυτόματα. Εάν η εφαρμογή χρησιμοποιεί μόνο προετοιμασμένα ερωτήματα, τότε οι ενέσεις SQL είναι σχεδόν αδύνατες.

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

$stmt = $db->prepare("INSERT INTO users (όνομα, login) VALUES (:name, :login)"); $stmt->bindParam(":name", $name); $stmt->bindParam(":login", $login); // Εισαγάγετε μια γραμμή με αυτές τις τιμές $name = "vasya"; $login = "vasya123"; $stmt->execute(); // Τώρα μια άλλη γραμμή με διαφορετικές τιμές $name = "petya"; $login = "petya123"; $stmt->execute();

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

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

$stmt = $db->prepare("INSERT INTO users (όνομα, σύνδεση) VALUES (?, ?)"); // Τα δεδομένα από τη μεταβλητή name θα εισαχθούν αντί για το πρώτο ερωτηματικό $stmt->bindParam(1, $name); // Τα δεδομένα από τη μεταβλητή σύνδεσης θα εισαχθούν αντί για το δεύτερο ερωτηματικό $stmt->bindParam(2, $login); // Εισαγάγετε μία γραμμή με αυτές τις τιμές $name = "vasya"; $login = "vasya123"; $stmt->execute(); // Τώρα μια άλλη γραμμή με διαφορετικές τιμές $name = "petya"; $login = "petya123"; $stmt->execute();

Επόμενο σημείο - Πώς αντιλαμβανόμαστε τα λάθη;

Υπάρχει μια τάξη για αυτό Εξαίρεση PDO. Συνιστώ να γράψετε όλα τα αιτήματά σας σε ένα μπλοκ προσπάθησε να πιάσεις.

Δοκιμάστε ( $db = new PDO("myql:host=localhost;dbname=test", "root", ""); $stmt = $db->query("SELECT * FROM users"); $result = $stmt ->fetch(PDO::FETCH_ASSOC echo $result["login"] ) catch(PDOException $e) (echo "Error: ".$e->getMessage()."
"; echo "Στη γραμμή: ".$e->getLine(); )

Εδώ κάναμε λάθος και γράψαμε myqlαντί mysql. Και τάξη Εξαίρεση PDOθα μας γράψει σχετικά.

Έχει πολλές μεθόδους, αλλά οι πιο συχνά χρησιμοποιούμενες είναι getMessage()που μας επιστρέφει το κείμενο σφάλματος και getLine(), το οποίο επιστρέφει τον αριθμό γραμμής όπου παρουσιάστηκε το σφάλμα.

Και τέλος, ας μιλήσουμε για συναλλαγές. Πρώτα θα δώσω τον κωδικό.

Δοκιμάστε ( $db = new PDO("mysql:host=localhost;dbname=test", "root", ""); $db->beginTransaction(); $stmt = $db->exec("INSERT INTO `users `(`login`) VALUES("login1")"); $stmt = $db->exec("INSERT INTO `users`(`login`) VALUES("login2")"); $stmt = $db- >exec("INSERT INTO `users`(`login`) VALUES("login3")" catch(PDOException $e) ($db->rollBack); )

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

«Γιατί χρειάζονται πραγματικά αυτές οι συναλλαγές;» - εσύ ρωτάς. Για να απαντήσετε σε αυτήν την ερώτηση, εξετάστε το παράδειγμα που έδωσα παραπάνω. Εκεί εισάγετε την τιμή στο πεδίο "login". login1, login2, login3.

Ας το φανταστούμε μετά την εισαγωγή σύνδεση 1Και σύνδεση 2, παρουσιάστηκε κάποιο σφάλμα. Αποδεικνύεται ότι αυτά τα δεδομένα εισάγονται και σύνδεση 3- Οχι. Σε πολλές περιπτώσεις αυτό είναι απαράδεκτο και θα διακόψει την εφαρμογή στο μέλλον.

Ακριβώς για την πρόληψη τέτοιων καταστάσεων χρειάζονται συναλλαγές. Εάν το σενάριό μας αποτύχει, τότε η μέθοδος rollBack()θα επιστρέψει τα πάντα στην αρχική τους μορφή. Εκείνοι. σύνδεση 1Και σύνδεση 2επίσης δεν θα εισαχθεί. Ας μιμηθεί αυτό το σφάλμα.

Δοκιμάστε ( $db = new PDO("mysql:host=localhost;dbname=test", "root", ""); $db->beginTransaction(); $stmt = $db->exec("INSERT INTO `users `(`login`) VALUES("login1")"); $stmt = $db->exec("INSERT INTO `users`(`login`) VALUES("login2")"); exit("σφάλμα") $stmt = $db->exec("INSERT INTO `users`(`login`) VALUES("login3")"; ()

Μετά την εισαγωγή σύνδεση 1Και σύνδεση 2βγαίνουμε από το σενάριο χρησιμοποιώντας τη συνάρτηση έξοδος(). Ρίχνουμε μια εξαίρεση, καταλήγουμε σε μπλοκ σύλληψη, και μετά επιστρέφουμε τα πάντα στην αρχική τους μορφή. Τώρα, αν κοιτάξουμε στη βάση δεδομένων, δεν θα δούμε εκεί σύνδεση 1Και σύνδεση 2.

Θα τελειώσουμε σε αυτό το σημείο. Προφανώς εδώ δεν έχουμε καλύψει όλα όσα μας παρέχει η ΠΟΠ, αλλά έχουμε μάθει τα βασικά της συνεργασίας με αυτήν. Μπορείτε πάντα να βρείτε πιο λεπτομερείς πληροφορίες σχετικά με αυτήν την επέκταση στον επίσημο ιστότοπο της PHP.

Το υλικό προετοιμάστηκε από τον Vladislav Andreev ειδικά για τον ιστότοπο

ΥΣΤΕΡΟΓΡΑΦΟ.Θέλετε να προχωρήσετε περαιτέρω στο mastering PHP και OOP; Δώστε προσοχή στα premium μαθήματα σχετικά με διάφορες πτυχές της κατασκευής ιστοτόπων, συμπεριλαμβανομένου του προγραμματισμού σε PHP, καθώς και σε ένα δωρεάν μάθημα για τη δημιουργία του δικού σας συστήματος CMS στην PHP από την αρχή χρησιμοποιώντας το OOP:

Σας άρεσε το υλικό και θέλετε να με ευχαριστήσετε;
Απλά μοιραστείτε με τους φίλους και τους συναδέλφους σας!


mob_info